This patch introduces virDBusIsServiceEnabled, we can use
this method to get if the service is supported.
In one case, if org.freedesktop.machine1 is unavailable on
host, we should skip creating machine through systemd.
Signed-off-by: Gao feng <gaofeng(a)cn.fujitsu.com>
---
src/util/virdbus.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virdbus.h | 1 +
src/util/virsystemd.c | 11 ++--------
3 files changed, 62 insertions(+), 9 deletions(-)
diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index 62c31be..29068b0 100644
--- a/src/util/virdbus.c
+++ b/src/util/virdbus.c
@@ -1207,6 +1207,58 @@ int virDBusMessageRead(DBusMessage *msg,
return ret;
}
+/**
+ * virDBusIsServiceEnabled:
+ * @name: service name
+ */
+bool virDBusIsServiceEnabled(const char *name)
+{
+ DBusConnection *conn;
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter, sub;
+ bool ret = false;
+
+ if (!virDBusHasSystemBus())
+ return ret;
+
+ conn = virDBusGetSystemBus();
+
+ if (virDBusCallMethod(conn,
+ &reply,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "ListActivatableNames",
+ DBUS_TYPE_INVALID) < 0) {
+ VIR_DEBUG("ListActivatableNames failed.");
+ return ret;
+ }
+
+ if (!dbus_message_iter_init(reply, &iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+ VIR_DEBUG("Reply message incorrect.");
+ goto cleanup;
+ }
+
+ 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 = true;
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+ VIR_DEBUG("Service %s is %s", name, ret ? "available" :
"unavailable");
+ dbus_message_unref(reply);
+ return false;
+}
+
#else /* ! WITH_DBUS */
DBusConnection *virDBusGetSystemBus(void)
@@ -1271,4 +1323,11 @@ int virDBusMessageDecode(DBusMessage* msg ATTRIBUTE_UNUSED,
return -1;
}
+bool virDBusIsServiceEnabled(const char *name ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("DBus support not compiled into this
binary"));
+ return false;
+}
+
#endif /* ! WITH_DBUS */
diff --git a/src/util/virdbus.h b/src/util/virdbus.h
index a5aab56..0ce5e1a 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, ...);
+bool virDBusIsServiceEnabled(const char *name);
#endif /* __VIR_DBUS_H__ */
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index 3e69ef6..abbb438 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -145,7 +145,7 @@ int virSystemdCreateMachine(const char *name,
char *username = NULL;
char *slicename = NULL;
- if (!virDBusHasSystemBus())
+ if (!virDBusIsServiceEnabled("org.freedesktop.machine1"))
return -2;
conn = virDBusGetSystemBus();
@@ -228,15 +228,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;
--
1.8.3.1