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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list