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 | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virdbus.h | 1 +
src/util/virsystemd.c | 17 +++++--------
3 files changed, 73 insertions(+), 11 deletions(-)
diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index 62c31be..ad3045a 100644
--- a/src/util/virdbus.c
+++ b/src/util/virdbus.c
@@ -1207,6 +1207,66 @@ 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) {
+
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("ListActivatableNames failed"));
+ 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 +1331,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 3e69ef6..7674cc6 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.1