[libvirt] [PATCH v2] DBus: introduce virDBusIsServiceEnabled

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> --- 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

On Wed, Sep 11, 2013 at 11:15:02AM +0800, Gao feng wrote:
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> --- 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"));
ACK, but no need for this, since virDBusCallMethod will already have reported the error. I'll remove this virReportError and push it, so no need to repost. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Wed, Sep 11, 2013 at 01:50:27PM +0100, Daniel P. Berrange wrote:
On Wed, Sep 11, 2013 at 11:15:02AM +0800, Gao feng wrote:
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> --- 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"));
ACK, but no need for this, since virDBusCallMethod will already have reported the error.
I'll remove this virReportError and push it, so no need to repost.
I suck for forgetting to run 'make check' before pushing. I've just applied a fix for the test suite problems. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (2)
-
Daniel P. Berrange
-
Gao feng