3

I'm trying to interface UDisks2 with a Qt application, and reading a custom property crash the program.

For SMART attributes, everything is OK (including the custom properties), but when I try to read the RAID devices property ActiveDevices I get a Qt fatal error and the app crash

Following is a test program which illustrate the behaviour:

#include <QApplication>

#include <QDBusMetaType>
#include <QDBusConnection>
#include <QDBusInterface>

#include <QDebug>


//create the structure as defined in 
// http://udisks.freedesktop.org/docs/latest/gdbus-org.freedesktop.UDisks2.MDRaid.html#gdbus-property-org-freedesktop-UDisks2-MDRaid.ActiveDevices 
struct MDRaidMember {
   QDBusObjectPath block;
   qint32 slot;
   QStringList state;
   qint64 numReadErrors;
   QVariantMap expansion;
};
Q_DECLARE_METATYPE(MDRaidMember)


//marshalling operator
QDBusArgument &operator<<(QDBusArgument &argument, const MDRaidMember& raidMember)
{
    argument.beginStructure();
    argument << raidMember.block;
    argument << raidMember.slot;
    argument << raidMember.state;
    argument << raidMember.numReadErrors;
    argument << raidMember.expansion;
    argument.endStructure();
    return argument;
}


//unmarshall operator
const QDBusArgument &operator>>(const QDBusArgument &argument, MDRaidMember& raidMember)
{
    argument.beginStructure();
    argument >> raidMember.block;
    argument >> raidMember.slot;
    argument >> raidMember.state;
    argument >> raidMember.numReadErrors;
    argument >> raidMember.expansion;
    argument.endStructure();
    return argument;
}



int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  //register the type, everything looks fine
  qDebug() << qRegisterMetaType<MDRaidMember>("MDRaidMember");
  qDebug() << qDBusRegisterMetaType<MDRaidMember>();


  QDBusInterface iface("org.freedesktop.UDisks2",
                       "/org/freedesktop/UDisks2/mdraid/9aec6784_86ec37d4_8c1c6add_4dc9fe81",
                       "org.freedesktop.UDisks2.MDRaid",
                       QDBusConnection::systemBus());

  //read some properties
  qDebug() << iface.property("UUID");
  qDebug() << iface.property("ActiveDevices"); //crash the test program!

  return app.exec();
}

Executing this code produce the following output

1057
1057
QVariant(QString, "9aec6784:86ec37d4:8c1c6add:4dc9fe81")
Cannot construct placeholder type QDBusRawType
zsh: abort (core dumped)  ./app/test_members

Anyone encoutered such a case ? I don't thing it is related to my code at all, as the result is the same if the custom type aren't declared (keeping only the content of the main function).

Michaël Lhomme
  • 346
  • 1
  • 8

1 Answers1

5

I didn't find a correct answer for this, but here is a workaround: calling the Get method on interface org.freedesktop.DBus.Properties and unmarshalling the result manually. The tricky part was figuring the result's content (it's a QVariant containing a QDBusVariant containing a QDBusArgument)

The updated main function:

//...

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  //register the type, everything looks fine
  qDebug() << qRegisterMetaType<MDRaidMember>("MDRaidMember");
  qDebug() << qDBusRegisterMetaType<MDRaidMember>();


  QDBusInterface iface("org.freedesktop.UDisks2",
                   "/org/freedesktop/UDisks2/mdraid/9aec6784_86ec37d4_8c1c6add_4dc9fe81",
                   "org.freedesktop.DBus.Properties",
                   QDBusConnection::systemBus());

  QDBusMessage reply = iface.call("Get", "org.freedesktop.UDisks2.MDRaid", "ActiveDevices");
  QVariant v = reply.arguments().first();
  QDBusArgument arg = v.value<QDBusVariant>().variant().value<QDBusArgument>();

  QList<MDRaidMember> members;
  arg.beginArray();
  while(!arg.atEnd()) {
    MDRaidMember m;
    arg >> m;
    members << m;
  }

  qDebug() << members;

  return app.exec();
}
Michaël Lhomme
  • 346
  • 1
  • 8
  • 1
    There is undocumented [`qdbus_cast< T >(QVariant)`](https://github.com/openwebos/qt/blob/master/src/dbus/qdbusargument.h#L166) overloading specially for these purposes. – Tomilov Anatoliy Nov 16 '17 at 07:00