Blob Blame History Raw
From 351d57a6576d6026ac0e3807030b07e877e5de07 Mon Sep 17 00:00:00 2001
Message-Id: <351d57a6576d6026ac0e3807030b07e877e5de07.1381871412.git.jdenemar@redhat.com>
From: Gao feng <gaofeng@cn.fujitsu.com>
Date: Mon, 14 Oct 2013 16:45:13 +0100
Subject: [PATCH] DBus: introduce virDBusIsServiceEnabled

For

  https://bugzilla.redhat.com/show_bug.cgi?id=1018730

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@cn.fujitsu.com>
(cherry picked from commit 7ada155cdf2bbfac16ce08f64abb455a940e2cf7)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/util/virdbus.c    | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virdbus.h    |  1 +
 src/util/virsystemd.c | 17 +++++---------
 3 files changed, 68 insertions(+), 11 deletions(-)

diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index 62c31be..a2c4b4e 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 a5aab56..194a01a 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 13370b5..e72b7f0 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;
 
-- 
1.8.3.2