This removes all the sd-bus code and uses GDBus instead. Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> --- Changes in v3: - domain property Id is handled correctly for offline domains README | 1 - configure.ac | 3 - data/Makefile.am | 4 +- data/org.libvirt.Connect.xml | 56 ++++ data/org.libvirt.Domain.xml | 51 +++ libvirt-dbus.spec.in | 4 +- src/Makefile.am | 3 - src/connect.c | 320 ++++++++---------- src/connect.h | 36 +-- src/domain.c | 748 ++++++++++++++++++++----------------------- src/domain.h | 6 +- src/events.c | 177 +++++----- src/main.c | 307 +++++++----------- src/util.c | 167 ++++------ src/util.h | 53 ++- test/travis-run | 2 +- 16 files changed, 889 insertions(+), 1049 deletions(-) create mode 100644 data/org.libvirt.Connect.xml create mode 100644 data/org.libvirt.Domain.xml diff --git a/README b/README index a85114e..b95b09b 100644 --- a/README +++ b/README @@ -56,7 +56,6 @@ raised in future releases based on this distro build target policy. The packages required to build libvirt-dbus are - - systemd-211 - libvirt - glib2 diff --git a/configure.ac b/configure.ac index 36a4720..241bf1d 100644 --- a/configure.ac +++ b/configure.ac @@ -13,11 +13,9 @@ AM_SILENT_RULES([yes]) GLIB2_REQUIRED=2.44.0 LIBVIRT_REQUIRED=1.2.8 -SYSTEMD_REQUIRED=211 LIBVIRT_GLIB_REQUIRED=0.0.7 AC_SUBST([GLIB2_REQUIRED]) dnl used in the .spec file AC_SUBST([LIBVIRT_REQUIRED]) dnl used in the .spec file -AC_SUBST([SYSTEMD_REQUIRED]) dnl used in the .spec file AC_SUBST([LIBVIRT_GLIB_REQUIRED]) dnl used in the .spec file LIBVIRT_DBUS_MAJOR_VERSION=`echo $VERSION | awk -F. '{print $1}'` @@ -41,7 +39,6 @@ AC_PROG_CC_STDC PKG_CHECK_MODULES(GIO2, gio-unix-2.0 >= GLIB2_REQUIRED) PKG_CHECK_MODULES(GLIB2, glib-2.0 >= GLIB2_REQUIRED) PKG_CHECK_MODULES(LIBVIRT, libvirt >= $LIBVIRT_REQUIRED) -PKG_CHECK_MODULES(SYSTEMD, libsystemd >= $SYSTEMD_REQUIRED) PKG_CHECK_MODULES(LIBVIRT_GLIB, libvirt-glib-1.0 >= LIBVIRT_GLIB_REQUIRED) LIBVIRT_COMPILE_WARNINGS diff --git a/data/Makefile.am b/data/Makefile.am index a886687..dd60713 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -18,7 +18,9 @@ polkit_files = \ polkitdir = $(sysconfdir)/polkit-1/rules.d polkit_DATA = $(polkit_files:.rules.in=.rules) -interfaces_files = +interfaces_files = \ + org.libvirt.Connect.xml \ + org.libvirt.Domain.xml interfacesdir = $(DBUS_INTERFACES_DIR) interfaces_DATA = $(interfaces_files) diff --git a/data/org.libvirt.Connect.xml b/data/org.libvirt.Connect.xml new file mode 100644 index 0000000..787cd8d --- /dev/null +++ b/data/org.libvirt.Connect.xml @@ -0,0 +1,56 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + +<node name="/org/libvirt/connect"> + <interface name="org.libvirt.Connect"> + <method name="ListDomains"> + <arg name="flags" type="u" direction="in"/> + <arg name="domains" type="ao" direction="out"/> + </method> + <method name="CreateXML"> + <arg name="xml" type="s" direction="in"/> + <arg name="flags" type="u" direction="in"/> + <arg name="domain" type="o" direction="out"/> + </method> + <method name="DefineXML"> + <arg name="xml" type="s" direction="in"/> + <arg name="domain" type="o" direction="out"/> + </method> + <signal name="DomainCrashed"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainDefined"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainPMSuspended"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainResumed"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainShutdown"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainStarted"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainStopped"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainSuspended"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + <signal name="DomainUndefined"> + <arg name="reason" type="s"/> + <arg name="domain" type="o"/> + </signal> + </interface> +</node> diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml new file mode 100644 index 0000000..48bf40f --- /dev/null +++ b/data/org.libvirt.Domain.xml @@ -0,0 +1,51 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + +<node name="/org/libvirt/domain"> + <interface name="org.libvirt.Domain"> + <property name="Name" type="s" access="read"/> + <property name="UUID" type="s" access="read"/> + <property name="Id" type="u" access="read"/> + <property name="Vcpus" type="u" access="read"/> + <property name="OSType" type="s" access="read"/> + <property name="Active" type="b" access="read"/> + <property name="Persistent" type="b" access="read"/> + <property name="State" type="s" access="read"/> + <property name="Autostart" type="b" access="read"/> + <method name="GetXMLDesc"> + <arg name="flags" type="u" direction="in"/> + <arg name="xml" type="s" direction="out"/> + </method> + <method name="GetStats"> + <arg name="stats" type="u" direction="in"/> + <arg name="flags" type="u" direction="in"/> + <arg name="records" type="a{sv}" direction="out"/> + </method> + <method name="Shutdown"/> + <method name="Destroy"/> + <method name="Reboot"> + <arg name="flags" type="u" direction="in"/> + </method> + <method name="Reset"> + <arg name="flags" type="u" direction="in"/> + </method> + <method name="Create"/> + <method name="Undefine"/> + <signal name="DeviceAdded"> + <arg name="device" type="s"/> + </signal> + <signal name="DeviceRemoved"> + <arg name="device" type="s"/> + </signal> + <signal name="DiskChange"> + <arg name="oldSrcPath" type="s"/> + <arg name="newSrcPath" type="s"/> + <arg name="device" type="s"/> + <arg name="reason" type="s"/> + </signal> + <signal name="TrayChange"> + <arg name="device" type="s"/> + <arg name="reason" type="s"/> + </signal> + </interface> +</node> diff --git a/libvirt-dbus.spec.in b/libvirt-dbus.spec.in index 662ece1..eb531bb 100644 --- a/libvirt-dbus.spec.in +++ b/libvirt-dbus.spec.in @@ -2,7 +2,6 @@ %define glib2_version @GLIB2_REQUIRED@ %define libvirt_version @LIBVIRT_REQUIRED@ -%define systemd_version @SYSTEMD_REQUIRED@ %define libvirt_glib_version @LIBVIRT_GLIB_REQUIRED@ %define system_user @SYSTEM_USER@ @@ -19,12 +18,10 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: gcc BuildRequires: glib2-devel >= %{glib2_version} BuildRequires: libvirt-devel >= %{libvirt_version} -BuildRequires: systemd-devel >= %{systemd_version} BuildRequires: libvirt-glib-devel >= %{libvirt_glib_version} Requires: glib2 >= %{glib2_version} Requires: libvirt-libs >= %{libvirt_version} -Requires: systemd-libs >= %{systemd_version} Requires: libvirt-glib >= %{libvirt_glib_version} Requires(pre): shadow-utils @@ -61,5 +58,6 @@ exit 0 %{_datadir}/dbus-1/services/org.libvirt.service %{_datadir}/dbus-1/system-services/org.libvirt.service %{_datadir}/dbus-1/system.d/org.libvirt.conf +%{_datadir}/dbus-1/interfaces/org.libvirt.*.xml %changelog diff --git a/src/Makefile.am b/src/Makefile.am index e7bba9d..7248561 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,6 @@ bin_PROGRAMS = libvirt-dbus libvirt_dbus_SOURCES = $(DAEMON_SOURCES) libvirt_dbus_CFLAGS = \ - $(SYSTEMD_CFLAGS) \ $(GIO2_CFLAGS) \ $(GLIB2_CFLAGS) \ $(LIBVIRT_CFLAGS) \ @@ -29,7 +28,6 @@ libvirt_dbus_CFLAGS = \ $(NULL) libvirt_dbus_LDFLAGS = \ - $(SYSTEMD_LDFLAGS) \ $(GIO2_LDFLAGS) \ $(GLIB2_LDFLAGS) \ $(LIBVIRT_LDFLAGS) \ @@ -39,7 +37,6 @@ libvirt_dbus_LDFLAGS = \ $(NULL) libvirt_dbus_LDADD = \ - $(SYSTEMD_LIBS) \ $(GIO2_LIBS) \ $(GLIB2_LIBS) \ $(LIBVIRT_LIBS) \ diff --git a/src/connect.c b/src/connect.c index 695fc0d..70af8ac 100644 --- a/src/connect.c +++ b/src/connect.c @@ -1,12 +1,11 @@ +#include "connect.h" #include "domain.h" #include "events.h" -#include "connect.h" #include "util.h" -#include <stdbool.h> -#include <stdlib.h> +#include <glib/gprintf.h> -static int virtDBusConnectCredType[] = { +static gint virtDBusConnectCredType[] = { VIR_CRED_AUTHNAME, VIR_CRED_ECHOPROMPT, VIR_CRED_REALM, @@ -15,31 +14,31 @@ static int virtDBusConnectCredType[] = { VIR_CRED_EXTERNAL, }; -static int -virtDBusConnectAuthCallback(virConnectCredentialPtr cred VIRT_ATTR_UNUSED, - unsigned int ncred VIRT_ATTR_UNUSED, - void *cbdata) +static gint +virtDBusConnectAuthCallback(virConnectCredentialPtr cred G_GNUC_UNUSED, + guint ncred G_GNUC_UNUSED, + gpointer cbdata) { - sd_bus_error *error = cbdata; - - return virtDBusUtilSetError(error, - "Interactive authentication is not supported. " - "Use client configuration file for libvirt."); + GError **error = cbdata; + g_set_error(error, VIRT_DBUS_ERROR, VIRT_DBUS_ERROR_LIBVIRT, + "Interactive authentication is not supported. " + "Use client configuration file for libvirt."); + return -1; } static virConnectAuth virtDBusConnectAuth = { virtDBusConnectCredType, - VIRT_N_ELEMENTS(virtDBusConnectCredType), + G_N_ELEMENTS(virtDBusConnectCredType), virtDBusConnectAuthCallback, NULL, }; static void virtDBusConnectClose(virtDBusConnect *connect, - bool deregisterEvents) + gboolean deregisterEvents) { - for (int i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i += 1) { + for (gint i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i += 1) { if (connect->callback_ids[i] >= 0) { if (deregisterEvents) { virConnectDomainEventDeregisterAny(connect->connection, @@ -53,130 +52,91 @@ virtDBusConnectClose(virtDBusConnect *connect, connect->connection = NULL; } -int +gboolean virtDBusConnectOpen(virtDBusConnect *connect, - sd_bus_error *error) + GError **error) { if (connect->connection) { if (virConnectIsAlive(connect->connection)) - return 0; + return TRUE; else - virtDBusConnectClose(connect, false); + virtDBusConnectClose(connect, FALSE); } virtDBusConnectAuth.cbdata = error; connect->connection = virConnectOpenAuth(connect->uri, &virtDBusConnectAuth, 0); - if (!connect->connection) - return virtDBusUtilSetLastVirtError(error); + if (!connect->connection) { + if (error && !*error) + virtDBusUtilSetLastVirtError(error); + return FALSE; + } virtDBusEventsRegister(connect); - return 0; + return TRUE; } -static int -virtDBusConnectEnumarateDomains(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path VIRT_ATTR_UNUSED, - void *userdata, - char ***nodes, - sd_bus_error *error) +static void +virtDBusConnectListDomains(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainListFreep) virDomainPtr *domains = NULL; - _cleanup_(virtDBusUtilStrvFreep) char **paths = NULL; - int n_domains; - int r; - - r = virtDBusConnectOpen(connect, error); - if (r < 0) - return r; - - n_domains = virConnectListAllDomains(connect->connection, &domains, 0); - if (n_domains < 0) - return virtDBusUtilSetLastVirtError(error); - - paths = calloc(n_domains + 1, sizeof(char *)); - - for (int i = 0; i < n_domains; i += 1) - paths[i] = virtDBusUtilBusPathForVirDomain(domains[i], - connect->domainPath); + virtDBusConnect *connect = userData; + g_autoptr(virDomainPtr) domains = NULL; + guint flags; + GVariantBuilder builder; + GVariant *gdomains; - *nodes = paths; - paths = NULL; + g_variant_get(inArgs, "(u)", &flags); - return 0; -} + if (!virtDBusConnectOpen(connect, error)) + return; -static int -virtDBusConnectListDomains(sd_bus_message *message, - void *userdata, - sd_bus_error *error) -{ - virtDBusConnect *connect = userdata; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - _cleanup_(virtDBusUtilVirDomainListFreep) virDomainPtr *domains = NULL; - uint32_t flags; - int r; - - r = sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - r = virtDBusConnectOpen(connect, error); - if (r < 0) - return r; - - r = virConnectListAllDomains(connect->connection, &domains, flags); - if (r < 0) + if (virConnectListAllDomains(connect->connection, &domains, flags) < 0) return virtDBusUtilSetLastVirtError(error); - r = sd_bus_message_new_method_return(message, &reply); - if (r < 0) - return r; - - r = sd_bus_message_open_container(reply, 'a', "o"); - if (r < 0) - return r; + if (!*domains) + return; - for (int i = 0; domains[i] != NULL; i += 1) { - _cleanup_(virtDBusUtilFreep) char *path = NULL; + g_variant_builder_init(&builder, G_VARIANT_TYPE("ao")); + for (gint i = 0; domains[i]; i++) { + g_autofree gchar *path = NULL; path = virtDBusUtilBusPathForVirDomain(domains[i], connect->domainPath); - r = sd_bus_message_append(reply, "o", path); - if (r < 0) - return r; + g_variant_builder_add(&builder, "o", path); } - r = sd_bus_message_close_container(reply); - if (r < 0) - return r; - - return sd_bus_send(NULL, reply, NULL); + gdomains = g_variant_builder_end(&builder); + *outArgs = g_variant_new_tuple(&gdomains, 1); } -static int -virtDBusConnectCreateXML(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusConnectCreateXML(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - const char *xml; - uint32_t flags; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - _cleanup_(virtDBusUtilFreep) char *path = NULL; - int r; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + g_autofree gchar *path = NULL; + gchar *xml; + guint flags; - r = sd_bus_message_read(message, "su", &xml, &flags); - if (r < 0) - return r; + g_variant_get(inArgs, "(&su)", &xml, &flags); - r = virtDBusConnectOpen(connect, error); - if (r < 0) - return r; + if (!virtDBusConnectOpen(connect, error)) + return; domain = virDomainCreateXML(connect->connection, xml, flags); if (!domain) @@ -184,27 +144,27 @@ virtDBusConnectCreateXML(sd_bus_message *message, path = virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); - return sd_bus_reply_method_return(message, "o", path); + *outArgs = g_variant_new("(o)", path); } -static int -virtDBusConnectDefineXML(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusConnectDefineXML(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - const char *xml; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - _cleanup_(virtDBusUtilFreep) char *path = NULL; - int r; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + g_autofree gchar *path = NULL; + gchar *xml; - r = sd_bus_message_read(message, "s", &xml); - if (r < 0) - return r; + g_variant_get(inArgs, "(&s)", &xml); - r = virtDBusConnectOpen(connect, error); - if (r < 0) - return r; + if (!virtDBusConnectOpen(connect, error)) + return; domain = virDomainDefineXML(connect->connection, xml); if (!domain) @@ -212,97 +172,77 @@ virtDBusConnectDefineXML(sd_bus_message *message, path = virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); - return sd_bus_reply_method_return(message, "o", path); + *outArgs = g_variant_new("(o)", path); } -static const sd_bus_vtable virt_connect_vtable[] = { - SD_BUS_VTABLE_START(0), +static virtDBusGDBusMethodTable virtDBusConnectMethodTable[] = { + { "ListDomains", virtDBusConnectListDomains }, + { "CreateXML", virtDBusConnectCreateXML }, + { "DefineXML", virtDBusConnectDefineXML }, + { NULL, NULL } +}; - SD_BUS_METHOD("ListDomains", "u", "ao", virtDBusConnectListDomains, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("CreateXML", "su", "o", virtDBusConnectCreateXML, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("DefineXML", "s", "o", virtDBusConnectDefineXML, SD_BUS_VTABLE_UNPRIVILEGED), +static GDBusInterfaceInfo *interfaceInfo = NULL; - SD_BUS_SIGNAL("DomainDefined", "so", 0), - SD_BUS_SIGNAL("DomainUndefined", "so", 0), - SD_BUS_SIGNAL("DomainStarted", "so", 0), - SD_BUS_SIGNAL("DomainSuspended", "so", 0), - SD_BUS_SIGNAL("DomainResumed", "so", 0), - SD_BUS_SIGNAL("DomainStopped", "so", 0), - SD_BUS_SIGNAL("DomainShutdown", "so", 0), - SD_BUS_SIGNAL("DomainPMSuspended", "so", 0), - SD_BUS_SIGNAL("DomainCrashed", "so", 0), +static void +virtDBusConnectFree(virtDBusConnect *connect) +{ + if (connect->connection) + virtDBusConnectClose(connect, TRUE); - SD_BUS_VTABLE_END -}; + g_free(connect->domainPath); + g_free(connect); +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virtDBusConnect, virtDBusConnectFree); -int +void virtDBusConnectNew(virtDBusConnect **connectp, - sd_bus *bus, - const char *uri, - const char *connectPath) + GDBusConnection *bus, + const gchar *uri, + const gchar *connectPath, + GError **error) { - _cleanup_(virtDBusConnectFreep) virtDBusConnect *connect = NULL; - int r; + g_autoptr(virtDBusConnect) connect = NULL; + + if (!interfaceInfo) { + interfaceInfo = virtDBusGDBusLoadIntrospectData(VIRT_DBUS_CONNECT_INTERFACE, + error); + if (!interfaceInfo) + return; + } - connect = calloc(1, sizeof(virtDBusConnect)); - for (int i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i += 1) + connect = g_new0(virtDBusConnect, 1); + + for (gint i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i += 1) connect->callback_ids[i] = -1; - connect->bus = sd_bus_ref(bus); + connect->bus = bus; connect->uri = uri; connect->connectPath = connectPath; - connect->enumerateDomains = virtDBusConnectEnumarateDomains; - - r = sd_bus_add_object_vtable(connect->bus, - NULL, - connect->connectPath, - VIRT_DBUS_CONNECT_INTERFACE, - virt_connect_vtable, - connect); - if (r < 0) - return r; + virtDBusGDBusRegisterObject(bus, + connect->connectPath, + interfaceInfo, + virtDBusConnectMethodTable, + NULL, + connect); - if ((r = virtDBusDomainRegister(connect, bus) < 0)) - return r; + virtDBusDomainRegister(connect, error); + if (error && *error) + return; *connectp = connect; connect = NULL; - - return 0; -} - -virtDBusConnect * -virtDBusConnectFree(virtDBusConnect *connect) -{ - if (connect->bus) - sd_bus_unref(connect->bus); - - if (connect->connection) - virtDBusConnectClose(connect, true); - - free(connect->domainPath); - - free(connect); - - return NULL; -} - -void -virtDBusConnectFreep(virtDBusConnect **connectp) -{ - if (*connectp) - virtDBusConnectFree(*connectp); } void -virtDBusConnectListFree(virtDBusConnect ***connectList) +virtDBusConnectListFree(virtDBusConnect **connectList) { - if (!*connectList) + if (!connectList) return; - for (int i = 0; (*connectList)[i]; i += 1) - virtDBusConnectFree((*connectList)[i]); + for (gint i = 0; connectList[i]; i += 1) + virtDBusConnectFree(connectList[i]); - free(*connectList); + g_free(connectList); } diff --git a/src/connect.h b/src/connect.h index 9e5f533..bfe2995 100644 --- a/src/connect.h +++ b/src/connect.h @@ -2,39 +2,33 @@ #define VIR_ENUM_SENTINELS +#include "util.h" + #include <libvirt/libvirt.h> -#include <systemd/sd-bus.h> #define VIRT_DBUS_CONNECT_INTERFACE "org.libvirt.Connect" struct virtDBusConnect { - sd_bus *bus; - const char *uri; - const char *connectPath; - char *domainPath; + GDBusConnection *bus; + const gchar *uri; + const gchar *connectPath; + gchar *domainPath; virConnectPtr connection; - sd_bus_node_enumerator_t enumerateDomains; - - int callback_ids[VIR_DOMAIN_EVENT_ID_LAST]; + gint callback_ids[VIR_DOMAIN_EVENT_ID_LAST]; }; typedef struct virtDBusConnect virtDBusConnect; -int +void virtDBusConnectNew(virtDBusConnect **connectp, - sd_bus *bus, - const char *uri, - const char *connectPath); + GDBusConnection *bus, + const gchar *uri, + const gchar *connectPath, + GError **error); -int +gboolean virtDBusConnectOpen(virtDBusConnect *connect, - sd_bus_error *error); - -virtDBusConnect * -virtDBusConnectFree(virtDBusConnect *connect); - -void -virtDBusConnectFreep(virtDBusConnect **connectp); + GError **error); void -virtDBusConnectListFree(virtDBusConnect ***connectList); +virtDBusConnectListFree(virtDBusConnect **connectList); diff --git a/src/domain.c b/src/domain.c index f68a3a0..e4404c1 100644 --- a/src/domain.c +++ b/src/domain.c @@ -1,208 +1,192 @@ -#define _GNU_SOURCE - #include "domain.h" #include "util.h" #include <libvirt/libvirt.h> -#include <stdio.h> static virDomainPtr virtDBusDomainGetVirDomain(virtDBusConnect *connect, - const char *path, - sd_bus_error *error) + const gchar *objectPath, + GError **error) { virDomainPtr domain; if (virtDBusConnectOpen(connect, error) < 0) return NULL; - domain = virtDBusUtilVirDomainFromBusPath(connect->connection, path, + domain = virtDBusUtilVirDomainFromBusPath(connect->connection, + objectPath, connect->domainPath); - if (domain == NULL) { - sd_bus_error_setf(error, - SD_BUS_ERROR_UNKNOWN_OBJECT, - "Unknown object '%s'.", path); + if (!domain) { + virtDBusUtilSetLastVirtError(error); return NULL; } return domain; } -static int -virtDBusDomainGetName(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetName(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - const char *name = ""; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + const gchar *name; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; name = virDomainGetName(domain); - if (name == NULL) - return sd_bus_message_append(reply, "s", ""); + if (!name) + return virtDBusUtilSetLastVirtError(error); - return sd_bus_message_append(reply, "s", name); + *value = g_variant_new("s", name); } -static int -virtDBusDomainGetUUID(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetUUID(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - char uuid[VIR_UUID_STRING_BUFLEN] = ""; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + gchar uuid[VIR_UUID_STRING_BUFLEN] = ""; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - virDomainGetUUIDString(domain, uuid); + if (virDomainGetUUIDString(domain, uuid) < 0) + return virtDBusUtilSetLastVirtError(error); - return sd_bus_message_append(reply, "s", uuid); + *value = g_variant_new("s", uuid); } -static int -virtDBusDomainGetId(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetId(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + guint id; + + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + id = virDomainGetID(domain); + if (id == (guint)-1) + id = 0; - return sd_bus_message_append(reply, "u", virDomainGetID(domain)); + *value = g_variant_new("u", id); } -static int -virtDBusDomainGetVcpus(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetVcpus(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + gint vcpus; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - return sd_bus_message_append(reply, "u", virDomainGetVcpusFlags(domain, VIR_DOMAIN_VCPU_CURRENT)); + vcpus = virDomainGetVcpusFlags(domain, VIR_DOMAIN_VCPU_CURRENT); + if (vcpus < 0) + return virtDBusUtilSetLastVirtError(error); + + *value = g_variant_new("u", vcpus); } -static int -virtDBusDomainGetOsType(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetOsType(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - _cleanup_(virtDBusUtilFreep) char *os_type = NULL; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + g_autofree gchar *osType = NULL; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - os_type = virDomainGetOSType(domain); - if (os_type == NULL) - return sd_bus_message_append(reply, "s", ""); + osType = virDomainGetOSType(domain); + if (!osType) + return virtDBusUtilSetLastVirtError(error); - return sd_bus_message_append(reply, "s", os_type); + *value = g_variant_new("s", osType); } -static int -virtDBusDomainGetActive(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetActive(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int active; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + gint active; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; active = virDomainIsActive(domain); if (active < 0) - return sd_bus_message_append(reply, "b", 0); + return virtDBusUtilSetLastVirtError(error); - return sd_bus_message_append(reply, "b", active); + *value = g_variant_new("b", !!active); } -static int -virtDBusDomainGetPersistent(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetPersistent(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int persistent; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + gint persistent; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; persistent = virDomainIsPersistent(domain); if (persistent < 0) - return sd_bus_message_append(reply, "b", 0); + return virtDBusUtilSetLastVirtError(error); - return sd_bus_message_append(reply, "b", persistent); + *value = g_variant_new("b", !!persistent); } -static int -virtDBusDomainGetState(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetState(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int state = 0; - const char *string; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + gint state = 0; + const gchar *string; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - virDomainGetState(domain, &state, NULL, 0); + if (virDomainGetState(domain, &state, NULL, 0) < 0) + return virtDBusUtilSetLastVirtError(error); switch (state) { case VIR_DOMAIN_NOSTATE: @@ -232,88 +216,80 @@ virtDBusDomainGetState(sd_bus *bus VIRT_ATTR_UNUSED, break; } - return sd_bus_message_append(reply, "s", string); + *value = g_variant_new("s", string); } -static int -virtDBusDomainGetAutostart(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - const char *property VIRT_ATTR_UNUSED, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error VIRT_ATTR_UNUSED) +static void +virtDBusDomainGetAutostart(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int autostart = 0; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + gint autostart = 0; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - virDomainGetAutostart(domain, &autostart); + if (virDomainGetAutostart(domain, &autostart) < 0) + return virtDBusUtilSetLastVirtError(error); - return sd_bus_message_append(reply, "b", autostart); + *value = g_variant_new("b", !!autostart); } -static int -virtDBusDomainGetXMLDesc(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainGetXMLDesc(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - _cleanup_(virtDBusUtilFreep) char *description = NULL; - uint32_t flags; - int r; - - r = sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; - - description = virDomainGetXMLDesc(domain, flags); - if (!description) + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + g_autofree gchar *xml = NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); + + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + xml = virDomainGetXMLDesc(domain, flags); + if (!xml) return virtDBusUtilSetLastVirtError(error); - return sd_bus_reply_method_return(message, "s", description); + *outArgs = g_variant_new("(s)", xml); } -static void -virtDBusDomainStatsRecordListFreep(virDomainStatsRecordPtr **statsp) -{ - if (*statsp) - virDomainStatsRecordListFree(*statsp); -} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainStatsRecordPtr, virDomainStatsRecordListFree); -static int -virtDBusDomainGetStats(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainGetStats(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; virDomainPtr domains[2]; - _cleanup_(virtDBusDomainStatsRecordListFreep) virDomainStatsRecordPtr *records = NULL; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - uint32_t flags, stats; - int r; + g_autoptr(virDomainStatsRecordPtr) records = NULL; + guint stats; + guint flags; + GVariant *grecords; - r = sd_bus_message_read(message, "uu", &stats, &flags); - if (r < 0) - return r; + g_variant_get(inArgs, "(uu)", &stats, &flags); - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; domains[0] = domain; domains[1] = NULL; @@ -321,243 +297,213 @@ virtDBusDomainGetStats(sd_bus_message *message, if (virDomainListGetStats(domains, stats, &records, flags) != 1) return virtDBusUtilSetLastVirtError(error); - r = sd_bus_message_new_method_return(message, &reply); - if (r < 0) - return r; - - r = virtDBusUtilMessageAppendTypedParameters(reply, records[0]->params, records[0]->nparams); - if (r < 0) - return r; + grecords = virtDBusUtilTypedParamsToGVariant(records[0]->params, + records[0]->nparams); - return sd_bus_send(NULL, reply, NULL); + *outArgs = g_variant_new_tuple(&grecords, 1); } -static int -virtDBusDomainShutdown(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainShutdown(GVariant *inArgs G_GNUC_UNUSED, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int r; - - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; - - r = virDomainShutdown(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; - return sd_bus_reply_method_return(message, ""); + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + if (virDomainShutdown(domain) < 0) + virtDBusUtilSetLastVirtError(error); } -static int -virtDBusDomainDestroy(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainDestroy(GVariant *inArgs G_GNUC_UNUSED, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int r; - - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; - - r = virDomainDestroy(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - return sd_bus_reply_method_return(message, ""); + if (virDomainDestroy(domain) < 0) + virtDBusUtilSetLastVirtError(error); } -static int -virtDBusDomainReboot(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainReboot(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) + { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - uint32_t flags; - int r; - - r = sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; - - r = virDomainReboot(domain, flags); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); - return sd_bus_reply_method_return(message, ""); + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + if (virDomainReboot(domain, flags) < 0) + virtDBusUtilSetLastVirtError(error); } -static int -virtDBusDomainReset(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainReset(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) + { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - uint32_t flags; - int r; - - r = sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; - - r = virDomainReset(domain, flags); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); + + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - return sd_bus_reply_method_return(message, ""); + if (virDomainReset(domain, flags) < 0) + virtDBusUtilSetLastVirtError(error); } -static int -virtDBusDomainCreate(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainCreate(GVariant *inArgs G_GNUC_UNUSED, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int r; - - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; - - r = virDomainCreate(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; - return sd_bus_reply_method_return(message, ""); + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + if (virDomainCreate(domain) < 0) + virtDBusUtilSetLastVirtError(error); } -static int -virtDBusDomainUndefine(sd_bus_message *message, - void *userdata, - sd_bus_error *error) +static void +virtDBusDomainUndefine(GVariant *inArgs G_GNUC_UNUSED, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int r; - - domain = virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain == NULL) - return -1; - - r = virDomainUndefine(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect = userData; + g_autoptr(virDomain) domain = NULL; + + domain = virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; - return sd_bus_reply_method_return(message, ""); + if (virDomainUndefine(domain) < 0) + virtDBusUtilSetLastVirtError(error); } -static const sd_bus_vtable virt_domain_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("Name", "s", virtDBusDomainGetName, 0, 0), - SD_BUS_PROPERTY("UUID", "s", virtDBusDomainGetUUID, 0, 0), - SD_BUS_PROPERTY("Id", "u", virtDBusDomainGetId, 0, 0), - SD_BUS_PROPERTY("Vcpus", "u", virtDBusDomainGetVcpus, 0, 0), - SD_BUS_PROPERTY("OSType", "s", virtDBusDomainGetOsType, 0, 0), - SD_BUS_PROPERTY("Active", "b", virtDBusDomainGetActive, 0, 0), - SD_BUS_PROPERTY("Persistent", "b", virtDBusDomainGetPersistent, 0, 0), - SD_BUS_PROPERTY("State", "s", virtDBusDomainGetState, 0, 0), - SD_BUS_PROPERTY("Autostart", "b", virtDBusDomainGetAutostart, 0, 0), - - SD_BUS_METHOD("GetXMLDesc", "u", "s", virtDBusDomainGetXMLDesc, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetStats", "uu", "a{sv}", virtDBusDomainGetStats, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Shutdown", "", "", virtDBusDomainShutdown, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Destroy", "", "", virtDBusDomainDestroy, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Reboot", "u", "", virtDBusDomainReboot, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Reset", "u", "", virtDBusDomainReset, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Create", "", "", virtDBusDomainCreate, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Undefine", "", "", virtDBusDomainUndefine, SD_BUS_VTABLE_UNPRIVILEGED), - - SD_BUS_SIGNAL("DeviceAdded", "s", 0), - SD_BUS_SIGNAL("DeviceRemoved", "s", 0), - SD_BUS_SIGNAL("DiskChange", "ssss", 0), - SD_BUS_SIGNAL("TrayChange", "ss", 0), - - SD_BUS_VTABLE_END +static virtDBusGDBusPropertyTable virtDBusDomainPropertyTable[] = { + { "Name", virtDBusDomainGetName, NULL }, + { "UUID", virtDBusDomainGetUUID, NULL }, + { "Id", virtDBusDomainGetId, NULL }, + { "Vcpus", virtDBusDomainGetVcpus, NULL }, + { "OSType", virtDBusDomainGetOsType, NULL }, + { "Active", virtDBusDomainGetActive, NULL }, + { "Persistent", virtDBusDomainGetPersistent, NULL }, + { "State", virtDBusDomainGetState, NULL }, + { "Autostart", virtDBusDomainGetAutostart, NULL }, + { NULL, NULL, NULL } +}; + +static virtDBusGDBusMethodTable virtDBusDomainMethodTable[] = { + { "GetXMLDesc", virtDBusDomainGetXMLDesc }, + { "GetStats", virtDBusDomainGetStats }, + { "Shutdown", virtDBusDomainShutdown }, + { "Destroy", virtDBusDomainDestroy }, + { "Reboot", virtDBusDomainReboot }, + { "Reset", virtDBusDomainReset }, + { "Create", virtDBusDomainCreate }, + { "Undefine", virtDBusDomainUndefine }, + { NULL, NULL } }; -static int -virtDBusDomainLookup(sd_bus *bus VIRT_ATTR_UNUSED, - const char *path, - const char *interface VIRT_ATTR_UNUSED, - void *userdata, - void **found, - sd_bus_error *error VIRT_ATTR_UNUSED) +static gchar ** +virtDBusDomainEnumerate(gpointer userData) { - virtDBusConnect *connect = userdata; - _cleanup_(virtDBusUtilFreep) char *name = NULL; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain = NULL; - int r; + virtDBusConnect *connect = userData; + g_autoptr(virDomainPtr) domains = NULL; + gint num = 0; + gchar **ret = NULL; - r = sd_bus_path_decode(path, connect->domainPath, &name); - if (r < 0) - return r; + if (!virtDBusConnectOpen(connect, NULL)) + return NULL; - if (*name == '\0') - return 0; + num = virConnectListAllDomains(connect->connection, &domains, 0); + if (num < 0) + return NULL; - domain = virtDBusDomainGetVirDomain(connect, path, error); - if (!domain) - return 0; + if (num == 0) + return NULL; + + ret = g_new0(gchar *, num + 1); - /* - * There's no way to unref the pointer we're returning here. So, - * return the connect object and look up the domain again in the - * domain_* callbacks. - */ - *found = connect; + for (gint i = 0; i < num; i++) { + ret[i] = virtDBusUtilBusPathForVirDomain(domains[i], + connect->domainPath); + } - return 1; + return ret; } -int +static GDBusInterfaceInfo *interfaceInfo = NULL; + +void virtDBusDomainRegister(virtDBusConnect *connect, - sd_bus *bus) + GError **error) { - int r; - - r = asprintf(&connect->domainPath, "%s/domain", connect->connectPath); - if (r < 0) - return r; - - r = sd_bus_add_node_enumerator(bus, NULL, connect->domainPath, - connect->enumerateDomains, connect); - if (r < 0) - return r; - - return sd_bus_add_fallback_vtable(bus, - NULL, - connect->domainPath, - VIRT_DBUS_DOMAIN_INTERFACE, - virt_domain_vtable, - virtDBusDomainLookup, - connect); + connect->domainPath = g_strdup_printf("%s/domain", connect->connectPath); + + if (!interfaceInfo) { + interfaceInfo = virtDBusGDBusLoadIntrospectData(VIRT_DBUS_DOMAIN_INTERFACE, + error); + if (!interfaceInfo) + return; + } + + virtDBusGDBusRegisterSubtree(connect->bus, + connect->domainPath, + interfaceInfo, + virtDBusDomainEnumerate, + virtDBusDomainMethodTable, + virtDBusDomainPropertyTable, + connect); } diff --git a/src/domain.h b/src/domain.h index 03a29ed..7dc7e5b 100644 --- a/src/domain.h +++ b/src/domain.h @@ -2,10 +2,8 @@ #include "connect.h" -#include <systemd/sd-bus.h> - #define VIRT_DBUS_DOMAIN_INTERFACE "org.libvirt.Domain" -int +void virtDBusDomainRegister(virtDBusConnect *connect, - sd_bus *bus); + GError **error); diff --git a/src/events.c b/src/events.c index c45acd7..dada55f 100644 --- a/src/events.c +++ b/src/events.c @@ -2,23 +2,19 @@ #include "events.h" #include "util.h" -#include <assert.h> #include <libvirt/libvirt.h> -#include <systemd/sd-bus.h> -static int -virtDBusEventsDomainLifecycle(virConnectPtr connection VIRT_ATTR_UNUSED, +static gint +virtDBusEventsDomainLifecycle(virConnectPtr connection G_GNUC_UNUSED, virDomainPtr domain, - int event, - int detail VIRT_ATTR_UNUSED, - void *opaque) + gint event, + gint detail G_GNUC_UNUSED, + gpointer opaque) { virtDBusConnect *connect = opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL; - const char *signal = NULL; - const char *name; - _cleanup_(virtDBusUtilFreep) char *path = NULL; - int r; + const gchar *signal = NULL; + const gchar *name; + g_autofree gchar *path = NULL; switch (event) { case VIR_DOMAIN_EVENT_DEFINED: @@ -52,103 +48,77 @@ virtDBusEventsDomainLifecycle(virConnectPtr connection VIRT_ATTR_UNUSED, return 0; } - r = sd_bus_message_new_signal(connect->bus, - &message, - connect->connectPath, - VIRT_DBUS_CONNECT_INTERFACE, - signal); - if (r < 0) - return r; - name = virDomainGetName(domain); path = virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); - r = sd_bus_message_append(message, "so", name ? : "", path); - if (r < 0) - return r; + g_dbus_connection_emit_signal(connect->bus, + NULL, + connect->connectPath, + VIRT_DBUS_CONNECT_INTERFACE, + signal, + g_variant_new("(so)", name, path), + NULL); - return sd_bus_send(connect->bus, message, NULL); + return 0; } -static int -virtDBusEventsDomainDeviceAdded(virConnectPtr connection VIRT_ATTR_UNUSED, +static gint +virtDBusEventsDomainDeviceAdded(virConnectPtr connection G_GNUC_UNUSED, virDomainPtr domain, - const char *device, - void *opaque) + const gchar *device, + gpointer opaque) { virtDBusConnect *connect = opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL; - _cleanup_(virtDBusUtilFreep) char *path = NULL; - int r; + g_autofree gchar *path = NULL; path = virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); - r = sd_bus_message_new_signal(connect->bus, - &message, + g_dbus_connection_emit_signal(connect->bus, + NULL, path, VIRT_DBUS_DOMAIN_INTERFACE, - "DeviceAdded"); - if (r < 0) - return r; + "DeviceAdded", + g_variant_new("(s)", device), + NULL); - r = sd_bus_message_append(message, "s", device); - if (r < 0) - return r; - - return sd_bus_send(connect->bus, message, NULL); + return 0; } -static int -virtDBusEventsDomainDeviceRemoved(virConnectPtr connection VIRT_ATTR_UNUSED, +static gint +virtDBusEventsDomainDeviceRemoved(virConnectPtr connection G_GNUC_UNUSED, virDomainPtr domain, - const char *device, - void *opaque) + const gchar *device, + gpointer opaque) { virtDBusConnect *connect = opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL; - _cleanup_(virtDBusUtilFreep) char *path = NULL; - int r; + g_autofree gchar *path = NULL; path = virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); - r = sd_bus_message_new_signal(connect->bus, - &message, + g_dbus_connection_emit_signal(connect->bus, + NULL, path, VIRT_DBUS_DOMAIN_INTERFACE, - "DeviceRemoved"); - if (r < 0) - return r; - - r = sd_bus_message_append(message, "s", device); - if (r < 0) - return r; + "DeviceRemoved", + g_variant_new("(s)", device), + NULL); - return sd_bus_send(connect->bus, message, NULL); + return 0; } -static int -virtDBusEventsDomainTrayChange(virConnectPtr connection VIRT_ATTR_UNUSED, +static gint +virtDBusEventsDomainTrayChange(virConnectPtr connection G_GNUC_UNUSED, virDomainPtr domain, - const char *device, - int reason, - void *opaque) + const gchar *device, + gint reason, + gpointer opaque) { virtDBusConnect *connect = opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL; - _cleanup_(virtDBusUtilFreep) char *path = NULL; - const char *reasonstr; - int r; + g_autofree gchar *path = NULL; + const gchar *reasonstr; path = virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); - r = sd_bus_message_new_signal(connect->bus, - &message, - path, - VIRT_DBUS_DOMAIN_INTERFACE, - "TrayChange"); - if (r < 0) - return r; - switch (reason) { case VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN: reasonstr = "open"; @@ -161,38 +131,32 @@ virtDBusEventsDomainTrayChange(virConnectPtr connection VIRT_ATTR_UNUSED, break; } - r = sd_bus_message_append(message, "ss", device, reasonstr); - if (r < 0) - return r; + g_dbus_connection_emit_signal(connect->bus, + NULL, + path, + VIRT_DBUS_DOMAIN_INTERFACE, + "TrayChange", + g_variant_new("(ss)", device, reasonstr), + NULL); - return sd_bus_send(connect->bus, message, NULL); + return 0; } -static int -virtDBusEventsDomainDiskChange(virConnectPtr connection VIRT_ATTR_UNUSED, +static gint +virtDBusEventsDomainDiskChange(virConnectPtr connection G_GNUC_UNUSED, virDomainPtr domain, - const char *old_src_path, - const char *new_src_path, - const char *device, - int reason, - void *opaque) + const gchar *old_src_path, + const gchar *new_src_path, + const gchar *device, + gint reason, + gpointer opaque) { virtDBusConnect *connect = opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL; - _cleanup_(virtDBusUtilFreep) char *path = NULL; - const char *reasonstr; - int r; + g_autofree gchar *path = NULL; + const gchar *reasonstr; path = virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); - r = sd_bus_message_new_signal(connect->bus, - &message, - path, - VIRT_DBUS_DOMAIN_INTERFACE, - "DiskChange"); - if (r < 0) - return r; - switch (reason) { case VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START: reasonstr = "missing-on-start"; @@ -205,19 +169,24 @@ virtDBusEventsDomainDiskChange(virConnectPtr connection VIRT_ATTR_UNUSED, break; } - r = sd_bus_message_append(message, "ssss", old_src_path, new_src_path, device, reasonstr); - if (r < 0) - return r; + g_dbus_connection_emit_signal(connect->bus, + NULL, + path, + VIRT_DBUS_DOMAIN_INTERFACE, + "DiskChange", + g_variant_new("(ssss)", old_src_path, + new_src_path, device, reasonstr), + NULL); - return sd_bus_send(connect->bus, message, NULL); + return 0; } static void virtDBusEventsRegisterEvent(virtDBusConnect *connect, - int id, + gint id, virConnectDomainEventGenericCallback callback) { - assert(connect->callback_ids[id] == -1); + g_assert(connect->callback_ids[id] == -1); connect->callback_ids[id] = virConnectDomainEventRegisterAny(connect->connection, NULL, diff --git a/src/main.c b/src/main.c index 6f11aab..bbbec09 100644 --- a/src/main.c +++ b/src/main.c @@ -1,92 +1,23 @@ -#include "config.h" - #include "connect.h" #include "util.h" -#include <errno.h> -#include <getopt.h> -#include <poll.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/signalfd.h> -#include <systemd/sd-bus.h> -#include <unistd.h> - -static int loop_status; - -static int -virtDBusGetLibvirtEvents(sd_bus *bus) -{ - int events; - int virt_events = 0; - - events = sd_bus_get_events(bus); - - if (events & POLLIN) - virt_events |= VIR_EVENT_HANDLE_READABLE; - - if (events & POLLOUT) - virt_events |= VIR_EVENT_HANDLE_WRITABLE; - - return virt_events; -} +#include <glib-unix.h> +#include <libvirt-glib/libvirt-glib.h> -static int -virtDBusProcessEvents(sd_bus *bus) -{ - for (;;) { - int r; - - r = sd_bus_process(bus, NULL); - if (r < 0) - return r; - - if (r == 0) - break; - } - - return 0; -} - -static void -virtDBusVirEventRemoveHandlep(int *watchp) -{ - if (*watchp >= 0) - virEventRemoveHandle(*watchp); -} - -static void -virtDBusHandleSignal(int watch VIRT_ATTR_UNUSED, - int fd VIRT_ATTR_UNUSED, - int events VIRT_ATTR_UNUSED, - void *opaque VIRT_ATTR_UNUSED) -{ - loop_status = -ECANCELED; -} - -static void -virtDBusHandleBusEvent(int watch, - int fd VIRT_ATTR_UNUSED, - int events VIRT_ATTR_UNUSED, - void *opaque) -{ - sd_bus *bus = opaque; - - loop_status = virtDBusProcessEvents(bus); - - if (loop_status < 0) - return; - - virEventUpdateHandle(watch, virtDBusGetLibvirtEvents(bus)); -} +struct _virtDBusDriver { + const gchar *uri; + const gchar *object; +}; +typedef struct _virtDBusDriver virtDBusDriver; -struct virtDBusDriver { - const char *uri; - const char *object; +struct _virtDBusRegisterData { + virtDBusConnect **connectList; + const virtDBusDriver *drivers; + gsize ndrivers; }; +typedef struct _virtDBusRegisterData virtDBusRegisterData; -static const struct virtDBusDriver sessionDrivers[] = { +static const virtDBusDriver sessionDrivers[] = { { "qemu:///session", "/org/libvirt/QEMU" }, { "test:///default", "/org/libvirt/Test" }, { "uml:///session", "/org/libvirt/UML" }, @@ -96,7 +27,7 @@ static const struct virtDBusDriver sessionDrivers[] = { { "vmwarews:///session", "/org/libvirt/VMwareWS" }, }; -static const struct virtDBusDriver systemDrivers[] = { +static const virtDBusDriver systemDrivers[] = { { "bhyve:///system", "/org/libvirt/BHyve" }, { "lxc:///", "/org/libvirt/LXC" }, { "openvz:///system", "/org/libvirt/OpenVZ" }, @@ -108,131 +39,133 @@ static const struct virtDBusDriver systemDrivers[] = { { "xen:///", "/org/libvirt/Xen" }, }; -int -main(int argc, char *argv[]) +static gboolean +virtDBusHandleSignal(gpointer data) { - enum { - ARG_SYSTEM = 255, - ARG_SESSION - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "system", no_argument, NULL, ARG_SYSTEM }, - { "session", no_argument, NULL, ARG_SESSION }, - {} - }; - - bool system_bus; - const struct virtDBusDriver *drivers = NULL; - int ndrivers = 0; - - _cleanup_(virtDBusConnectListFree) virtDBusConnect **connect = NULL; - _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; - _cleanup_(virtDBusUtilClosep) int signal_fd = -1; - _cleanup_(virtDBusVirEventRemoveHandlep) int bus_watch = -1; - _cleanup_(virtDBusVirEventRemoveHandlep) int signal_watch = -1; - sigset_t mask; - int c; - int r; - - if (geteuid() == 0) { - system_bus = true; - } else { - system_bus = false; - } + g_main_loop_quit(data); + return TRUE; +} - while ((c = getopt_long(argc, argv, "hc:", options, NULL)) >= 0) { - switch (c) { - case 'h': - printf("Usage: %s [OPTIONS]\n", program_invocation_short_name); - printf("\n"); - printf("Provide a D-Bus interface to a libvirtd.\n"); - printf("\n"); - printf(" -h, --help Display this help text and exit\n"); - printf(" --session Connect to the session bus\n"); - printf(" --system Connect to the system bus\n"); - return 0; - - case ARG_SYSTEM: - system_bus = true; - break; - - case ARG_SESSION: - system_bus = false; - break; - - default: - return EXIT_FAILURE; +static void +virtDBusAcquired(GDBusConnection *connection, + const gchar *name G_GNUC_UNUSED, + gpointer opaque) +{ + virtDBusRegisterData *data = opaque; + GError *error = NULL; + + for (gsize i = 0; i < data->ndrivers; i += 1) { + virtDBusConnectNew(&data->connectList[i], connection, + data->drivers[i].uri, data->drivers[i].object, + &error); + if (error) { + g_printerr("%s\n", error->message); + exit(EXIT_FAILURE); } } - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGINT); - sigprocmask(SIG_BLOCK, &mask, NULL); +} + +static void +virtDBusNameAcquired(GDBusConnection *connection G_GNUC_UNUSED, + const gchar *name G_GNUC_UNUSED, + gpointer data G_GNUC_UNUSED) +{ +} + +static void +virtDBusNameLost(GDBusConnection *connection G_GNUC_UNUSED, + const gchar *name G_GNUC_UNUSED, + gpointer data G_GNUC_UNUSED) +{ + g_printerr("Disconnected from D-Bus.\n"); + exit(EXIT_FAILURE); +} + +static void +virtDBusRegisterDataFree(virtDBusRegisterData *data) +{ + virtDBusConnectListFree(data->connectList); +} +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(virtDBusRegisterData, virtDBusRegisterDataFree); + +int +main(gint argc, gchar *argv[]) +{ + static gboolean systemOpt = FALSE; + static gboolean sessionOpt = FALSE; + GBusType busType; + g_auto(virtDBusGDBusSource) sigintSource = 0; + g_auto(virtDBusGDBusSource) sigtermSource = 0; + g_auto(virtDBusGDBusOwner) busOwner = 0; + g_autoptr(GOptionContext) context = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GMainLoop) loop = NULL; + g_auto(virtDBusRegisterData) data = { 0 }; + + static GOptionEntry options[] = { + { "system", 0, 0, G_OPTION_ARG_NONE, &systemOpt, + "Connect to the system bus", NULL }, + { "session", 0, 0, G_OPTION_ARG_NONE, &sessionOpt, + "Connect to the session bus", NULL }, + { NULL } + }; - virEventRegisterDefaultImpl(); + context = g_option_context_new("Provide a D-Bus interface to a libvirtd."); + g_option_context_add_main_entries(context, options, NULL); - r = system_bus ? sd_bus_open_system(&bus) : sd_bus_open_user(&bus); - if (r < 0) { - fprintf(stderr, "Failed to connect to session bus: %s\n", strerror(-r)); - return EXIT_FAILURE; + if (!g_option_context_parse(context, &argc, &argv, &error)) { + g_printerr("%s\n", error->message); + exit(EXIT_FAILURE); } - r = sd_bus_request_name(bus, "org.libvirt", 0); - if (r < 0) { - fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r)); - return EXIT_FAILURE; + if (sessionOpt && systemOpt) { + g_printerr("Only one of --session or --system can be used.\n"); + exit(EXIT_FAILURE); } - if (system_bus) { - drivers = systemDrivers; - ndrivers = VIRT_N_ELEMENTS(systemDrivers); + if (sessionOpt) { + busType = G_BUS_TYPE_SESSION; + } else if (systemOpt) { + busType = G_BUS_TYPE_SYSTEM; } else { - drivers = sessionDrivers; - ndrivers = VIRT_N_ELEMENTS(sessionDrivers); + if (geteuid() == 0) { + busType = G_BUS_TYPE_SYSTEM; + } else { + busType = G_BUS_TYPE_SESSION; + } } - connect = calloc(ndrivers + 1, sizeof(virtDBusConnect *)); - - for (int i = 0; i < ndrivers; i += 1) { - r = virtDBusConnectNew(&connect[i], bus, - drivers[i].uri, drivers[i].object); - if (r < 0) { - fprintf(stderr, "Failed to register libvirt connection.\n"); - return EXIT_FAILURE; - } + if (busType == G_BUS_TYPE_SYSTEM) { + data.drivers = systemDrivers; + data.ndrivers = G_N_ELEMENTS(systemDrivers); + } else { + data.drivers = sessionDrivers; + data.ndrivers = G_N_ELEMENTS(sessionDrivers); } + data.connectList = g_new0(virtDBusConnect *, data.ndrivers + 1); - r = virtDBusProcessEvents(bus); - if (r < 0) - return EXIT_FAILURE; + loop = g_main_loop_new(NULL, FALSE); - bus_watch = virEventAddHandle(sd_bus_get_fd(bus), - virtDBusGetLibvirtEvents(bus), - virtDBusHandleBusEvent, - bus, - NULL); + sigtermSource = g_unix_signal_add(SIGTERM, + virtDBusHandleSignal, + loop); - signal_fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); - signal_watch = virEventAddHandle(signal_fd, - VIR_EVENT_HANDLE_READABLE, + sigintSource = g_unix_signal_add(SIGINT, virtDBusHandleSignal, - NULL, - NULL); - if (signal_watch < 0) { - fprintf(stderr, "Failed to register signal handler.\n"); - return EXIT_FAILURE; - } + loop); - while (loop_status >= 0) - virEventRunDefaultImpl(); + gvir_init(0, NULL); + gvir_event_register(); - if (loop_status < 0 && loop_status != -ECANCELED) { - fprintf(stderr, "Error: %s\n", strerror(-loop_status)); - return EXIT_FAILURE; - } + busOwner = g_bus_own_name(busType, "org.libvirt", + G_BUS_NAME_OWNER_FLAGS_NONE, + virtDBusAcquired, + virtDBusNameAcquired, + virtDBusNameLost, + &data, NULL); + + g_main_loop_run(loop); return EXIT_SUCCESS; } diff --git a/src/util.c b/src/util.c index 9042a0f..d6c27f3 100644 --- a/src/util.c +++ b/src/util.c @@ -1,155 +1,126 @@ #include "util.h" #include <libvirt/virterror.h> -#include <stdlib.h> -#include <unistd.h> +#include <string.h> -int -virtDBusUtilMessageAppendTypedParameters(sd_bus_message *message, - virTypedParameterPtr parameters, - int n_parameters) +static const GDBusErrorEntry virtDBusUtilErrorEntries[] = { + { VIRT_DBUS_ERROR_LIBVIRT, "org.libvirt.Error" }, +}; + +G_STATIC_ASSERT(G_N_ELEMENTS(virtDBusUtilErrorEntries) == VIRT_DBUS_N_ERRORS); + +GQuark +virtDBusErrorQuark(void) { - int r; + static volatile gsize quarkVolatile = 0; + g_dbus_error_register_error_domain("virt-dbus-error-quark", + &quarkVolatile, + virtDBusUtilErrorEntries, + G_N_ELEMENTS(virtDBusUtilErrorEntries)); + return (GQuark) quarkVolatile; +} - r = sd_bus_message_open_container(message, 'a', "{sv}"); - if (r < 0) - return r; +GVariant * +virtDBusUtilTypedParamsToGVariant(virTypedParameterPtr params, + gint nparams) +{ + GVariantBuilder builder; - for (int i = 0; i < n_parameters; i += 1) { - r = sd_bus_message_open_container(message, SD_BUS_TYPE_DICT_ENTRY, "sv"); - if (r < 0) - return r; + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); - r = sd_bus_message_append(message, "s", parameters[i].field); - if (r < 0) - return r; + for (gint i = 0; i < nparams; i++) { + GVariant *value = NULL; - switch (parameters[i].type) { + switch (params[i].type) { case VIR_TYPED_PARAM_INT: - r = sd_bus_message_append(message, "v", "i", parameters[i].value.i); + value = g_variant_new("i", params[i].value.i); break; case VIR_TYPED_PARAM_UINT: - r = sd_bus_message_append(message, "v", "u", parameters[i].value.ui); + value = g_variant_new("u", params[i].value.ui); break; case VIR_TYPED_PARAM_LLONG: - r = sd_bus_message_append(message, "v", "x", parameters[i].value.l); + value = g_variant_new("x", params[i].value.l); break; case VIR_TYPED_PARAM_ULLONG: - r = sd_bus_message_append(message, "v", "t", parameters[i].value.ul); + value = g_variant_new("t", params[i].value.ul); break; case VIR_TYPED_PARAM_DOUBLE: - r = sd_bus_message_append(message, "v", "d", parameters[i].value.d); + value = g_variant_new("d", params[i].value.d); break; case VIR_TYPED_PARAM_BOOLEAN: - r = sd_bus_message_append(message, "v", "b", parameters[i].value.b); + value = g_variant_new("b", params[i].value.b); break; case VIR_TYPED_PARAM_STRING: - r = sd_bus_message_append(message, "v", "s", parameters[i].value.s); + value = g_variant_new("s", params[i].value.s); break; } - if (r < 0) - return r; - - r = sd_bus_message_close_container(message); - if (r < 0) - return r; + g_variant_builder_add(&builder, "{sv}", + params[i].field, + g_variant_new_variant(value)); } - return sd_bus_message_close_container(message); + return g_variant_builder_end(&builder); } -int -virtDBusUtilSetLastVirtError(sd_bus_error *error) +void +virtDBusUtilSetLastVirtError(GError **error) { virErrorPtr vir_error; vir_error = virGetLastError(); - if (!vir_error) - return 0; + if (!vir_error) { + g_set_error(error, VIRT_DBUS_ERROR, VIRT_DBUS_ERROR_LIBVIRT, + "unknown error"); + } else { + g_set_error_literal(error, VIRT_DBUS_ERROR, VIRT_DBUS_ERROR_LIBVIRT, + vir_error->message); + } +} - return sd_bus_error_set(error, VIRT_DBUS_ERROR_INTERFACE, vir_error->message); +static gchar * +virtDBusUtilEncodeUUID(const gchar *uuid) +{ + gchar *ret = g_strdup_printf("_%s", uuid); + return g_strdelimit(ret, "-", '_'); } -int -virtDBusUtilSetError(sd_bus_error *error, - const char *message) +static gchar * +virtDBusUtilDecodeUUID(const gchar *uuid) { - return sd_bus_error_set(error, VIRT_DBUS_ERROR_INTERFACE, message); + gchar *ret = g_strdup(uuid+1); + return g_strdelimit(ret, "_", '-'); } -char * +gchar * virtDBusUtilBusPathForVirDomain(virDomainPtr domain, - const char *domainPath) + const gchar *domainPath) { - char *path = NULL; - char uuid[VIR_UUID_STRING_BUFLEN] = ""; - + gchar uuid[VIR_UUID_STRING_BUFLEN] = ""; + g_autofree gchar *newUuid = NULL; virDomainGetUUIDString(domain, uuid); - sd_bus_path_encode(domainPath, uuid, &path); - - return path; + newUuid = virtDBusUtilEncodeUUID(uuid); + return g_strdup_printf("%s/%s", domainPath, newUuid); } virDomainPtr virtDBusUtilVirDomainFromBusPath(virConnectPtr connection, - const char *path, - const char *domainPath) + const gchar *path, + const gchar *domainPath) { - _cleanup_(virtDBusUtilFreep) char *name = NULL; - int r; + g_autofree gchar *name = NULL; + gsize prefixLen = strlen(domainPath) + 1; - r = sd_bus_path_decode(path, domainPath, &name); - if (r < 0) - return NULL; + name = virtDBusUtilDecodeUUID(path+prefixLen); return virDomainLookupByUUIDString(connection, name); } void -virtDBusUtilFreep(void *p) -{ - free(*(void **)p); -} - -void -virtDBusUtilClosep(int *fdp) -{ - if (*fdp >= 0) - close(*fdp); -} - -void -virtDBusUtilStrvFreep(void *p) -{ - char **strv = *(char ***)p; - - if (strv == NULL) - return; - - for (unsigned i = 0; strv[i] != NULL; i++) - free(strv[i]); - - free(strv); -} - -void -virtDBusUtilVirDomainFreep(virDomainPtr *domainp) -{ - if (*domainp) - virDomainFree(*domainp); -} - -void -virtDBusUtilVirDomainListFreep(virDomainPtr **domainsp) +virtDBusUtilVirDomainListFree(virDomainPtr *domains) { - virDomainPtr *domains = *domainsp; - - if (!domains) - return; - - for (int i = 0; domains[i] != NULL; i += 1) + for (gint i = 0; domains[i] != NULL; i += 1) virDomainFree(domains[i]); - free(domains); + g_free(domains); } diff --git a/src/util.h b/src/util.h index 2a6f7e2..8cafafa 100644 --- a/src/util.h +++ b/src/util.h @@ -1,49 +1,38 @@ #pragma once -#include <libvirt/libvirt.h> -#include <systemd/sd-bus.h> - -#define VIRT_DBUS_ERROR_INTERFACE "org.libvirt.Error" - -#define _cleanup_(_x) __attribute__((__cleanup__(_x))) +#include "gdbus.h" -#define VIRT_ATTR_UNUSED __attribute__((__unused__)) +#include <libvirt/libvirt.h> -#define VIRT_N_ELEMENTS(array) (sizeof(array) / sizeof(*(array))) +#define VIRT_DBUS_ERROR virtDBusErrorQuark() +typedef enum { + VIRT_DBUS_ERROR_LIBVIRT, + VIRT_DBUS_N_ERRORS /*< skip >*/ +} VirtDBusError; -int -virtDBusUtilMessageAppendTypedParameters(sd_bus_message *message, - virTypedParameterPtr parameters, - int n_parameters); +GQuark +virtDBusErrorQuark(void); -int -virtDBusUtilSetLastVirtError(sd_bus_error *error); +GVariant * +virtDBusUtilTypedParamsToGVariant(virTypedParameterPtr params, + gint nparams); -int -virtDBusUtilSetError(sd_bus_error *error, - const char *message); +void +virtDBusUtilSetLastVirtError(GError **error); -char * +gchar * virtDBusUtilBusPathForVirDomain(virDomainPtr domain, - const char *domainPath); + const gchar *domainPath); virDomainPtr virtDBusUtilVirDomainFromBusPath(virConnectPtr connection, - const char *path, - const char *domainPath); + const gchar *path, + const gchar *domainPath); void -virtDBusUtilFreep(void *p); +virtDBusUtilVirDomainListFree(virDomainPtr *domains); -void -virtDBusUtilClosep(int *fdp); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomain, virDomainFree); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainPtr, virtDBusUtilVirDomainListFree); -void -virtDBusUtilStrvFreep(void *p); - -void -virtDBusUtilVirDomainFreep(virDomainPtr *domainp); - -void -virtDBusUtilVirDomainListFreep(virDomainPtr **domainsp); diff --git a/test/travis-run b/test/travis-run index 28260f4..7577253 100755 --- a/test/travis-run +++ b/test/travis-run @@ -22,7 +22,7 @@ sudo chroot "$CHROOT" << EOF set -ex # install build deps apt-get update -apt-get install -y dh-autoreconf pkg-config libvirt-dev libsystemd-dev libglib2.0-dev libtool python3-gi python3-dbus dbus +apt-get install -y dh-autoreconf pkg-config libvirt-dev libglib2.0-dev libtool python3-gi python3-dbus dbus # run build and tests as user chown -R buildd:buildd /build -- 2.14.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list