diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 62c31bea81..a2c4b4e42d 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1207,6 +1207,61 @@ int virDBusMessageRead(DBusMessage *msg, return ret; } +/** + * virDBusIsServiceEnabled: + * @name: service name + * + * Retruns 0 if service is available, -1 on fatal error, or -2 if service is not available + */ +int virDBusIsServiceEnabled(const char *name) +{ + DBusConnection *conn; + DBusMessage *reply = NULL; + DBusMessageIter iter, sub; + int ret = -1; + + if (!virDBusHasSystemBus()) + return -2; + + conn = virDBusGetSystemBus(); + + if (virDBusCallMethod(conn, + &reply, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ListActivatableNames", + DBUS_TYPE_INVALID) < 0) + return ret; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Reply message incorrect")); + goto cleanup; + } + + ret = -2; + dbus_message_iter_recurse(&iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { + const char *service = NULL; + + dbus_message_iter_get_basic(&sub, &service); + dbus_message_iter_next(&sub); + + if (STREQ(service, name)) { + ret = 0; + break; + } + } + + VIR_DEBUG("Service %s is %s", name, ret ? "unavailable" : "available"); + + cleanup: + dbus_message_unref(reply); + return ret; +} + #else /* ! WITH_DBUS */ DBusConnection *virDBusGetSystemBus(void) @@ -1271,4 +1326,10 @@ int virDBusMessageDecode(DBusMessage* msg ATTRIBUTE_UNUSED, return -1; } +int virDBusIsServiceEnabled(const char *name ATTRIBUTE_UNUSED) +{ + VIR_DEBUG("DBus support not compiled into this binary"); + return -2; +} + #endif /* ! WITH_DBUS */ diff --git a/src/util/virdbus.h b/src/util/virdbus.h index a5aab568f6..194a01abba 100644 --- a/src/util/virdbus.h +++ b/src/util/virdbus.h @@ -45,4 +45,5 @@ int virDBusCallMethod(DBusConnection *conn, int virDBusMessageRead(DBusMessage *msg, const char *types, ...); +int virDBusIsServiceEnabled(const char *name); #endif /* __VIR_DBUS_H__ */ diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c index 3e69ef6679..7674cc6cf9 100644 --- a/src/util/virsystemd.c +++ b/src/util/virsystemd.c @@ -138,18 +138,20 @@ int virSystemdCreateMachine(const char *name, bool iscontainer, const char *partition) { - int ret = -1; + int ret; DBusConnection *conn; char *machinename = NULL; char *creatorname = NULL; char *username = NULL; char *slicename = NULL; - if (!virDBusHasSystemBus()) - return -2; + ret = virDBusIsServiceEnabled("org.freedesktop.machine1"); + if (ret < 0) + return ret; conn = virDBusGetSystemBus(); + ret = -1; if (privileged) { if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0) goto cleanup; @@ -228,15 +230,8 @@ int virSystemdCreateMachine(const char *name, (unsigned int)pidleader, rootdir ? rootdir : "", 1, "Slice", "s", - slicename) < 0) { - virErrorPtr err = virGetLastError(); - if (err->code == VIR_ERR_DBUS_SERVICE && - STREQ(err->str2, "org.freedesktop.DBus.Error.ServiceUnknown")) { - virResetLastError(); - ret = -2; - } + slicename) < 0) goto cleanup; - } ret = 0;