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>
This commit is contained in:
Gao feng 2013-09-11 11:15:02 +08:00 committed by Daniel P. Berrange
parent 66e2adb2ba
commit 7ada155cdf
3 changed files with 68 additions and 11 deletions

View File

@ -1207,6 +1207,61 @@ 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)
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 +1326,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 */

View File

@ -45,4 +45,5 @@ int virDBusCallMethod(DBusConnection *conn,
int virDBusMessageRead(DBusMessage *msg,
const char *types, ...);
int virDBusIsServiceEnabled(const char *name);
#endif /* __VIR_DBUS_H__ */

View File

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