[libvirt] [PATCHv2 2/2] Check if systemd is running before creating machines

Ján Tomko jtomko at redhat.com
Mon Mar 3 15:47:46 UTC 2014


If systemd is installed, but not the init system,
systemd-machined fails with an unhelpful error message:
Launch helper exited with unknown return code 1

Currently we only check if the "machine1" service is
available (in ListActivatableNames).
Also check if "systemd1" service is registered with DBus
(ListNames).

This fixes https://bugs.gentoo.org/show_bug.cgi?id=493246#c22
---
 src/util/virdbus.c     | 21 +++++++++++++++++++++
 src/util/virdbus.h     |  1 +
 src/util/virsystemd.c  |  6 ++++++
 tests/virsystemdmock.c | 24 +++++++++++++++++++++++-
 tests/virsystemdtest.c | 37 +++++++++++++++++++++++++++++++++++++
 5 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index 3c9416e..d15e56e 100644
--- a/src/util/virdbus.c
+++ b/src/util/virdbus.c
@@ -1319,6 +1319,21 @@ int virDBusIsServiceEnabled(const char *name)
     return ret;
 }
 
+/**
+ * virDBusIsServiceRegistered
+ * @name: service name
+ *
+ * Retruns 0 if service is registered, -1 on fatal error, or -2 if service is not registered
+ */
+int virDBusIsServiceRegistered(const char *name)
+{
+    int ret = virDBusIsServiceInList("ListNames", name);
+
+    VIR_DEBUG("Service %s is %sregistered", name, ret ? "not " : "");
+
+    return ret;
+}
+
 #else /* ! WITH_DBUS */
 void virDBusSetSharedBus(bool shared ATTRIBUTE_UNUSED)
 {
@@ -1397,4 +1412,10 @@ int virDBusIsServiceEnabled(const char *name ATTRIBUTE_UNUSED)
     return -2;
 }
 
+int virDBusIsServiceRegistered(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 979c566..1ca8641 100644
--- a/src/util/virdbus.h
+++ b/src/util/virdbus.h
@@ -49,4 +49,5 @@ int virDBusMessageRead(DBusMessage *msg,
                        const char *types, ...);
 
 int virDBusIsServiceEnabled(const char *name);
+int virDBusIsServiceRegistered(const char *name);
 #endif /* __VIR_DBUS_H__ */
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index 8adf209..d263c58 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -173,6 +173,9 @@ int virSystemdCreateMachine(const char *name,
     if (ret < 0)
         return ret;
 
+    if ((ret = virDBusIsServiceRegistered("org.freedesktop.systemd1")) < 0)
+        return ret;
+
     if (!(conn = virDBusGetSystemBus()))
         return -1;
 
@@ -274,6 +277,9 @@ int virSystemdTerminateMachine(const char *name,
     if (ret < 0)
         return ret;
 
+    if ((ret = virDBusIsServiceRegistered("org.freedesktop.systemd1")) < 0)
+        return ret;
+
     if (!(conn = virDBusGetSystemBus()))
         return -1;
 
diff --git a/tests/virsystemdmock.c b/tests/virsystemdmock.c
index 0295231..b4fcf6e 100644
--- a/tests/virsystemdmock.c
+++ b/tests/virsystemdmock.c
@@ -66,6 +66,7 @@ DBusMessage *dbus_connection_send_with_reply_and_block(DBusConnection *connectio
 {
     DBusMessage *reply = NULL;
     const char *service = dbus_message_get_destination(message);
+    const char *member = dbus_message_get_member(message);
 
     if (STREQ(service, "org.freedesktop.machine1")) {
         if (getenv("FAIL_BAD_SERVICE")) {
@@ -82,7 +83,8 @@ DBusMessage *dbus_connection_send_with_reply_and_block(DBusConnection *connectio
         } else {
             reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
         }
-    } else if (STREQ(service, "org.freedesktop.DBus")) {
+    } else if (STREQ(service, "org.freedesktop.DBus") &&
+               STREQ(member, "ListActivatableNames")) {
         const char *svc1 = "org.foo.bar.wizz";
         const char *svc2 = "org.freedesktop.machine1";
         DBusMessageIter iter, sub;
@@ -101,6 +103,26 @@ DBusMessage *dbus_connection_send_with_reply_and_block(DBusConnection *connectio
                                             &svc2))
             goto error;
         dbus_message_iter_close_container(&iter, &sub);
+    } else if (STREQ(service, "org.freedesktop.DBus") &&
+               STREQ(member, "ListNames")) {
+        const char *svc1 = "org.foo.bar.wizz";
+        const char *svc2 = "org.freedesktop.systemd1";
+        DBusMessageIter iter, sub;
+        reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+        dbus_message_iter_init_append(reply, &iter);
+        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+                                         "s", &sub);
+
+        if (!dbus_message_iter_append_basic(&sub,
+                                            DBUS_TYPE_STRING,
+                                            &svc1))
+            goto error;
+        if ((!getenv("FAIL_NO_SERVICE") && !getenv("FAIL_NOT_REGISTERED")) &&
+            !dbus_message_iter_append_basic(&sub,
+                                            DBUS_TYPE_STRING,
+                                            &svc2))
+            goto error;
+        dbus_message_iter_close_container(&iter, &sub);
     } else {
         reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
     }
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
index 9f6fc83..9752d12 100644
--- a/tests/virsystemdtest.c
+++ b/tests/virsystemdtest.c
@@ -135,6 +135,40 @@ static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
     return 0;
 }
 
+static int testCreateSystemdNotRunning(const void *opaque ATTRIBUTE_UNUSED)
+{
+    unsigned char uuid[VIR_UUID_BUFLEN] = {
+        1, 1, 1, 1,
+        2, 2, 2, 2,
+        3, 3, 3, 3,
+        4, 4, 4, 4
+    };
+    int rv;
+
+    setenv("FAIL_NOT_REGISTERED", "1", 1);
+
+    if ((rv = virSystemdCreateMachine("demo",
+                                      "qemu",
+                                      true,
+                                      uuid,
+                                      NULL,
+                                      123,
+                                      false,
+                                      NULL)) == 0) {
+        unsetenv("FAIL_NOT_REGISTERED");
+        fprintf(stderr, "%s", "Unexpected create machine success\n");
+        return -1;
+    }
+    unsetenv("FAIL_NOT_REGISTERED");
+
+    if (rv != -2) {
+        fprintf(stderr, "%s", "Unexpected create machine error\n");
+        return -1;
+    }
+
+    return 0;
+}
+
 static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
 {
     unsigned char uuid[VIR_UUID_BUFLEN] = {
@@ -216,6 +250,9 @@ mymain(void)
         ret = -1;
     if (virtTestRun("Test create no systemd ", testCreateNoSystemd, NULL) < 0)
         ret = -1;
+    if (virtTestRun("Test create systemd not running ",
+                    testCreateSystemdNotRunning, NULL) < 0)
+        ret = -1;
     if (virtTestRun("Test create bad systemd ", testCreateBadSystemd, NULL) < 0)
         ret = -1;
 
-- 
1.8.3.2




More information about the libvir-list mailing list