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