From nobody Thu May 2 23:13:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 152162657454318.91809871805731; Wed, 21 Mar 2018 03:02:54 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 900E15BEC9; Wed, 21 Mar 2018 10:02:52 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CE2EC5DD84; Wed, 21 Mar 2018 10:02:51 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EE6644CA99; Wed, 21 Mar 2018 10:02:50 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w2LA2nPb023252 for ; Wed, 21 Mar 2018 06:02:49 -0400 Received: by smtp.corp.redhat.com (Postfix) id 7E3A7215CDB7; Wed, 21 Mar 2018 10:02:49 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id 088992166BDA for ; Wed, 21 Mar 2018 10:02:48 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 21 Mar 2018 11:02:43 +0100 Message-Id: <425bbae062daa26074f79484a8cce373c2afa968.1521626292.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-loop: libvir-list@redhat.com Subject: [libvirt] [dbus PATCH v3 1/5] introduce support for GDBus implementation X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 21 Mar 2018 10:02:53 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" We will switch to GDBus implementation of D-Bus protocol because sd-bus implementation is not thread safe. Processing messages in threads is essential since Libvirt API can take some significant amount of time to return and that would block the whole libvirt-dbus daemon. Signed-off-by: Pavel Hrdina --- Changes in v3: - fixed a bug while loading XML interface files, now it fails gracefully with error message Changes in v2: - changed glib2 required version to 2.44.0, required for the auto-cleanup macros - changed libvirt-glib required version to 0.0.7 README | 1 + configure.ac | 12 ++ data/Makefile.am | 5 + libvirt-dbus.spec.in | 6 + src/Makefile.am | 17 ++- src/gdbus.c | 398 +++++++++++++++++++++++++++++++++++++++++++++++= ++++ src/gdbus.h | 108 ++++++++++++++ test/Makefile.am | 3 +- test/travis-run | 2 +- 9 files changed, 547 insertions(+), 5 deletions(-) create mode 100644 src/gdbus.c create mode 100644 src/gdbus.h diff --git a/README b/README index 754d957..a85114e 100644 --- a/README +++ b/README @@ -58,6 +58,7 @@ The packages required to build libvirt-dbus are =20 - systemd-211 - libvirt + - glib2 =20 Patches submissions =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/configure.ac b/configure.ac index df1a375..0e3bc01 100644 --- a/configure.ac +++ b/configure.ac @@ -11,10 +11,14 @@ AC_USE_SYSTEM_EXTENSIONS =20 AM_SILENT_RULES([yes]) =20 +GLIB2_REQUIRED=3D2.44.0 LIBVIRT_REQUIRED=3D1.2.8 SYSTEMD_REQUIRED=3D211 +LIBVIRT_GLIB_REQUIRED=3D0.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 =20 LIBVIRT_DBUS_MAJOR_VERSION=3D`echo $VERSION | awk -F. '{print $1}'` LIBVIRT_DBUS_MINOR_VERSION=3D`echo $VERSION | awk -F. '{print $2}'` @@ -34,8 +38,11 @@ AC_PROG_MKDIR_P AM_PROG_CC_C_O AC_PROG_CC_STDC =20 +PKG_CHECK_MODULES(GIO2, gio-unix-2.0 >=3D GLIB2_REQUIRED) +PKG_CHECK_MODULES(GLIB2, glib-2.0 >=3D GLIB2_REQUIRED) PKG_CHECK_MODULES(LIBVIRT, libvirt >=3D $LIBVIRT_REQUIRED) PKG_CHECK_MODULES(SYSTEMD, libsystemd >=3D $SYSTEMD_REQUIRED) +PKG_CHECK_MODULES(LIBVIRT_GLIB, libvirt-glib-1.0 >=3D LIBVIRT_GLIB_REQUIRE= D) =20 LIBVIRT_COMPILE_WARNINGS LIBVIRT_LINKER_RELRO @@ -56,6 +63,11 @@ LIBVIRT_ARG_WITH([DBUS_SYSTEM_POLICIES], [where D-Bus sy= stem policies directory DBUS_SYSTEM_POLICIES_DIR=3D"$with_dbus_system_policies" AC_SUBST(DBUS_SYSTEM_POLICIES_DIR) =20 +LIBVIRT_ARG_WITH([DBUS_INTERFACES], [where D-Bus interfaces directory is], + ['$(datadir)/dbus-1/interfaces']) +DBUS_INTERFACES_DIR=3D"$with_dbus_interfaces" +AC_SUBST([DBUS_INTERFACES_DIR]) + LIBVIRT_ARG_WITH([SYSTEM_USER], [username to run system instance as], ['libvirtdbus']) SYSTEM_USER=3D$with_system_user diff --git a/data/Makefile.am b/data/Makefile.am index 9a53305..a886687 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -18,11 +18,16 @@ polkit_files =3D \ polkitdir =3D $(sysconfdir)/polkit-1/rules.d polkit_DATA =3D $(polkit_files:.rules.in=3D.rules) =20 +interfaces_files =3D +interfacesdir =3D $(DBUS_INTERFACES_DIR) +interfaces_DATA =3D $(interfaces_files) + EXTRA_DIST =3D \ $(service_in_files) \ $(system_service_in_files) \ $(system_policy_files) \ $(polkit_files) \ + $(interfaces_files) \ $(NULL) =20 CLEANFILES =3D \ diff --git a/libvirt-dbus.spec.in b/libvirt-dbus.spec.in index ce5cecf..662ece1 100644 --- a/libvirt-dbus.spec.in +++ b/libvirt-dbus.spec.in @@ -1,7 +1,9 @@ # -*- rpm-spec -*- =20 +%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@ =20 Name: @PACKAGE@ @@ -15,11 +17,15 @@ Source0: ftp://libvirt.org/libvirt/dbus/%{name}-%{versi= on}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) =20 BuildRequires: gcc +BuildRequires: glib2-devel >=3D %{glib2_version} BuildRequires: libvirt-devel >=3D %{libvirt_version} BuildRequires: systemd-devel >=3D %{systemd_version} +BuildRequires: libvirt-glib-devel >=3D %{libvirt_glib_version} =20 +Requires: glib2 >=3D %{glib2_version} Requires: libvirt-libs >=3D %{libvirt_version} Requires: systemd-libs >=3D %{systemd_version} +Requires: libvirt-glib >=3D %{libvirt_glib_version} =20 Requires(pre): shadow-utils =20 diff --git a/src/Makefile.am b/src/Makefile.am index 1a5b50b..e7bba9d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,14 @@ AM_CPPFLAGS =3D \ - -I$(top_srcdir)/src + -I$(top_srcdir)/src \ + -DVIRT_DBUS_INTERFACES_DIR=3D\"$(DBUS_INTERFACES_DIR)\" =20 DAEMON_SOURCES =3D \ main.c \ connect.c connect.h \ util.c util.h \ domain.c domain.h \ - events.c events.h + events.c events.h \ + gdbus.c gdbus.h =20 EXTRA_DIST =3D \ $(DAEMON_SOURCES) @@ -18,18 +20,27 @@ libvirt_dbus_SOURCES =3D $(DAEMON_SOURCES) =20 libvirt_dbus_CFLAGS =3D \ $(SYSTEMD_CFLAGS) \ + $(GIO2_CFLAGS) \ + $(GLIB2_CFLAGS) \ $(LIBVIRT_CFLAGS) \ + $(LIBVIRT_GLIB_CFLAGS) \ $(WARN_CFLAGS) \ $(PIE_CFLAGS) \ $(NULL) =20 libvirt_dbus_LDFLAGS =3D \ $(SYSTEMD_LDFLAGS) \ + $(GIO2_LDFLAGS) \ + $(GLIB2_LDFLAGS) \ $(LIBVIRT_LDFLAGS) \ + $(LIBVIRT_GLIB_LDFLAGS) \ $(RELRO_LDFLAGS) \ $(PID_LDFLAGS) \ $(NULL) =20 libvirt_dbus_LDADD =3D \ $(SYSTEMD_LIBS) \ - $(LIBVIRT_LIBS) + $(GIO2_LIBS) \ + $(GLIB2_LIBS) \ + $(LIBVIRT_LIBS) \ + $(LIBVIRT_GLIB_LIBS) diff --git a/src/gdbus.c b/src/gdbus.c new file mode 100644 index 0000000..cbfd07d --- /dev/null +++ b/src/gdbus.c @@ -0,0 +1,398 @@ +#include "gdbus.h" + +#include + +struct _virtDBusGDBusMethodData { + virtDBusGDBusMethodTable *methods; + virtDBusGDBusPropertyTable *properties; + gpointer *userData; +}; +typedef struct _virtDBusGDBusMethodData virtDBusGDBusMethodData; + +struct _virtDBusGDBusSubtreeData { + GDBusInterfaceInfo *interface; + virtDBusGDBusEnumerateFunc enumerate; + virtDBusGDBusMethodData *methodData; +}; +typedef struct _virtDBusGDBusSubtreeData virtDBusGDBusSubtreeData; + +static const gchar *dbusInterfacePrefix =3D NULL; + +/** + * virtDBusGDBusLoadIntrospectData: + * @interface: name of the interface + * @error: return location for error + * + * Reads an interface XML description from file and returns new + * interface info. The caller owns an reference to the returned info. + * + * The file path is constructed as: + * + * VIRT_DBUS_INTERFACES_DIR/{@interface}.xml + * + * Returns interface info on success, NULL on failure. + */ +GDBusInterfaceInfo * +virtDBusGDBusLoadIntrospectData(gchar const *interface, + GError **error) +{ + g_autofree gchar *introspectFile =3D NULL; + g_autofree gchar *introspectXML =3D NULL; + g_autoptr(GDBusNodeInfo) nodeInfo =3D NULL; + GDBusInterfaceInfo *ret; + + if (!dbusInterfacePrefix) { + dbusInterfacePrefix =3D g_getenv("VIRT_DBUS_INTERFACES_DIR"); + if (!dbusInterfacePrefix) + dbusInterfacePrefix =3D VIRT_DBUS_INTERFACES_DIR; + } + + introspectFile =3D g_strdup_printf("%s/%s.xml", dbusInterfacePrefix, i= nterface); + + if (!g_file_get_contents(introspectFile, &introspectXML, NULL, error)) + return NULL; + + nodeInfo =3D g_dbus_node_info_new_for_xml(introspectXML, error); + if (!nodeInfo) + return NULL; + + ret =3D nodeInfo->interfaces[0]; + if (!ret) { + g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + "no interface defined in '%s'", introspectFile); + return NULL; + } + + return g_dbus_interface_info_ref(ret); +} + +static void +virtDBusGDBusHandlePropertyGet(GVariant *parameters, + GDBusMethodInvocation *invocation, + const gchar *objectPath, + virtDBusGDBusMethodData *data) +{ + virtDBusGDBusPropertyGetFunc getFunc =3D NULL; + const gchar *interface; + const gchar *name; + GVariant *value =3D NULL; + GError *error =3D NULL; + + g_variant_get(parameters, "(&s&s)", &interface, &name); + + for (gint i =3D 0; data->properties[i].name; i++) { + if (g_strcmp0(name, data->properties[i].name) =3D=3D 0) { + getFunc =3D data->properties[i].getFunc; + break; + } + } + + if (!getFunc) { + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_PROPERT= Y, + "unknown property '%s'", nam= e); + return; + } + + getFunc(objectPath, data->userData, &value, &error); + + if (error) { + g_dbus_method_invocation_return_gerror(invocation, error); + return; + } + + g_return_if_fail(value); + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(v)", value)); +} + +static void +virtDBusGDBusHandlePropertySet(GVariant *parameters, + GDBusMethodInvocation *invocation, + const gchar *objectPath, + virtDBusGDBusMethodData *data) +{ + virtDBusGDBusPropertySetFunc setFunc =3D NULL; + const gchar *interface; + const gchar *name; + g_autoptr(GVariant) value =3D NULL; + GError *error =3D NULL; + + g_variant_get(parameters, "(&s&sv)", &interface, &name, &value); + + for (gint i =3D 0; data->properties[i].name; i++) { + if (g_strcmp0(name, data->properties[i].name) =3D=3D 0) { + setFunc =3D data->properties[i].setFunc; + break; + } + } + + if (!setFunc) { + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_PROPERT= Y, + "unknown property '%s'", nam= e); + return; + } + + setFunc(value, objectPath, data->userData, &error); + + if (error) + g_dbus_method_invocation_return_gerror(invocation, error); + else + g_dbus_method_invocation_return_value(invocation, NULL); +} + +static void +virtDBusGDBusHandlePropertyGetAll(GDBusMethodInvocation *invocation, + const gchar *objectPath, + virtDBusGDBusMethodData *data) +{ + GVariant *value; + g_auto(GVariantBuilder) builder; + GError *error =3D NULL; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("(a{sv})")); + + g_variant_builder_open(&builder, G_VARIANT_TYPE("a{sv}")); + + for (gint i =3D 0; data->properties[i].name; i++) { + data->properties[i].getFunc(objectPath, data->userData, + &value, &error); + + if (error) { + g_dbus_method_invocation_return_gerror(invocation, error); + return; + } + + g_return_if_fail(value); + + g_variant_builder_add(&builder, "{sv}", + data->properties[i].name, + g_variant_new_variant(value)); + } + + g_variant_builder_close(&builder); + + g_dbus_method_invocation_return_value(invocation, + g_variant_builder_end(&builder)); +} + +static void +virtDBusGDBusHandleMethod(GVariant *parameters, + GDBusMethodInvocation *invocation, + const gchar *objectPath, + const gchar *methodName, + virtDBusGDBusMethodData *data) +{ + virtDBusGDBusMethodFunc methodFunc =3D NULL; + GDBusMessage *msg =3D g_dbus_method_invocation_get_message(invocation); + GUnixFDList *inFDs =3D NULL; + GVariant *outArgs =3D NULL; + GUnixFDList *outFDs =3D NULL; + GError *error =3D NULL; + + for (gint i =3D 0; data->methods[i].name; i++) { + if (g_strcmp0(methodName, data->methods[i].name) =3D=3D 0) { + methodFunc =3D data->methods[i].methodFunc; + break; + } + } + + if (!methodFunc) { + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "unknown method '%s'", metho= dName); + return; + } + + inFDs =3D g_dbus_message_get_unix_fd_list(msg); + + methodFunc(parameters, inFDs, objectPath, data->userData, + &outArgs, &outFDs, &error); + + if (error) { + g_dbus_method_invocation_return_gerror(invocation, error); + return; + } + + g_return_if_fail(outArgs || !outFDs); + + g_dbus_method_invocation_return_value_with_unix_fd_list(invocation, + outArgs, + outFDs); +} + +static void +virtDBusGDBusHandleMethodCall(GDBusConnection *connection G_GNUC_UNUSED, + const gchar *sender G_GNUC_UNUSED, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *methodName, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer userData) +{ + virtDBusGDBusMethodData *data =3D userData; + + if (g_strcmp0(interfaceName, "org.freedesktop.DBus.Properties") =3D=3D= 0) { + if (g_strcmp0(methodName, "Get") =3D=3D 0) { + virtDBusGDBusHandlePropertyGet(parameters, invocation, + objectPath, data); + } else if (g_strcmp0(methodName, "Set") =3D=3D 0) { + virtDBusGDBusHandlePropertySet(parameters, invocation, + objectPath, data); + } else if (g_strcmp0(methodName, "GetAll") =3D=3D 0) { + virtDBusGDBusHandlePropertyGetAll(invocation, objectPath, data= ); + } else { + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_MET= HOD, + "unknown method '%s'", m= ethodName); + } + } else { + virtDBusGDBusHandleMethod(parameters, invocation, objectPath, + methodName, data); + } +} + +static const GDBusInterfaceVTable virtDBusGDBusVtable =3D { + virtDBusGDBusHandleMethodCall, + NULL, + NULL, + { NULL } +}; + +/** + * virtDBusGDBusRegisterObject: + * @bus: GDBus connection + * @objectPath: object path + * @interface: interface info of the object + * @methods: table of method handlers + * @properties: table of property handlers + * @userData: data that are passed to method and property handlers + * + * Registers a new D-Bus object that we would like to handle. + */ +void +virtDBusGDBusRegisterObject(GDBusConnection *bus, + gchar const *objectPath, + GDBusInterfaceInfo *interface, + virtDBusGDBusMethodTable *methods, + virtDBusGDBusPropertyTable *properties, + gpointer userData) +{ + virtDBusGDBusMethodData *data =3D g_new0(virtDBusGDBusMethodData, 1); + + data->methods =3D methods; + data->properties =3D properties; + data->userData =3D userData; + + g_dbus_connection_register_object(bus, + objectPath, + interface, + &virtDBusGDBusVtable, + data, g_free, + NULL); +} + +static gchar ** +virtDBusGDBusEnumerate(GDBusConnection *connection G_GNUC_UNUSED, + const gchar *sender G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData) +{ + virtDBusGDBusSubtreeData *data =3D userData; + + if (data->enumerate) + return data->enumerate(data->methodData->userData); + + return NULL; +} + +static GDBusInterfaceInfo ** +virtDBusGDBusIntrospect(GDBusConnection *bus G_GNUC_UNUSED, + const gchar *sender G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + const gchar *node G_GNUC_UNUSED, + gpointer userData) +{ + virtDBusGDBusSubtreeData *data =3D userData; + GDBusInterfaceInfo **ret =3D g_new0(GDBusInterfaceInfo *, 2); + + ret[0] =3D g_dbus_interface_info_ref(data->interface); + + return ret; +} + +static const GDBusInterfaceVTable * +virtDBusGDBusDispatch(GDBusConnection *bus G_GNUC_UNUSED, + const gchar *sender G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + const gchar *interfaceName G_GNUC_UNUSED, + const gchar *node G_GNUC_UNUSED, + gpointer *outUserData, + gpointer userData) +{ + virtDBusGDBusSubtreeData *data =3D userData; + + *outUserData =3D data->methodData; + return &virtDBusGDBusVtable; +} + +static const GDBusSubtreeVTable virtDBusGDBusSubreeVtable =3D { + virtDBusGDBusEnumerate, + virtDBusGDBusIntrospect, + virtDBusGDBusDispatch, + { NULL } +}; + +static void +virtDBusGDBusSubtreeDataFree(gpointer opaque) +{ + virtDBusGDBusSubtreeData *data =3D opaque; + g_free(data->methodData); + g_free(data); +} + +/** + * virtDBusGDBusRegisterSubtree: + * @bus: GDBus connection + * @objectPath: object prefix path + * @interface: interface info of the object + * @methods: table of method handlers + * @properties: table of property handlers + * @userData: data that are passed to method and property handlers + * + * Registers a new D-Bus object prefix that we would like to handle. + */ +void +virtDBusGDBusRegisterSubtree(GDBusConnection *bus, + gchar const *objectPath, + GDBusInterfaceInfo *interface, + virtDBusGDBusEnumerateFunc enumerate, + virtDBusGDBusMethodTable *methods, + virtDBusGDBusPropertyTable *properties, + gpointer userData) +{ + virtDBusGDBusSubtreeData *data =3D g_new0(virtDBusGDBusSubtreeData, 1); + + data->methodData =3D g_new0(virtDBusGDBusMethodData, 1); + + data->interface =3D interface; + data->enumerate =3D enumerate; + data->methodData->methods =3D methods; + data->methodData->properties =3D properties; + data->methodData->userData =3D userData; + + g_dbus_connection_register_subtree(bus, + objectPath, + &virtDBusGDBusSubreeVtable, + G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UN= ENUMERATED_NODES, + data, + virtDBusGDBusSubtreeDataFree, + NULL); +} diff --git a/src/gdbus.h b/src/gdbus.h new file mode 100644 index 0000000..6c1a8a3 --- /dev/null +++ b/src/gdbus.h @@ -0,0 +1,108 @@ +#pragma once + +#include + +/** + * virtDBusGDBusMethodFunc: + * @inArgs: input arguments of the method call + * @inFDs: list of input file descriptors + * @objectPath: the object path the method was called on + * @userData: user data passed when registering new object or subtree + * @outArgs: return location of output arguments + * @outFDs: return location of output file descriptors + * @error: return location for error + * + * Handles D-Bus method call. In case of error the handler has + * to set an @error. + */ +typedef void +(*virtDBusGDBusMethodFunc)(GVariant *inArgs, + GUnixFDList *inFDs, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs, + GError **error); + +/** + * virtDBusGDBusPropertyGetFunc: + * @objectPath: the object path the method was called on + * @userData: user data passed when registering new object or subtree + * @value: return location for property value + * @error: return location for error + * + * Handles D-Bus Get action on a property. In case of error the handler + * has to set an @error, otherwise @value has to be set. + */ +typedef void +(*virtDBusGDBusPropertyGetFunc)(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error); + +/** + * virtDBusGDBusPropertySetFunc: + * @objectPath: the object path the method was called on + * @value: new value that should be set to the property + * @userData: user data passed when registering new object or subtree + * @error: return location for error + * + * Handles D-Bus Set action on a property. In case of error the handler + * has to set an @error. + */ +typedef void +(*virtDBusGDBusPropertySetFunc)(GVariant *value, + const gchar *objectPath, + gpointer userData, + GError **error); + +/** + * virtDBusGDBusEnumerateFunc: + * @userData: user data passed when registering new subtree + * + * Handles D-Bus introspection for subtree of objects. + * + * Returns a list of objects or NULL. + */ +typedef gchar ** +(*virtDBusGDBusEnumerateFunc)(gpointer userData); + +struct _virtDBusGDBusMethodTable { + const gchar *name; + virtDBusGDBusMethodFunc methodFunc; +}; +typedef struct _virtDBusGDBusMethodTable virtDBusGDBusMethodTable; + +struct _virtDBusGDBusPropertyTable { + const gchar *name; + virtDBusGDBusPropertyGetFunc getFunc; + virtDBusGDBusPropertySetFunc setFunc; +}; +typedef struct _virtDBusGDBusPropertyTable virtDBusGDBusPropertyTable; + +typedef guint virtDBusGDBusSource; +typedef guint virtDBusGDBusOwner; + +GDBusInterfaceInfo * +virtDBusGDBusLoadIntrospectData(gchar const *interface, + GError **error); + +void +virtDBusGDBusRegisterObject(GDBusConnection *bus, + gchar const *objectPath, + GDBusInterfaceInfo *interface, + virtDBusGDBusMethodTable *methods, + virtDBusGDBusPropertyTable *properties, + gpointer userData); + +void +virtDBusGDBusRegisterSubtree(GDBusConnection *bus, + gchar const *objectPath, + GDBusInterfaceInfo *interface, + virtDBusGDBusEnumerateFunc enumerate, + virtDBusGDBusMethodTable *methods, + virtDBusGDBusPropertyTable *properties, + gpointer userData); + +G_DEFINE_AUTO_CLEANUP_FREE_FUNC(virtDBusGDBusSource, g_source_remove, 0); +G_DEFINE_AUTO_CLEANUP_FREE_FUNC(virtDBusGDBusOwner, g_bus_unown_name, 0); diff --git a/test/Makefile.am b/test/Makefile.am index 4651d08..d3997f3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -13,4 +13,5 @@ EXTRA_DIST =3D \ travis-run =20 TESTS_ENVIRONMENT =3D \ - abs_top_builddir=3D$(abs_top_builddir) + abs_top_builddir=3D$(abs_top_builddir) \ + VIRT_DBUS_INTERFACES_DIR=3D$(abs_top_srcdir)/data diff --git a/test/travis-run b/test/travis-run index 482b286..28260f4 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 lib= tool python3-gi python3-dbus dbus +apt-get install -y dh-autoreconf pkg-config libvirt-dev libsystemd-dev lib= glib2.0-dev libtool python3-gi python3-dbus dbus =20 # run build and tests as user chown -R buildd:buildd /build --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 23:13:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1521626576168421.5934281869655; Wed, 21 Mar 2018 03:02:56 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6759721BB3; Wed, 21 Mar 2018 10:02:54 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 407C55C89C; Wed, 21 Mar 2018 10:02:54 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 018AF181BA00; Wed, 21 Mar 2018 10:02:54 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w2LA2orM023260 for ; Wed, 21 Mar 2018 06:02:50 -0400 Received: by smtp.corp.redhat.com (Postfix) id 1C727215CDB7; Wed, 21 Mar 2018 10:02:50 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id B7B58215CDC7 for ; Wed, 21 Mar 2018 10:02:49 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 21 Mar 2018 11:02:44 +0100 Message-Id: <84ab5360f22ad670ef719aab9375363f5c9cc61c.1521626292.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-loop: libvir-list@redhat.com Subject: [libvirt] [dbus PATCH v3 2/5] introduce run script to execute libvirt-dbus daemon X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 21 Mar 2018 10:02:55 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The GDBus implementation requires XML files with interface description and libvirt-dbus daemon needs to load them. In order to run the daemon without installing it you can use the run script to configure the environment variable for you. Signed-off-by: Pavel Hrdina Reviewed-by: Daniel P. Berrang=C3=A9 --- .gitignore | 1 + configure.ac | 2 ++ run.in | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 run.in diff --git a/.gitignore b/.gitignore index b468bbd..c6d9754 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ vgcore.* /libvirt-dbus-*.tar.gz /libvirt-dbus.spec /m4/aclocal\.m4 +/run /stamp-h1 =20 /data/session/org.libvirt.service diff --git a/configure.ac b/configure.ac index 0e3bc01..36a4720 100644 --- a/configure.ac +++ b/configure.ac @@ -73,6 +73,8 @@ LIBVIRT_ARG_WITH([SYSTEM_USER], [username to run system i= nstance as], SYSTEM_USER=3D$with_system_user AC_SUBST([SYSTEM_USER]) =20 +AC_CONFIG_FILES([run], + [chmod +x,-w run]) AC_OUTPUT(Makefile data/Makefile src/Makefile diff --git a/run.in b/run.in new file mode 100644 index 0000000..1e48dc8 --- /dev/null +++ b/run.in @@ -0,0 +1,22 @@ +#!/bin/sh +# +# With this script you can run libvirt-dbus daemon without needing to +# install it first. You just have to do for example: +# +# ./run ./src/libvirt-dbus [args ...] +# +# You can also run libvirt-dbus under valgrind like this: +# +# ./run valgrind [valgrind args ...] ./src/libvirt-dbus [args ...] +# +# or under gdb: +# +# ./run gdb --args ./src/libvirt-dbus [args ...] +# + +# Find this script +b=3D@abs_tob_builddir@ + +export VIRT_DBUS_INTERFACES_DIR=3D"$b/data" + +exec "$@" --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 23:13:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1521626579364843.9185218244246; Wed, 21 Mar 2018 03:02:59 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 59740C0587CD; Wed, 21 Mar 2018 10:02:57 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2E6EF5DD84; Wed, 21 Mar 2018 10:02:57 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id C18EF181BA02; Wed, 21 Mar 2018 10:02:56 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w2LA2plA023269 for ; Wed, 21 Mar 2018 06:02:51 -0400 Received: by smtp.corp.redhat.com (Postfix) id E91332166BDA; Wed, 21 Mar 2018 10:02:50 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id 56180215CDC7 for ; Wed, 21 Mar 2018 10:02:50 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 21 Mar 2018 11:02:45 +0100 Message-Id: <507f630a0e42b1eac4a3613355993bc7aeb54a54.1521626292.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-loop: libvir-list@redhat.com Subject: [libvirt] [dbus PATCH v3 3/5] switch from sd-bus to GDBus implementation X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 21 Mar 2018 10:02:57 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This removes all the sd-bus code and uses GDBus instead. Signed-off-by: Pavel Hrdina Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 targ= et policy. =20 The packages required to build libvirt-dbus are =20 - - systemd-211 - libvirt - glib2 =20 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]) =20 GLIB2_REQUIRED=3D2.44.0 LIBVIRT_REQUIRED=3D1.2.8 -SYSTEMD_REQUIRED=3D211 LIBVIRT_GLIB_REQUIRED=3D0.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 =20 LIBVIRT_DBUS_MAJOR_VERSION=3D`echo $VERSION | awk -F. '{print $1}'` @@ -41,7 +39,6 @@ AC_PROG_CC_STDC PKG_CHECK_MODULES(GIO2, gio-unix-2.0 >=3D GLIB2_REQUIRED) PKG_CHECK_MODULES(GLIB2, glib-2.0 >=3D GLIB2_REQUIRED) PKG_CHECK_MODULES(LIBVIRT, libvirt >=3D $LIBVIRT_REQUIRED) -PKG_CHECK_MODULES(SYSTEMD, libsystemd >=3D $SYSTEMD_REQUIRED) PKG_CHECK_MODULES(LIBVIRT_GLIB, libvirt-glib-1.0 >=3D LIBVIRT_GLIB_REQUIRE= D) =20 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 =3D \ polkitdir =3D $(sysconfdir)/polkit-1/rules.d polkit_DATA =3D $(polkit_files:.rules.in=3D.rules) =20 -interfaces_files =3D +interfaces_files =3D \ + org.libvirt.Connect.xml \ + org.libvirt.Domain.xml interfacesdir =3D $(DBUS_INTERFACES_DIR) interfaces_DATA =3D $(interfaces_files) =20 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ =20 %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@ =20 @@ -19,12 +18,10 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-ro= ot-%(%{__id_u} -n) BuildRequires: gcc BuildRequires: glib2-devel >=3D %{glib2_version} BuildRequires: libvirt-devel >=3D %{libvirt_version} -BuildRequires: systemd-devel >=3D %{systemd_version} BuildRequires: libvirt-glib-devel >=3D %{libvirt_glib_version} =20 Requires: glib2 >=3D %{glib2_version} Requires: libvirt-libs >=3D %{libvirt_version} -Requires: systemd-libs >=3D %{systemd_version} Requires: libvirt-glib >=3D %{libvirt_glib_version} =20 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 =20 %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 =3D libvirt-dbus libvirt_dbus_SOURCES =3D $(DAEMON_SOURCES) =20 libvirt_dbus_CFLAGS =3D \ - $(SYSTEMD_CFLAGS) \ $(GIO2_CFLAGS) \ $(GLIB2_CFLAGS) \ $(LIBVIRT_CFLAGS) \ @@ -29,7 +28,6 @@ libvirt_dbus_CFLAGS =3D \ $(NULL) =20 libvirt_dbus_LDFLAGS =3D \ - $(SYSTEMD_LDFLAGS) \ $(GIO2_LDFLAGS) \ $(GLIB2_LDFLAGS) \ $(LIBVIRT_LDFLAGS) \ @@ -39,7 +37,6 @@ libvirt_dbus_LDFLAGS =3D \ $(NULL) =20 libvirt_dbus_LDADD =3D \ - $(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" =20 -#include -#include +#include =20 -static int virtDBusConnectCredType[] =3D { +static gint virtDBusConnectCredType[] =3D { VIR_CRED_AUTHNAME, VIR_CRED_ECHOPROMPT, VIR_CRED_REALM, @@ -15,31 +14,31 @@ static int virtDBusConnectCredType[] =3D { VIR_CRED_EXTERNAL, }; =20 -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 =3D cbdata; - - return virtDBusUtilSetError(error, - "Interactive authentication is not support= ed. " - "Use client configuration file for libvirt= ."); + GError **error =3D 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; } =20 static virConnectAuth virtDBusConnectAuth =3D { virtDBusConnectCredType, - VIRT_N_ELEMENTS(virtDBusConnectCredType), + G_N_ELEMENTS(virtDBusConnectCredType), virtDBusConnectAuthCallback, NULL, }; =20 static void virtDBusConnectClose(virtDBusConnect *connect, - bool deregisterEvents) + gboolean deregisterEvents) { =20 - for (int i =3D 0; i < VIR_DOMAIN_EVENT_ID_LAST; i +=3D 1) { + for (gint i =3D 0; i < VIR_DOMAIN_EVENT_ID_LAST; i +=3D 1) { if (connect->callback_ids[i] >=3D 0) { if (deregisterEvents) { virConnectDomainEventDeregisterAny(connect->connection, @@ -53,130 +52,91 @@ virtDBusConnectClose(virtDBusConnect *connect, connect->connection =3D NULL; } =20 -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); } =20 virtDBusConnectAuth.cbdata =3D error; =20 connect->connection =3D virConnectOpenAuth(connect->uri, &virtDBusConnectAuth, 0); - if (!connect->connection) - return virtDBusUtilSetLastVirtError(error); + if (!connect->connection) { + if (error && !*error) + virtDBusUtilSetLastVirtError(error); + return FALSE; + } =20 virtDBusEventsRegister(connect); =20 - return 0; + return TRUE; } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainListFreep) virDomainPtr *domains =3D NU= LL; - _cleanup_(virtDBusUtilStrvFreep) char **paths =3D NULL; - int n_domains; - int r; - - r =3D virtDBusConnectOpen(connect, error); - if (r < 0) - return r; - - n_domains =3D virConnectListAllDomains(connect->connection, &domains, = 0); - if (n_domains < 0) - return virtDBusUtilSetLastVirtError(error); - - paths =3D calloc(n_domains + 1, sizeof(char *)); - - for (int i =3D 0; i < n_domains; i +=3D 1) - paths[i] =3D virtDBusUtilBusPathForVirDomain(domains[i], - connect->domainPath); + virtDBusConnect *connect =3D userData; + g_autoptr(virDomainPtr) domains =3D NULL; + guint flags; + GVariantBuilder builder; + GVariant *gdomains; =20 - *nodes =3D paths; - paths =3D NULL; + g_variant_get(inArgs, "(u)", &flags); =20 - return 0; -} + if (!virtDBusConnectOpen(connect, error)) + return; =20 -static int -virtDBusConnectListDomains(sd_bus_message *message, - void *userdata, - sd_bus_error *error) -{ - virtDBusConnect *connect =3D userdata; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply =3D NULL; - _cleanup_(virtDBusUtilVirDomainListFreep) virDomainPtr *domains =3D NU= LL; - uint32_t flags; - int r; - - r =3D sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - r =3D virtDBusConnectOpen(connect, error); - if (r < 0) - return r; - - r =3D virConnectListAllDomains(connect->connection, &domains, flags); - if (r < 0) + if (virConnectListAllDomains(connect->connection, &domains, flags) < 0) return virtDBusUtilSetLastVirtError(error); =20 - r =3D sd_bus_message_new_method_return(message, &reply); - if (r < 0) - return r; - - r =3D sd_bus_message_open_container(reply, 'a', "o"); - if (r < 0) - return r; + if (!*domains) + return; =20 - for (int i =3D 0; domains[i] !=3D NULL; i +=3D 1) { - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; + g_variant_builder_init(&builder, G_VARIANT_TYPE("ao")); =20 + for (gint i =3D 0; domains[i]; i++) { + g_autofree gchar *path =3D NULL; path =3D virtDBusUtilBusPathForVirDomain(domains[i], connect->domainPath); =20 - r =3D sd_bus_message_append(reply, "o", path); - if (r < 0) - return r; + g_variant_builder_add(&builder, "o", path); } =20 - r =3D sd_bus_message_close_container(reply); - if (r < 0) - return r; - - return sd_bus_send(NULL, reply, NULL); + gdomains =3D g_variant_builder_end(&builder); + *outArgs =3D g_variant_new_tuple(&gdomains, 1); } =20 -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 =3D userdata; - const char *xml; - uint32_t flags; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; - int r; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + g_autofree gchar *path =3D NULL; + gchar *xml; + guint flags; =20 - r =3D sd_bus_message_read(message, "su", &xml, &flags); - if (r < 0) - return r; + g_variant_get(inArgs, "(&su)", &xml, &flags); =20 - r =3D virtDBusConnectOpen(connect, error); - if (r < 0) - return r; + if (!virtDBusConnectOpen(connect, error)) + return; =20 domain =3D virDomainCreateXML(connect->connection, xml, flags); if (!domain) @@ -184,27 +144,27 @@ virtDBusConnectCreateXML(sd_bus_message *message, =20 path =3D virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); =20 - return sd_bus_reply_method_return(message, "o", path); + *outArgs =3D g_variant_new("(o)", path); } =20 -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 =3D userdata; - const char *xml; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; - int r; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + g_autofree gchar *path =3D NULL; + gchar *xml; =20 - r =3D sd_bus_message_read(message, "s", &xml); - if (r < 0) - return r; + g_variant_get(inArgs, "(&s)", &xml); =20 - r =3D virtDBusConnectOpen(connect, error); - if (r < 0) - return r; + if (!virtDBusConnectOpen(connect, error)) + return; =20 domain =3D virDomainDefineXML(connect->connection, xml); if (!domain) @@ -212,97 +172,77 @@ virtDBusConnectDefineXML(sd_bus_message *message, =20 path =3D virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); =20 - return sd_bus_reply_method_return(message, "o", path); + *outArgs =3D g_variant_new("(o)", path); } =20 -static const sd_bus_vtable virt_connect_vtable[] =3D { - SD_BUS_VTABLE_START(0), +static virtDBusGDBusMethodTable virtDBusConnectMethodTable[] =3D { + { "ListDomains", virtDBusConnectListDomains }, + { "CreateXML", virtDBusConnectCreateXML }, + { "DefineXML", virtDBusConnectDefineXML }, + { NULL, NULL } +}; =20 - 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 =3D NULL; =20 - 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); =20 - SD_BUS_VTABLE_END -}; + g_free(connect->domainPath); + g_free(connect); +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virtDBusConnect, virtDBusConnectFree); =20 -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 =3D NULL; - int r; + g_autoptr(virtDBusConnect) connect =3D NULL; + + if (!interfaceInfo) { + interfaceInfo =3D virtDBusGDBusLoadIntrospectData(VIRT_DBUS_CONNEC= T_INTERFACE, + error); + if (!interfaceInfo) + return; + } =20 - connect =3D calloc(1, sizeof(virtDBusConnect)); - for (int i =3D 0; i < VIR_DOMAIN_EVENT_ID_LAST; i +=3D 1) + connect =3D g_new0(virtDBusConnect, 1); + + for (gint i =3D 0; i < VIR_DOMAIN_EVENT_ID_LAST; i +=3D 1) connect->callback_ids[i] =3D -1; =20 - connect->bus =3D sd_bus_ref(bus); + connect->bus =3D bus; connect->uri =3D uri; connect->connectPath =3D connectPath; =20 - connect->enumerateDomains =3D virtDBusConnectEnumarateDomains; - - r =3D 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); =20 - if ((r =3D virtDBusDomainRegister(connect, bus) < 0)) - return r; + virtDBusDomainRegister(connect, error); + if (error && *error) + return; =20 *connectp =3D connect; connect =3D 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); } =20 void -virtDBusConnectListFree(virtDBusConnect ***connectList) +virtDBusConnectListFree(virtDBusConnect **connectList) { - if (!*connectList) + if (!connectList) return; =20 - for (int i =3D 0; (*connectList)[i]; i +=3D 1) - virtDBusConnectFree((*connectList)[i]); + for (gint i =3D 0; connectList[i]; i +=3D 1) + virtDBusConnectFree(connectList[i]); =20 - 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 @@ =20 #define VIR_ENUM_SENTINELS =20 +#include "util.h" + #include -#include =20 #define VIRT_DBUS_CONNECT_INTERFACE "org.libvirt.Connect" =20 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; =20 - 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; =20 -int +void virtDBusConnectNew(virtDBusConnect **connectp, - sd_bus *bus, - const char *uri, - const char *connectPath); + GDBusConnection *bus, + const gchar *uri, + const gchar *connectPath, + GError **error); =20 -int +gboolean virtDBusConnectOpen(virtDBusConnect *connect, - sd_bus_error *error); - -virtDBusConnect * -virtDBusConnectFree(virtDBusConnect *connect); - -void -virtDBusConnectFreep(virtDBusConnect **connectp); + GError **error); =20 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" =20 #include -#include =20 static virDomainPtr virtDBusDomainGetVirDomain(virtDBusConnect *connect, - const char *path, - sd_bus_error *error) + const gchar *objectPath, + GError **error) { virDomainPtr domain; =20 if (virtDBusConnectOpen(connect, error) < 0) return NULL; =20 - domain =3D virtDBusUtilVirDomainFromBusPath(connect->connection, path, + domain =3D virtDBusUtilVirDomainFromBusPath(connect->connection, + objectPath, connect->domainPath); - if (domain =3D=3D NULL) { - sd_bus_error_setf(error, - SD_BUS_ERROR_UNKNOWN_OBJECT, - "Unknown object '%s'.", path); + if (!domain) { + virtDBusUtilSetLastVirtError(error); return NULL; } =20 return domain; } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - const char *name =3D ""; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + const gchar *name; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 name =3D virDomainGetName(domain); - if (name =3D=3D NULL) - return sd_bus_message_append(reply, "s", ""); + if (!name) + return virtDBusUtilSetLastVirtError(error); =20 - return sd_bus_message_append(reply, "s", name); + *value =3D g_variant_new("s", name); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - char uuid[VIR_UUID_STRING_BUFLEN] =3D ""; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + gchar uuid[VIR_UUID_STRING_BUFLEN] =3D ""; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - virDomainGetUUIDString(domain, uuid); + if (virDomainGetUUIDString(domain, uuid) < 0) + return virtDBusUtilSetLastVirtError(error); =20 - return sd_bus_message_append(reply, "s", uuid); + *value =3D g_variant_new("s", uuid); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + guint id; + + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + id =3D virDomainGetID(domain); + if (id =3D=3D (guint)-1) + id =3D 0; =20 - return sd_bus_message_append(reply, "u", virDomainGetID(domain)); + *value =3D g_variant_new("u", id); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + gint vcpus; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - return sd_bus_message_append(reply, "u", virDomainGetVcpusFlags(domain= , VIR_DOMAIN_VCPU_CURRENT)); + vcpus =3D virDomainGetVcpusFlags(domain, VIR_DOMAIN_VCPU_CURRENT); + if (vcpus < 0) + return virtDBusUtilSetLastVirtError(error); + + *value =3D g_variant_new("u", vcpus); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - _cleanup_(virtDBusUtilFreep) char *os_type =3D NULL; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + g_autofree gchar *osType =3D NULL; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - os_type =3D virDomainGetOSType(domain); - if (os_type =3D=3D NULL) - return sd_bus_message_append(reply, "s", ""); + osType =3D virDomainGetOSType(domain); + if (!osType) + return virtDBusUtilSetLastVirtError(error); =20 - return sd_bus_message_append(reply, "s", os_type); + *value =3D g_variant_new("s", osType); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int active; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + gint active; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 active =3D virDomainIsActive(domain); if (active < 0) - return sd_bus_message_append(reply, "b", 0); + return virtDBusUtilSetLastVirtError(error); =20 - return sd_bus_message_append(reply, "b", active); + *value =3D g_variant_new("b", !!active); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int persistent; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + gint persistent; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 persistent =3D virDomainIsPersistent(domain); if (persistent < 0) - return sd_bus_message_append(reply, "b", 0); + return virtDBusUtilSetLastVirtError(error); =20 - return sd_bus_message_append(reply, "b", persistent); + *value =3D g_variant_new("b", !!persistent); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int state =3D 0; - const char *string; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + gint state =3D 0; + const gchar *string; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - virDomainGetState(domain, &state, NULL, 0); + if (virDomainGetState(domain, &state, NULL, 0) < 0) + return virtDBusUtilSetLastVirtError(error); =20 switch (state) { case VIR_DOMAIN_NOSTATE: @@ -232,88 +216,80 @@ virtDBusDomainGetState(sd_bus *bus VIRT_ATTR_UNUSED, break; } =20 - return sd_bus_message_append(reply, "s", string); + *value =3D g_variant_new("s", string); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int autostart =3D 0; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + gint autostart =3D 0; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - virDomainGetAutostart(domain, &autostart); + if (virDomainGetAutostart(domain, &autostart) < 0) + return virtDBusUtilSetLastVirtError(error); =20 - return sd_bus_message_append(reply, "b", autostart); + *value =3D g_variant_new("b", !!autostart); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - _cleanup_(virtDBusUtilFreep) char *description =3D NULL; - uint32_t flags; - int r; - - r =3D sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; - - description =3D virDomainGetXMLDesc(domain, flags); - if (!description) + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + g_autofree gchar *xml =3D NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); + + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + xml =3D virDomainGetXMLDesc(domain, flags); + if (!xml) return virtDBusUtilSetLastVirtError(error); =20 - return sd_bus_reply_method_return(message, "s", description); + *outArgs =3D g_variant_new("(s)", xml); } =20 -static void -virtDBusDomainStatsRecordListFreep(virDomainStatsRecordPtr **statsp) -{ - if (*statsp) - virDomainStatsRecordListFree(*statsp); -} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainStatsRecordPtr, virDomainStatsRecor= dListFree); =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; virDomainPtr domains[2]; - _cleanup_(virtDBusDomainStatsRecordListFreep) virDomainStatsRecordPtr = *records =3D NULL; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply =3D NULL; - uint32_t flags, stats; - int r; + g_autoptr(virDomainStatsRecordPtr) records =3D NULL; + guint stats; + guint flags; + GVariant *grecords; =20 - r =3D sd_bus_message_read(message, "uu", &stats, &flags); - if (r < 0) - return r; + g_variant_get(inArgs, "(uu)", &stats, &flags); =20 - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 domains[0] =3D domain; domains[1] =3D NULL; @@ -321,243 +297,213 @@ virtDBusDomainGetStats(sd_bus_message *message, if (virDomainListGetStats(domains, stats, &records, flags) !=3D 1) return virtDBusUtilSetLastVirtError(error); =20 - r =3D sd_bus_message_new_method_return(message, &reply); - if (r < 0) - return r; - - r =3D virtDBusUtilMessageAppendTypedParameters(reply, records[0]->para= ms, records[0]->nparams); - if (r < 0) - return r; + grecords =3D virtDBusUtilTypedParamsToGVariant(records[0]->params, + records[0]->nparams); =20 - return sd_bus_send(NULL, reply, NULL); + *outArgs =3D g_variant_new_tuple(&grecords, 1); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int r; - - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; - - r =3D virDomainShutdown(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; =20 - return sd_bus_reply_method_return(message, ""); + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + if (virDomainShutdown(domain) < 0) + virtDBusUtilSetLastVirtError(error); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int r; - - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; - - r =3D virDomainDestroy(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - return sd_bus_reply_method_return(message, ""); + if (virDomainDestroy(domain) < 0) + virtDBusUtilSetLastVirtError(error); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - uint32_t flags; - int r; - - r =3D sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; - - r =3D virDomainReboot(domain, flags); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); =20 - return sd_bus_reply_method_return(message, ""); + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + if (virDomainReboot(domain, flags) < 0) + virtDBusUtilSetLastVirtError(error); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - uint32_t flags; - int r; - - r =3D sd_bus_message_read(message, "u", &flags); - if (r < 0) - return r; - - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; - - r =3D virDomainReset(domain, flags); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); + + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - return sd_bus_reply_method_return(message, ""); + if (virDomainReset(domain, flags) < 0) + virtDBusUtilSetLastVirtError(error); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int r; - - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; - - r =3D virDomainCreate(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; =20 - return sd_bus_reply_method_return(message, ""); + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; + + if (virDomainCreate(domain) < 0) + virtDBusUtilSetLastVirtError(error); } =20 -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 =3D userdata; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int r; - - domain =3D virtDBusDomainGetVirDomain(connect, - sd_bus_message_get_path(message), - error); - if (domain =3D=3D NULL) - return -1; - - r =3D virDomainUndefine(domain); - if (r < 0) - return virtDBusUtilSetLastVirtError(error); + virtDBusConnect *connect =3D userData; + g_autoptr(virDomain) domain =3D NULL; + + domain =3D virtDBusDomainGetVirDomain(connect, objectPath, error); + if (!domain) + return; =20 - return sd_bus_reply_method_return(message, ""); + if (virDomainUndefine(domain) < 0) + virtDBusUtilSetLastVirtError(error); } =20 -static const sd_bus_vtable virt_domain_vtable[] =3D { - 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_BU= S_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Shutdown", "", "", virtDBusDomainShutdown, SD_BUS_VTABL= E_UNPRIVILEGED), - SD_BUS_METHOD("Destroy", "", "", virtDBusDomainDestroy, SD_BUS_VTABLE_= UNPRIVILEGED), - SD_BUS_METHOD("Reboot", "u", "", virtDBusDomainReboot, SD_BUS_VTABLE_U= NPRIVILEGED), - SD_BUS_METHOD("Reset", "u", "", virtDBusDomainReset, SD_BUS_VTABLE_UNP= RIVILEGED), - SD_BUS_METHOD("Create", "", "", virtDBusDomainCreate, SD_BUS_VTABLE_UN= PRIVILEGED), - SD_BUS_METHOD("Undefine", "", "", virtDBusDomainUndefine, SD_BUS_VTABL= E_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[] =3D { + { "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[] =3D { + { "GetXMLDesc", virtDBusDomainGetXMLDesc }, + { "GetStats", virtDBusDomainGetStats }, + { "Shutdown", virtDBusDomainShutdown }, + { "Destroy", virtDBusDomainDestroy }, + { "Reboot", virtDBusDomainReboot }, + { "Reset", virtDBusDomainReset }, + { "Create", virtDBusDomainCreate }, + { "Undefine", virtDBusDomainUndefine }, + { NULL, NULL } }; =20 -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 =3D userdata; - _cleanup_(virtDBusUtilFreep) char *name =3D NULL; - _cleanup_(virtDBusUtilVirDomainFreep) virDomainPtr domain =3D NULL; - int r; + virtDBusConnect *connect =3D userData; + g_autoptr(virDomainPtr) domains =3D NULL; + gint num =3D 0; + gchar **ret =3D NULL; =20 - r =3D sd_bus_path_decode(path, connect->domainPath, &name); - if (r < 0) - return r; + if (!virtDBusConnectOpen(connect, NULL)) + return NULL; =20 - if (*name =3D=3D '\0') - return 0; + num =3D virConnectListAllDomains(connect->connection, &domains, 0); + if (num < 0) + return NULL; =20 - domain =3D virtDBusDomainGetVirDomain(connect, path, error); - if (!domain) - return 0; + if (num =3D=3D 0) + return NULL; + + ret =3D g_new0(gchar *, num + 1); =20 - /* - * 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 =3D connect; + for (gint i =3D 0; i < num; i++) { + ret[i] =3D virtDBusUtilBusPathForVirDomain(domains[i], + connect->domainPath); + } =20 - return 1; + return ret; } =20 -int +static GDBusInterfaceInfo *interfaceInfo =3D NULL; + +void virtDBusDomainRegister(virtDBusConnect *connect, - sd_bus *bus) + GError **error) { - int r; - - r =3D asprintf(&connect->domainPath, "%s/domain", connect->connectPath= ); - if (r < 0) - return r; - - r =3D 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 =3D g_strdup_printf("%s/domain", connect->connectP= ath); + + if (!interfaceInfo) { + interfaceInfo =3D 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 @@ =20 #include "connect.h" =20 -#include - #define VIRT_DBUS_DOMAIN_INTERFACE "org.libvirt.Domain" =20 -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" =20 -#include #include -#include =20 -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 =3D opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message =3D NULL; - const char *signal =3D NULL; - const char *name; - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; - int r; + const gchar *signal =3D NULL; + const gchar *name; + g_autofree gchar *path =3D NULL; =20 switch (event) { case VIR_DOMAIN_EVENT_DEFINED: @@ -52,103 +48,77 @@ virtDBusEventsDomainLifecycle(virConnectPtr connection= VIRT_ATTR_UNUSED, return 0; } =20 - r =3D sd_bus_message_new_signal(connect->bus, - &message, - connect->connectPath, - VIRT_DBUS_CONNECT_INTERFACE, - signal); - if (r < 0) - return r; - name =3D virDomainGetName(domain); path =3D virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); =20 - r =3D 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); =20 - return sd_bus_send(connect->bus, message, NULL); + return 0; } =20 -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 =3D opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message =3D NULL; - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; - int r; + g_autofree gchar *path =3D NULL; =20 path =3D virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); =20 - r =3D 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); =20 - r =3D sd_bus_message_append(message, "s", device); - if (r < 0) - return r; - - return sd_bus_send(connect->bus, message, NULL); + return 0; } =20 -static int -virtDBusEventsDomainDeviceRemoved(virConnectPtr connection VIRT_ATTR_UNUSE= D, +static gint +virtDBusEventsDomainDeviceRemoved(virConnectPtr connection G_GNUC_UNUSED, virDomainPtr domain, - const char *device, - void *opaque) + const gchar *device, + gpointer opaque) { virtDBusConnect *connect =3D opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message =3D NULL; - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; - int r; + g_autofree gchar *path =3D NULL; =20 path =3D virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); =20 - r =3D 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 =3D sd_bus_message_append(message, "s", device); - if (r < 0) - return r; + "DeviceRemoved", + g_variant_new("(s)", device), + NULL); =20 - return sd_bus_send(connect->bus, message, NULL); + return 0; } =20 -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 =3D opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message =3D NULL; - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; - const char *reasonstr; - int r; + g_autofree gchar *path =3D NULL; + const gchar *reasonstr; =20 path =3D virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); =20 - r =3D 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 =3D "open"; @@ -161,38 +131,32 @@ virtDBusEventsDomainTrayChange(virConnectPtr connecti= on VIRT_ATTR_UNUSED, break; } =20 - r =3D 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); =20 - return sd_bus_send(connect->bus, message, NULL); + return 0; } =20 -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 =3D opaque; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *message =3D NULL; - _cleanup_(virtDBusUtilFreep) char *path =3D NULL; - const char *reasonstr; - int r; + g_autofree gchar *path =3D NULL; + const gchar *reasonstr; =20 path =3D virtDBusUtilBusPathForVirDomain(domain, connect->domainPath); =20 - r =3D 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 =3D "missing-on-start"; @@ -205,19 +169,24 @@ virtDBusEventsDomainDiskChange(virConnectPtr connecti= on VIRT_ATTR_UNUSED, break; } =20 - r =3D sd_bus_message_append(message, "ssss", old_src_path, new_src_pat= h, 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, reas= onstr), + NULL); =20 - return sd_bus_send(connect->bus, message, NULL); + return 0; } =20 static void virtDBusEventsRegisterEvent(virtDBusConnect *connect, - int id, + gint id, virConnectDomainEventGenericCallback callback) { - assert(connect->callback_ids[id] =3D=3D -1); + g_assert(connect->callback_ids[id] =3D=3D -1); =20 connect->callback_ids[id] =3D 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" =20 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int loop_status; - -static int -virtDBusGetLibvirtEvents(sd_bus *bus) -{ - int events; - int virt_events =3D 0; - - events =3D sd_bus_get_events(bus); - - if (events & POLLIN) - virt_events |=3D VIR_EVENT_HANDLE_READABLE; - - if (events & POLLOUT) - virt_events |=3D VIR_EVENT_HANDLE_WRITABLE; - - return virt_events; -} +#include +#include =20 -static int -virtDBusProcessEvents(sd_bus *bus) -{ - for (;;) { - int r; - - r =3D sd_bus_process(bus, NULL); - if (r < 0) - return r; - - if (r =3D=3D 0) - break; - } - - return 0; -} - -static void -virtDBusVirEventRemoveHandlep(int *watchp) -{ - if (*watchp >=3D 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 =3D -ECANCELED; -} - -static void -virtDBusHandleBusEvent(int watch, - int fd VIRT_ATTR_UNUSED, - int events VIRT_ATTR_UNUSED, - void *opaque) -{ - sd_bus *bus =3D opaque; - - loop_status =3D virtDBusProcessEvents(bus); - - if (loop_status < 0) - return; - - virEventUpdateHandle(watch, virtDBusGetLibvirtEvents(bus)); -} +struct _virtDBusDriver { + const gchar *uri; + const gchar *object; +}; +typedef struct _virtDBusDriver virtDBusDriver; =20 -struct virtDBusDriver { - const char *uri; - const char *object; +struct _virtDBusRegisterData { + virtDBusConnect **connectList; + const virtDBusDriver *drivers; + gsize ndrivers; }; +typedef struct _virtDBusRegisterData virtDBusRegisterData; =20 -static const struct virtDBusDriver sessionDrivers[] =3D { +static const virtDBusDriver sessionDrivers[] =3D { { "qemu:///session", "/org/libvirt/QEMU" }, { "test:///default", "/org/libvirt/Test" }, { "uml:///session", "/org/libvirt/UML" }, @@ -96,7 +27,7 @@ static const struct virtDBusDriver sessionDrivers[] =3D { { "vmwarews:///session", "/org/libvirt/VMwareWS" }, }; =20 -static const struct virtDBusDriver systemDrivers[] =3D { +static const virtDBusDriver systemDrivers[] =3D { { "bhyve:///system", "/org/libvirt/BHyve" }, { "lxc:///", "/org/libvirt/LXC" }, { "openvz:///system", "/org/libvirt/OpenVZ" }, @@ -108,131 +39,133 @@ static const struct virtDBusDriver systemDrivers[] = =3D { { "xen:///", "/org/libvirt/Xen" }, }; =20 -int -main(int argc, char *argv[]) +static gboolean +virtDBusHandleSignal(gpointer data) { - enum { - ARG_SYSTEM =3D 255, - ARG_SESSION - }; - - static const struct option options[] =3D { - { "help", no_argument, NULL, 'h' }, - { "system", no_argument, NULL, ARG_SYSTEM }, - { "session", no_argument, NULL, ARG_SESSION }, - {} - }; - - bool system_bus; - const struct virtDBusDriver *drivers =3D NULL; - int ndrivers =3D 0; - - _cleanup_(virtDBusConnectListFree) virtDBusConnect **connect =3D NULL; - _cleanup_(sd_bus_unrefp) sd_bus *bus =3D NULL; - _cleanup_(virtDBusUtilClosep) int signal_fd =3D -1; - _cleanup_(virtDBusVirEventRemoveHandlep) int bus_watch =3D -1; - _cleanup_(virtDBusVirEventRemoveHandlep) int signal_watch =3D -1; - sigset_t mask; - int c; - int r; - - if (geteuid() =3D=3D 0) { - system_bus =3D true; - } else { - system_bus =3D false; - } + g_main_loop_quit(data); + return TRUE; +} =20 - while ((c =3D getopt_long(argc, argv, "hc:", options, NULL)) >=3D 0) { - switch (c) { - case 'h': - printf("Usage: %s [OPTIONS]\n", program_invocation_short_n= ame); - printf("\n"); - printf("Provide a D-Bus interface to a libvirtd.\n"); - printf("\n"); - printf(" -h, --help Display this help text and exi= t\n"); - printf(" --session Connect to the session bus\n"); - printf(" --system Connect to the system bus\n"); - return 0; - - case ARG_SYSTEM: - system_bus =3D true; - break; - - case ARG_SESSION: - system_bus =3D false; - break; - - default: - return EXIT_FAILURE; +static void +virtDBusAcquired(GDBusConnection *connection, + const gchar *name G_GNUC_UNUSED, + gpointer opaque) +{ + virtDBusRegisterData *data =3D opaque; + GError *error =3D NULL; + + for (gsize i =3D 0; i < data->ndrivers; i +=3D 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); } } =20 - 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, virtDBusRegisterDat= aFree); + +int +main(gint argc, gchar *argv[]) +{ + static gboolean systemOpt =3D FALSE; + static gboolean sessionOpt =3D FALSE; + GBusType busType; + g_auto(virtDBusGDBusSource) sigintSource =3D 0; + g_auto(virtDBusGDBusSource) sigtermSource =3D 0; + g_auto(virtDBusGDBusOwner) busOwner =3D 0; + g_autoptr(GOptionContext) context =3D NULL; + g_autoptr(GError) error =3D NULL; + g_autoptr(GMainLoop) loop =3D NULL; + g_auto(virtDBusRegisterData) data =3D { 0 }; + + static GOptionEntry options[] =3D { + { "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 } + }; =20 - virEventRegisterDefaultImpl(); + context =3D g_option_context_new("Provide a D-Bus interface to a libvi= rtd."); + g_option_context_add_main_entries(context, options, NULL); =20 - r =3D 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); } =20 - r =3D 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); } =20 - if (system_bus) { - drivers =3D systemDrivers; - ndrivers =3D VIRT_N_ELEMENTS(systemDrivers); + if (sessionOpt) { + busType =3D G_BUS_TYPE_SESSION; + } else if (systemOpt) { + busType =3D G_BUS_TYPE_SYSTEM; } else { - drivers =3D sessionDrivers; - ndrivers =3D VIRT_N_ELEMENTS(sessionDrivers); + if (geteuid() =3D=3D 0) { + busType =3D G_BUS_TYPE_SYSTEM; + } else { + busType =3D G_BUS_TYPE_SESSION; + } } =20 - connect =3D calloc(ndrivers + 1, sizeof(virtDBusConnect *)); - - for (int i =3D 0; i < ndrivers; i +=3D 1) { - r =3D 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 =3D=3D G_BUS_TYPE_SYSTEM) { + data.drivers =3D systemDrivers; + data.ndrivers =3D G_N_ELEMENTS(systemDrivers); + } else { + data.drivers =3D sessionDrivers; + data.ndrivers =3D G_N_ELEMENTS(sessionDrivers); } + data.connectList =3D g_new0(virtDBusConnect *, data.ndrivers + 1); =20 - r =3D virtDBusProcessEvents(bus); - if (r < 0) - return EXIT_FAILURE; + loop =3D g_main_loop_new(NULL, FALSE); =20 - bus_watch =3D virEventAddHandle(sd_bus_get_fd(bus), - virtDBusGetLibvirtEvents(bus), - virtDBusHandleBusEvent, - bus, - NULL); + sigtermSource =3D g_unix_signal_add(SIGTERM, + virtDBusHandleSignal, + loop); =20 - signal_fd =3D signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); - signal_watch =3D virEventAddHandle(signal_fd, - VIR_EVENT_HANDLE_READABLE, + sigintSource =3D g_unix_signal_add(SIGINT, virtDBusHandleSignal, - NULL, - NULL); - if (signal_watch < 0) { - fprintf(stderr, "Failed to register signal handler.\n"); - return EXIT_FAILURE; - } + loop); =20 - while (loop_status >=3D 0) - virEventRunDefaultImpl(); + gvir_init(0, NULL); + gvir_event_register(); =20 - if (loop_status < 0 && loop_status !=3D -ECANCELED) { - fprintf(stderr, "Error: %s\n", strerror(-loop_status)); - return EXIT_FAILURE; - } + busOwner =3D g_bus_own_name(busType, "org.libvirt", + G_BUS_NAME_OWNER_FLAGS_NONE, + virtDBusAcquired, + virtDBusNameAcquired, + virtDBusNameLost, + &data, NULL); + + g_main_loop_run(loop); =20 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" =20 #include -#include -#include +#include =20 -int -virtDBusUtilMessageAppendTypedParameters(sd_bus_message *message, - virTypedParameterPtr parameters, - int n_parameters) +static const GDBusErrorEntry virtDBusUtilErrorEntries[] =3D { + { VIRT_DBUS_ERROR_LIBVIRT, "org.libvirt.Error" }, +}; + +G_STATIC_ASSERT(G_N_ELEMENTS(virtDBusUtilErrorEntries) =3D=3D VIRT_DBUS_N_= ERRORS); + +GQuark +virtDBusErrorQuark(void) { - int r; + static volatile gsize quarkVolatile =3D 0; + g_dbus_error_register_error_domain("virt-dbus-error-quark", + &quarkVolatile, + virtDBusUtilErrorEntries, + G_N_ELEMENTS(virtDBusUtilErrorEntri= es)); + return (GQuark) quarkVolatile; +} =20 - r =3D sd_bus_message_open_container(message, 'a', "{sv}"); - if (r < 0) - return r; +GVariant * +virtDBusUtilTypedParamsToGVariant(virTypedParameterPtr params, + gint nparams) +{ + GVariantBuilder builder; =20 - for (int i =3D 0; i < n_parameters; i +=3D 1) { - r =3D sd_bus_message_open_container(message, SD_BUS_TYPE_DICT_ENTR= Y, "sv"); - if (r < 0) - return r; + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); =20 - r =3D sd_bus_message_append(message, "s", parameters[i].field); - if (r < 0) - return r; + for (gint i =3D 0; i < nparams; i++) { + GVariant *value =3D NULL; =20 - switch (parameters[i].type) { + switch (params[i].type) { case VIR_TYPED_PARAM_INT: - r =3D sd_bus_message_append(message, "v", "i", parameters[i].v= alue.i); + value =3D g_variant_new("i", params[i].value.i); break; case VIR_TYPED_PARAM_UINT: - r =3D sd_bus_message_append(message, "v", "u", parameters[i].v= alue.ui); + value =3D g_variant_new("u", params[i].value.ui); break; case VIR_TYPED_PARAM_LLONG: - r =3D sd_bus_message_append(message, "v", "x", parameters[i].v= alue.l); + value =3D g_variant_new("x", params[i].value.l); break; case VIR_TYPED_PARAM_ULLONG: - r =3D sd_bus_message_append(message, "v", "t", parameters[i].v= alue.ul); + value =3D g_variant_new("t", params[i].value.ul); break; case VIR_TYPED_PARAM_DOUBLE: - r =3D sd_bus_message_append(message, "v", "d", parameters[i].v= alue.d); + value =3D g_variant_new("d", params[i].value.d); break; case VIR_TYPED_PARAM_BOOLEAN: - r =3D sd_bus_message_append(message, "v", "b", parameters[i].v= alue.b); + value =3D g_variant_new("b", params[i].value.b); break; case VIR_TYPED_PARAM_STRING: - r =3D sd_bus_message_append(message, "v", "s", parameters[i].v= alue.s); + value =3D g_variant_new("s", params[i].value.s); break; } =20 - if (r < 0) - return r; - - r =3D 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)); } =20 - return sd_bus_message_close_container(message); + return g_variant_builder_end(&builder); } =20 -int -virtDBusUtilSetLastVirtError(sd_bus_error *error) +void +virtDBusUtilSetLastVirtError(GError **error) { virErrorPtr vir_error; =20 vir_error =3D 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_LIBVIR= T, + vir_error->message); + } +} =20 - return sd_bus_error_set(error, VIRT_DBUS_ERROR_INTERFACE, vir_error->m= essage); +static gchar * +virtDBusUtilEncodeUUID(const gchar *uuid) +{ + gchar *ret =3D g_strdup_printf("_%s", uuid); + return g_strdelimit(ret, "-", '_'); } =20 -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 =3D g_strdup(uuid+1); + return g_strdelimit(ret, "_", '-'); } =20 -char * +gchar * virtDBusUtilBusPathForVirDomain(virDomainPtr domain, - const char *domainPath) + const gchar *domainPath) { - char *path =3D NULL; - char uuid[VIR_UUID_STRING_BUFLEN] =3D ""; - + gchar uuid[VIR_UUID_STRING_BUFLEN] =3D ""; + g_autofree gchar *newUuid =3D NULL; virDomainGetUUIDString(domain, uuid); - sd_bus_path_encode(domainPath, uuid, &path); - - return path; + newUuid =3D virtDBusUtilEncodeUUID(uuid); + return g_strdup_printf("%s/%s", domainPath, newUuid); } =20 virDomainPtr virtDBusUtilVirDomainFromBusPath(virConnectPtr connection, - const char *path, - const char *domainPath) + const gchar *path, + const gchar *domainPath) { - _cleanup_(virtDBusUtilFreep) char *name =3D NULL; - int r; + g_autofree gchar *name =3D NULL; + gsize prefixLen =3D strlen(domainPath) + 1; =20 - r =3D sd_bus_path_decode(path, domainPath, &name); - if (r < 0) - return NULL; + name =3D virtDBusUtilDecodeUUID(path+prefixLen); =20 return virDomainLookupByUUIDString(connection, name); } =20 void -virtDBusUtilFreep(void *p) -{ - free(*(void **)p); -} - -void -virtDBusUtilClosep(int *fdp) -{ - if (*fdp >=3D 0) - close(*fdp); -} - -void -virtDBusUtilStrvFreep(void *p) -{ - char **strv =3D *(char ***)p; - - if (strv =3D=3D NULL) - return; - - for (unsigned i =3D 0; strv[i] !=3D NULL; i++) - free(strv[i]); - - free(strv); -} - -void -virtDBusUtilVirDomainFreep(virDomainPtr *domainp) -{ - if (*domainp) - virDomainFree(*domainp); -} - -void -virtDBusUtilVirDomainListFreep(virDomainPtr **domainsp) +virtDBusUtilVirDomainListFree(virDomainPtr *domains) { - virDomainPtr *domains =3D *domainsp; - - if (!domains) - return; - - for (int i =3D 0; domains[i] !=3D NULL; i +=3D 1) + for (gint i =3D 0; domains[i] !=3D NULL; i +=3D 1) virDomainFree(domains[i]); =20 - 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 =20 -#include -#include - -#define VIRT_DBUS_ERROR_INTERFACE "org.libvirt.Error" - -#define _cleanup_(_x) __attribute__((__cleanup__(_x))) +#include "gdbus.h" =20 -#define VIRT_ATTR_UNUSED __attribute__((__unused__)) +#include =20 -#define VIRT_N_ELEMENTS(array) (sizeof(array) / sizeof(*(array))) +#define VIRT_DBUS_ERROR virtDBusErrorQuark() =20 +typedef enum { + VIRT_DBUS_ERROR_LIBVIRT, + VIRT_DBUS_N_ERRORS /*< skip >*/ +} VirtDBusError; =20 -int -virtDBusUtilMessageAppendTypedParameters(sd_bus_message *message, - virTypedParameterPtr parameters, - int n_parameters); +GQuark +virtDBusErrorQuark(void); =20 -int -virtDBusUtilSetLastVirtError(sd_bus_error *error); +GVariant * +virtDBusUtilTypedParamsToGVariant(virTypedParameterPtr params, + gint nparams); =20 -int -virtDBusUtilSetError(sd_bus_error *error, - const char *message); +void +virtDBusUtilSetLastVirtError(GError **error); =20 -char * +gchar * virtDBusUtilBusPathForVirDomain(virDomainPtr domain, - const char *domainPath); + const gchar *domainPath); =20 virDomainPtr virtDBusUtilVirDomainFromBusPath(virConnectPtr connection, - const char *path, - const char *domainPath); + const gchar *path, + const gchar *domainPath); =20 void -virtDBusUtilFreep(void *p); +virtDBusUtilVirDomainListFree(virDomainPtr *domains); =20 -void -virtDBusUtilClosep(int *fdp); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomain, virDomainFree); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainPtr, virtDBusUtilVirDomainListFree); =20 -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 lib= glib2.0-dev libtool python3-gi python3-dbus dbus +apt-get install -y dh-autoreconf pkg-config libvirt-dev libglib2.0-dev lib= tool python3-gi python3-dbus dbus =20 # run build and tests as user chown -R buildd:buildd /build --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 23:13:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1521626582701393.6436802744515; Wed, 21 Mar 2018 03:03:02 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2AB5E5D67A; Wed, 21 Mar 2018 10:03:01 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CEABB7A40B; Wed, 21 Mar 2018 10:03:00 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6DD00180BAD5; Wed, 21 Mar 2018 10:03:00 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w2LA2p1o023270 for ; Wed, 21 Mar 2018 06:02:51 -0400 Received: by smtp.corp.redhat.com (Postfix) id 87A31215CDC7; Wed, 21 Mar 2018 10:02:51 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2E8EA215CDB7 for ; Wed, 21 Mar 2018 10:02:51 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 21 Mar 2018 11:02:46 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-loop: libvir-list@redhat.com Subject: [libvirt] [dbus PATCH v3 4/5] main: introduce thread pool to process D-Bus messages X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 21 Mar 2018 10:03:01 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The default thread count is currently 4 and it is also configurable via --threads/-t paramter for the libvirt-dbus daemon. Signed-off-by: Pavel Hrdina Reviewed-by: Daniel P. Berrang=C3=A9 --- src/connect.c | 4 +++ src/connect.h | 1 + src/gdbus.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++---------= ---- src/gdbus.h | 4 +++ src/main.c | 10 ++++++ 5 files changed, 95 insertions(+), 21 deletions(-) diff --git a/src/connect.c b/src/connect.c index 70af8ac..bf97cd5 100644 --- a/src/connect.c +++ b/src/connect.c @@ -56,6 +56,8 @@ gboolean virtDBusConnectOpen(virtDBusConnect *connect, GError **error) { + g_autoptr(GMutexLocker) lock =3D g_mutex_locker_new(&connect->lock); + if (connect->connection) { if (virConnectIsAlive(connect->connection)) return TRUE; @@ -213,6 +215,8 @@ virtDBusConnectNew(virtDBusConnect **connectp, =20 connect =3D g_new0(virtDBusConnect, 1); =20 + g_mutex_init(&connect->lock); + for (gint i =3D 0; i < VIR_DOMAIN_EVENT_ID_LAST; i +=3D 1) connect->callback_ids[i] =3D -1; =20 diff --git a/src/connect.h b/src/connect.h index bfe2995..9572857 100644 --- a/src/connect.h +++ b/src/connect.h @@ -14,6 +14,7 @@ struct virtDBusConnect { const gchar *connectPath; gchar *domainPath; virConnectPtr connection; + GMutex lock; =20 gint callback_ids[VIR_DOMAIN_EVENT_ID_LAST]; }; diff --git a/src/gdbus.c b/src/gdbus.c index cbfd07d..688dc38 100644 --- a/src/gdbus.c +++ b/src/gdbus.c @@ -16,6 +16,16 @@ struct _virtDBusGDBusSubtreeData { }; typedef struct _virtDBusGDBusSubtreeData virtDBusGDBusSubtreeData; =20 +struct _virtDBusGDBusThreadData { + const gchar *objectPath; + const gchar *interfaceName; + const gchar *methodName; + GVariant *parameters; + GDBusMethodInvocation *invocation; + virtDBusGDBusMethodData *methodData; +}; +typedef struct _virtDBusGDBusThreadData virtDBusGDBusThreadData; + static const gchar *dbusInterfacePrefix =3D NULL; =20 /** @@ -226,6 +236,38 @@ virtDBusGDBusHandleMethod(GVariant *parameters, outFDs); } =20 +static void +virtDBusGDBusMethodCallThread(gpointer threadData, + gpointer userData G_GNUC_UNUSED) +{ + g_autofree virtDBusGDBusThreadData *data =3D threadData; + + if (g_strcmp0(data->interfaceName, "org.freedesktop.DBus.Properties") = =3D=3D 0) { + if (g_strcmp0(data->methodName, "Get") =3D=3D 0) { + virtDBusGDBusHandlePropertyGet(data->parameters, data->invocat= ion, + data->objectPath, data->methodD= ata); + } else if (g_strcmp0(data->methodName, "Set") =3D=3D 0) { + virtDBusGDBusHandlePropertySet(data->parameters, data->invocat= ion, + data->objectPath, data->methodD= ata); + } else if (g_strcmp0(data->methodName, "GetAll") =3D=3D 0) { + virtDBusGDBusHandlePropertyGetAll(data->invocation, data->obje= ctPath, + data->methodData); + } else { + g_dbus_method_invocation_return_error(data->invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_MET= HOD, + "unknown method '%s'", + data->methodName); + } + } else { + virtDBusGDBusHandleMethod(data->parameters, data->invocation, + data->objectPath, data->methodName, + data->methodData); + } +} + +GThreadPool *threadPool; + static void virtDBusGDBusHandleMethodCall(GDBusConnection *connection G_GNUC_UNUSED, const gchar *sender G_GNUC_UNUSED, @@ -236,27 +278,18 @@ virtDBusGDBusHandleMethodCall(GDBusConnection *connec= tion G_GNUC_UNUSED, GDBusMethodInvocation *invocation, gpointer userData) { - virtDBusGDBusMethodData *data =3D userData; - - if (g_strcmp0(interfaceName, "org.freedesktop.DBus.Properties") =3D=3D= 0) { - if (g_strcmp0(methodName, "Get") =3D=3D 0) { - virtDBusGDBusHandlePropertyGet(parameters, invocation, - objectPath, data); - } else if (g_strcmp0(methodName, "Set") =3D=3D 0) { - virtDBusGDBusHandlePropertySet(parameters, invocation, - objectPath, data); - } else if (g_strcmp0(methodName, "GetAll") =3D=3D 0) { - virtDBusGDBusHandlePropertyGetAll(invocation, objectPath, data= ); - } else { - g_dbus_method_invocation_return_error(invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_UNKNOWN_MET= HOD, - "unknown method '%s'", m= ethodName); - } - } else { - virtDBusGDBusHandleMethod(parameters, invocation, objectPath, - methodName, data); - } + virtDBusGDBusThreadData *data =3D g_new0(virtDBusGDBusThreadData, 1); + + g_assert(data); + + data->objectPath =3D objectPath; + data->interfaceName =3D interfaceName; + data->methodName =3D methodName; + data->parameters =3D parameters; + data->invocation =3D invocation; + data->methodData =3D userData; + + g_thread_pool_push(threadPool, data, NULL); } =20 static const GDBusInterfaceVTable virtDBusGDBusVtable =3D { @@ -396,3 +429,25 @@ virtDBusGDBusRegisterSubtree(GDBusConnection *bus, virtDBusGDBusSubtreeDataFree, NULL); } + +/** + * virtDBusGDBusPrepareThreadPool: + * @maxThreads: the number of maximum threads in thread pool + * @error: return location for error or NULL + * + * Initializes thread pool to be used to process D-Bus messages. + * + * Returns TRUE on success, FALSE on error and sets @error. + */ +gboolean +virtDBusGDBusPrepareThreadPool(gint maxThreads, + GError **error) +{ + threadPool =3D g_thread_pool_new(virtDBusGDBusMethodCallThread, + NULL, + maxThreads, + FALSE, + error); + + return !!threadPool; +} diff --git a/src/gdbus.h b/src/gdbus.h index 6c1a8a3..5ab9cd0 100644 --- a/src/gdbus.h +++ b/src/gdbus.h @@ -104,5 +104,9 @@ virtDBusGDBusRegisterSubtree(GDBusConnection *bus, virtDBusGDBusPropertyTable *properties, gpointer userData); =20 +gboolean +virtDBusGDBusPrepareThreadPool(gint maxThreads, + GError **error); + G_DEFINE_AUTO_CLEANUP_FREE_FUNC(virtDBusGDBusSource, g_source_remove, 0); G_DEFINE_AUTO_CLEANUP_FREE_FUNC(virtDBusGDBusOwner, g_bus_unown_name, 0); diff --git a/src/main.c b/src/main.c index bbbec09..7afde4f 100644 --- a/src/main.c +++ b/src/main.c @@ -89,11 +89,14 @@ virtDBusRegisterDataFree(virtDBusRegisterData *data) } G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(virtDBusRegisterData, virtDBusRegisterDat= aFree); =20 +#define VIRT_DBUS_MAX_THREADS 4 + int main(gint argc, gchar *argv[]) { static gboolean systemOpt =3D FALSE; static gboolean sessionOpt =3D FALSE; + static gint maxThreads =3D VIRT_DBUS_MAX_THREADS; GBusType busType; g_auto(virtDBusGDBusSource) sigintSource =3D 0; g_auto(virtDBusGDBusSource) sigtermSource =3D 0; @@ -108,6 +111,8 @@ main(gint argc, gchar *argv[]) "Connect to the system bus", NULL }, { "session", 0, 0, G_OPTION_ARG_NONE, &sessionOpt, "Connect to the session bus", NULL }, + { "threads", 't', 0, G_OPTION_ARG_INT, &maxThreads, + "Configure maximal number of worker threads", "N" }, { NULL } }; =20 @@ -145,6 +150,11 @@ main(gint argc, gchar *argv[]) } data.connectList =3D g_new0(virtDBusConnect *, data.ndrivers + 1); =20 + if (!virtDBusGDBusPrepareThreadPool(maxThreads, &error)) { + g_printerr("%s\n", error->message); + exit(EXIT_FAILURE); + } + loop =3D g_main_loop_new(NULL, FALSE); =20 sigtermSource =3D g_unix_signal_add(SIGTERM, --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 23:13:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1521626586280515.3360347678057; Wed, 21 Mar 2018 03:03:06 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B8AB6883C3; Wed, 21 Mar 2018 10:03:04 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8FA3B413C; Wed, 21 Mar 2018 10:03:04 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 4FA95180BAD9; Wed, 21 Mar 2018 10:03:04 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w2LA2q6j023286 for ; Wed, 21 Mar 2018 06:02:52 -0400 Received: by smtp.corp.redhat.com (Postfix) id 26797215CDB7; Wed, 21 Mar 2018 10:02:52 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id C1B492166BDA for ; Wed, 21 Mar 2018 10:02:51 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Wed, 21 Mar 2018 11:02:47 +0100 Message-Id: <419225a417965e0ddf9b858ae8358cc96e0332b9.1521626292.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-loop: libvir-list@redhat.com Subject: [libvirt] [dbus PATCH v3 5/5] docs: rewrite HACKING and README into markdown format and improve it X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 21 Mar 2018 10:03:05 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Pavel Hrdina Reviewed-by: Daniel P. Berrang=C3=A9 --- HACKING | 199 --------------------------------------------------------= ---- HACKING.md | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile.am | 2 + README | 80 ------------------------ README.md | 72 ++++++++++++++++++++++ 5 files changed, 265 insertions(+), 279 deletions(-) delete mode 100644 HACKING create mode 100644 HACKING.md delete mode 100644 README create mode 100644 README.md diff --git a/HACKING b/HACKING deleted file mode 100644 index 21fb683..0000000 --- a/HACKING +++ /dev/null @@ -1,199 +0,0 @@ - Tips for hacking on libvirt-dbus - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - - -Coding style rules - - - Opening & closing braces for functions should be at start of line - - int - foo(int bar) - { - ... - } - - Not - - int - foo(int bar) { - ... - } - - - - - Opening brace for if/while/for loops should be at the end of line - - if (foo) { - bar; - wizz; - } - - Not - - if (foo) - { - bar; - wizz; - } - - Rationale: putting every if/while/for opening brace on a new line - expands function length too much - - - - - If a brace needs to be used for one clause in an if/else statement, - it should be used for both clauses, even if the other clauses are - only single statements. eg - - if (foo) { - bar; - wizz; - } else { - eek; - } - - Not - - if (foo) { - bar; - wizz; - } else - eek; - - - - - Function parameter attribute annotations should follow the parameter - name, eg - - int - foo(int bar G_GNUC_UNUSED) - { - } - - Not - - int - foo(G_GNUC_UNUSED int bar) - { - } - - Rationale: Adding / removing G_GNUC_UNUSED should not cause the - rest of the line to move around since that obscures diffs. - - - - - There should be no space between function names & open brackets eg - - int - foo(int bar) - { - } - - Not - - int - foo (int bar) - { - } - - - - - To keep lines under 80 characters (where practical), multiple parameters - should be on new lines. Do not attempt to line up parameters vertically - eg - - int - foo(int bar, - unsigned long wizz) - { - } - - Not - - int - foo(int bar, unsigned long wizz) - { - } - - Not - - int - foo(int bar, - unsigned long wizz) - { - } - - Rationale: attempting vertical alignment causes bigger diffs when - modifying code if type names change causing whitespace re-alignment. - - - - Usage of goto should follow one of the following patterns, and - label naming conventions. In particular any exit path jumps should - obay the 'cleanup' vs 'error' label naming - - * Interrupted system calls: - - retry: - err =3D func() - if (err < 0 && errno =3D=3D EINTR) - goto retry; - - Alternate label name: retry_func: - - - * Shared cleanup paths: - - int - foo(int bar) - { - int ret =3D -1; - - - if (something goes wrong) - goto cleanup; - - ret =3D 0; - cleanup: - ...shared cleanup code... - return ret; - } - - - * Separate error exit paths: - - int - foo(int bar) - { - if (something goes wrong) - goto error; - - return 0; - - error: - ...error cleanup code... - return -1; - } - - - * Separate and shared error exit paths: - - int - foo(int bar) - { - int ret =3D -1; - - if (something very bad goes wrong) - goto error; - - if (something goes wrong) - goto cleanup; - - ret =3D 0; - cleanup: - ...shared cleanup code... - return 0; - - error: - ...error cleanup code... - return -1; - } diff --git a/HACKING.md b/HACKING.md new file mode 100644 index 0000000..75aa6d0 --- /dev/null +++ b/HACKING.md @@ -0,0 +1,191 @@ +Tips for hacking on libvirt-dbus +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D + +Here is where to get code: + +``` +$ git clone https://libvirt.org/git/libvirt-dbus.git +``` + +Alternatively you can use one of the mirrors: + +[https://github.com/libvirt/libvirt-dbus](https://github.com/libvirt/libvi= rt-dbus) +[https://gitlab.com/libvirt/libvirt-dbus](https://gitlab.com/libvirt/libvi= rt-dbus) + + +Running from git repository +--------------------------- + + * The first step is to run autoreconf to create configure script: + + ``` + ./autogen.sh + ``` + + Now you can compile libvirt-dbus: + + ``` + make + ``` + + + * Before posting a patch, you should run tests: + + ``` + make check + ``` + + The test tool requires python3 and python3-dbus. + + + * To run libvirt-dbus directly from the build dir without installing it + use the run script: + + ``` + ./run ./src/libvirt-dbus + ``` + + +Coding style rules +------------------ + + * Opening & closing braces for functions should be at start of line: + + ``` + int + foo(int bar) + { + ... + } + ``` + + Not + + ``` + int + foo(int bar) { + ... + } + ``` + + * Opening brace for if/while/for loops should be at the end of line: + + ``` + if (foo) { + bar; + wizz; + } + ``` + + Not + + ``` + if (foo) + { + bar; + wizz; + } + ``` + + Rationale: putting every if/while/for opening brace on a new line + expands function length too much. + + + * If a brace needs to be used for one clause in an if/else statement, + it should be used for both clauses, even if the other clauses are + only single statements. eg: + + ``` + if (foo) { + bar; + wizz; + } else { + eek; + } + ``` + + Not + + ``` + if (foo) { + bar; + wizz; + } else + eek; + ``` + + + * Function parameter attribute annotations should follow the parameter + name, eg: + + ``` + int + foo(int bar G_GNUC_UNUSED) + { + } + ``` + + Not + + ``` + int + foo(G_GNUC_UNUSED int bar) + { + } + ``` + + Rationale: Adding / removing G_GNUC_UNUSED should not cause the + rest of the line to move around since that obscures diffs. + + + * There should be no space between function names & open brackets eg: + + ``` + int + foo(int bar) + { + } + ``` + + Not + + ``` + int + foo (int bar) + { + } + ``` + + + * To keep lines under 80 characters (where practical), multiple paramete= rs + should be on new lines. Do not attempt to line up parameters verticall= y eg: + + ``` + int + foo(int bar, + unsigned long wizz) + { + } + ``` + + Not + + ``` + int + foo(int bar, unsigned long wizz) + { + } + ``` + + Not + + ``` + int + foo(int bar, + unsigned long wizz) + { + } + ``` + + Rationale: attempting vertical alignment causes bigger diffs when + modifying code if type names change causing whitespace re-alignment. diff --git a/Makefile.am b/Makefile.am index d2c3fc5..a890ff1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,6 +7,8 @@ EXTRA_DIST =3D \ $(PACKAGE).spec \ $(PACKAGE).spec.in \ AUTHORS.in \ + HACKING.md \ + README.md \ $(NULL) =20 DISTCLEAN_FILES =3D $(PACKAGE).spec diff --git a/README b/README deleted file mode 100644 index b95b09b..0000000 --- a/README +++ /dev/null @@ -1,80 +0,0 @@ -libvirt-dbus -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -libvirt is a C toolkit to interact with the virtualization capabilities -of recent versions of Linux (and other OSes). It is free software -available under the GNU Lesser General Public License. Virtualization on -the Linux Operating System means the ability to run multiple instances of -Operating Systems concurrently on a single hardware system where the basic -resources are driven by a Linux instance. The library aim at providing -long term stable C API initially for the Xen paravirtualization but -should be able to integrate other virtualization mechanisms if needed. - -libvirt-dbus wraps libvirt to provide a high-level object-oriented API bet= ter -suited for dbus-based applications - -libvirt-dbus is Free Software and licenced under LGPLv2+. - -The latest official releases can be found at: - - ftp://libvirt.org/libvirt/dbus/ - -NB: at this time, libvirt-dbus is *NOT* considered API/ABI stable. Future -releases may still include API/ABI incompatible changes. - -Dependencies / supported platforms -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -The libvirt-dbus projects attempts to be moderately conservative -about updating the minimum required versions of external package -dependencies, to strike a balance between enabling use of new -features while minimizing inconvenience for downstream developers -on distro platforms with specific shipped versions. - -There are roughly two classes of Linux distro - short lifetime -(Fedora, Ubuntu non-LTS, etc) and extended lifetime (RHEL, CentOS, -Debian, Ubuntu LTS). Based on this classification, the libvirt-dbus -project will generally aim to ensure build support for - - - Most recent 2 releases of short lifetime distros - - Most recent major release of extended lifetime distros, - with most recent 2 minor updates - -The project will consider RHEL, Fedora, Debian, Ubuntu LTS, Ubuntu, -OpenSUSE and SUSE (SLES/SLED) distros to be a representative subset -of distros when determining min required versions of external deps -that is reasonable to target. Other distros of similar release vintage -will typically have similar versions to at least one of these distros. -In the case of Debian, the project may at times choose to require use -of an update from the backports repository. - -At any time, it may be possible to build on versions of distros -that are older than those implied by this policy, but the project -will not guarantee this remains the case in future releases. The -min required package versions of external dependencies may be -raised in future releases based on this distro build target policy. - -The packages required to build libvirt-dbus are - - - libvirt - - glib2 - -Patches submissions -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -Patch submissions are welcomed from any interested contributor. Please -send them to the main libvir-list mailing list - - libvir-list@redhat.com - -Questions about usage / deployment can be send to the end users mailing -list - - libvirt-users@redhat.com - -For further information about mailing lists & contacting the developers, -please consult - - http://libvirt.org/contact.html - ---End diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ce265c --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +libvirt-dbus +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Libvirt provides a portable, long term stable C API for managing the +virtualization technologies provided by many operating systems. It +includes support for QEMU, KVM, Xen, LXC, bhyve, Virtuozzo, VMware +vCenter and ESX, VMware Desktop, Hyper-V, VirtualBox and the POWER +Hypervisor. + +libvirt-dbus wraps libvirt API to provide a high-level object-oriented +API better suited for dbus-based applications. + +libvirt-dbus is Free Software and licenced under LGPLv2+. + + * [https://libvirt.org/libvirt-dbus.html](https://libvirt.org/dbus.html) + +The latest official releases can be found at: + + * [https://libvirt.org/sources/dbus/](https://libvirt.org/sources/dbus/) + +NB: at this time, libvirt-dbus is *NOT* considered API/ABI stable. Future +releases may still include API/ABI incompatible changes. + + +Dependencies / supported platforms +---------------------------------- + +The packages required to build libvirt-dbus are + + - libvirt + - libvirt-glib + - glib2 + + +Installation +------------ + +libvirt-dbus uses GNU Autotools build system, so the build & install +process is fairly simple. For example, to install as root user: + +``` +# ./configure --prefix=3D/usr --sysconfigdir=3D/etc --localstatedir=3D/var +# make +# make install +``` + +or to install as unprivileged user: + +``` +$ ./configure --prefix=3D$HOME/usr +$ make +$ make install +``` + + +Patches submissions +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Patch submissions are welcomed from any interested contributor. Please +send them to the main libvir-list mailing list + + * libvir-list@redhat.com + +Questions about usage / deployment can be send to the end users mailing +list + + * libvirt-users@redhat.com + +For further information about mailing lists & contacting the developers, +please consult + +[https://libvirt.org/contact.html](https://libvirt.org/contact.html) --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list