[libvirt] [dbus PATCH 3/9] domain: split domain code into separate file

Pavel Hrdina phrdina at redhat.com
Mon Jul 24 13:38:56 UTC 2017


Instead of having all code only in one file split it logically to have
one file for D-Bus object.

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 src/Makefile.am |   3 +-
 src/domain.c    | 549 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/domain.h    |   9 +
 src/manager.c   | 551 +-------------------------------------------------------
 src/manager.h   |   6 +
 5 files changed, 568 insertions(+), 550 deletions(-)
 create mode 100644 src/domain.c
 create mode 100644 src/domain.h

diff --git a/src/Makefile.am b/src/Makefile.am
index e60f250..f066ed3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,8 @@ AM_CPPFLAGS = \
 DAEMON_SOURCES = \
 	main.c \
 	manager.c manager.h \
-	util.c util.h
+	util.c util.h \
+	domain.c domain.h
 
 EXTRA_DIST = \
 	$(DAEMON_SOURCES)
diff --git a/src/domain.c b/src/domain.c
new file mode 100644
index 0000000..1bda3b8
--- /dev/null
+++ b/src/domain.c
@@ -0,0 +1,549 @@
+#include "domain.h"
+#include "util.h"
+
+static int
+domain_get_name(sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    const char *name = "";
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "s", "");
+
+    name = virDomainGetName(domain);
+    if (name == NULL)
+        return sd_bus_message_append(reply, "s", "");
+
+    return sd_bus_message_append(reply, "s", name);
+}
+
+static int
+domain_get_uuid(sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    char uuid[VIR_UUID_STRING_BUFLEN] = "";
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "s", "");
+
+    virDomainGetUUIDString(domain, uuid);
+
+    return sd_bus_message_append(reply, "s", uuid);
+}
+
+static int
+domain_get_id(sd_bus *bus,
+              const char *path,
+              const char *interface,
+              const char *property,
+              sd_bus_message *reply,
+              void *userdata,
+              sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "u", 0);
+
+    return sd_bus_message_append(reply, "u", virDomainGetID(domain));
+}
+
+static int
+domain_get_vcpus(sd_bus *bus,
+                 const char *path,
+                 const char *interface,
+                 const char *property,
+                 sd_bus_message *reply,
+                 void *userdata,
+                 sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "u", 0);
+
+    return sd_bus_message_append(reply, "u", virDomainGetVcpusFlags(domain, VIR_DOMAIN_VCPU_CURRENT));
+}
+
+static int
+domain_get_os_type(sd_bus *bus,
+                   const char *path,
+                   const char *interface,
+                   const char *property,
+                   sd_bus_message *reply,
+                   void *userdata,
+                   sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    _cleanup_(freep) char *os_type = NULL;
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "s", "");
+
+    os_type = virDomainGetOSType(domain);
+    if (os_type == NULL)
+        return sd_bus_message_append(reply, "s", "");
+
+    return sd_bus_message_append(reply, "s", os_type);
+}
+
+static int
+domain_get_active(sd_bus *bus,
+                  const char *path,
+                  const char *interface,
+                  const char *property,
+                  sd_bus_message *reply,
+                  void *userdata,
+                  sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int active;
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "b", 0);
+
+    active = virDomainIsActive(domain);
+    if (active < 0)
+        return sd_bus_message_append(reply, "b", 0);
+
+    return sd_bus_message_append(reply, "b", active);
+}
+
+static int
+domain_get_persistent(sd_bus *bus,
+                      const char *path,
+                      const char *interface,
+                      const char *property,
+                      sd_bus_message *reply,
+                      void *userdata,
+                      sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int persistent;
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "b", 0);
+
+    persistent = virDomainIsPersistent(domain);
+    if (persistent < 0)
+        return sd_bus_message_append(reply, "b", 0);
+
+    return sd_bus_message_append(reply, "b", persistent);
+}
+
+static int
+domain_get_state(sd_bus *bus,
+                 const char *path,
+                 const char *interface,
+                 const char *property,
+                 sd_bus_message *reply,
+                 void *userdata,
+                 sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int state = 0;
+    const char *string;
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "s", "");
+
+    virDomainGetState(domain, &state, NULL, 0);
+
+    switch (state) {
+        case VIR_DOMAIN_NOSTATE:
+        default:
+            string = "nostate";
+            break;
+        case VIR_DOMAIN_RUNNING:
+            string = "running";
+            break;
+        case VIR_DOMAIN_BLOCKED:
+            string = "blocked";
+            break;
+        case VIR_DOMAIN_PAUSED:
+            string = "paused";
+            break;
+        case VIR_DOMAIN_SHUTDOWN:
+            string = "shutdown";
+            break;
+        case VIR_DOMAIN_SHUTOFF:
+            string = "shutoff";
+            break;
+        case VIR_DOMAIN_CRASHED:
+            string = "crashed";
+            break;
+        case VIR_DOMAIN_PMSUSPENDED:
+            string = "pmsuspended";
+            break;
+    }
+
+    return sd_bus_message_append(reply, "s", string);
+}
+
+static int
+domain_get_autostart(sd_bus *bus,
+                     const char *path,
+                     const char *interface,
+                     const char *property,
+                     sd_bus_message *reply,
+                     void *userdata,
+                     sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int autostart = 0;
+
+    domain = domain_from_bus_path(manager->connection, path);
+    if (domain == NULL)
+        return sd_bus_message_append(reply, "b", 0);
+
+    virDomainGetAutostart(domain, &autostart);
+
+    return sd_bus_message_append(reply, "b", autostart);
+}
+
+static int
+domain_get_xml_desc(sd_bus_message *message,
+                    void *userdata,
+                    sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    _cleanup_(freep) char *description = NULL;
+    uint32_t flags;
+    int r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    r = sd_bus_message_read(message, "u", &flags);
+    if (r < 0)
+        return r;
+
+    description = virDomainGetXMLDesc(domain, flags);
+    if (!description)
+        return bus_error_set_last_virt_error(error);
+
+    return sd_bus_reply_method_return(message, "s", description);
+}
+
+static void
+virDomainStatsRecordListFreep(virDomainStatsRecordPtr **statsp)
+{
+    if (*statsp)
+        virDomainStatsRecordListFree(*statsp);
+}
+
+static int
+domain_get_stats(sd_bus_message *message,
+                 void *userdata,
+                 sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    virDomainPtr domains[2];
+    _cleanup_(virDomainStatsRecordListFreep) virDomainStatsRecordPtr *records = NULL;
+    _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+    uint32_t flags, stats;
+    int r;
+
+    r = sd_bus_message_read(message, "uu", &stats, &flags);
+    if (r < 0)
+        return r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    domains[0] = domain;
+    domains[1] = NULL;
+
+    if (virDomainListGetStats(domains, stats, &records, flags) != 1)
+        return bus_error_set_last_virt_error(error);
+
+    r = sd_bus_message_new_method_return(message, &reply);
+    if (r < 0)
+        return r;
+
+    r = bus_message_append_typed_parameters(reply, records[0]->params, records[0]->nparams);
+    if (r < 0)
+        return r;
+
+    return sd_bus_send(NULL, reply, NULL);
+}
+
+static int
+domain_shutdown(sd_bus_message *message,
+                void *userdata,
+                sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    r = virDomainShutdown(domain);
+    if (r < 0)
+        return bus_error_set_last_virt_error(error);
+
+    return sd_bus_reply_method_return(message, "");
+}
+
+static int
+domain_destroy(sd_bus_message *message,
+               void *userdata,
+               sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    r = virDomainDestroy(domain);
+    if (r < 0)
+        return bus_error_set_last_virt_error(error);
+
+    return sd_bus_reply_method_return(message, "");
+}
+
+static int
+domain_reboot(sd_bus_message *message,
+               void *userdata,
+               sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    uint32_t flags;
+    int r;
+
+    r = sd_bus_message_read(message, "u", &flags);
+    if (r < 0)
+        return r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    r = virDomainReboot(domain, flags);
+    if (r < 0)
+        return bus_error_set_last_virt_error(error);
+
+    return sd_bus_reply_method_return(message, "");
+}
+
+static int
+domain_reset(sd_bus_message *message,
+             void *userdata,
+             sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    uint32_t flags;
+    int r;
+
+    r = sd_bus_message_read(message, "u", &flags);
+    if (r < 0)
+        return r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    r = virDomainReset(domain, flags);
+    if (r < 0)
+        return bus_error_set_last_virt_error(error);
+
+    return sd_bus_reply_method_return(message, "");
+}
+
+static int
+domain_create(sd_bus_message *message,
+              void *userdata,
+              sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    r = virDomainCreate(domain);
+    if (r < 0)
+        return bus_error_set_last_virt_error(error);
+
+    return sd_bus_reply_method_return(message, "");
+}
+
+static int
+domain_undefine(sd_bus_message *message,
+                void *userdata,
+                sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int r;
+
+    domain = domain_from_bus_path(manager->connection,
+                                  sd_bus_message_get_path(message));
+    if (domain == NULL) {
+        return sd_bus_reply_method_errorf(message,
+                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
+                                          "Unknown object '%s'.",
+                                          sd_bus_message_get_path(message));
+    }
+
+    r = virDomainUndefine(domain);
+    if (r < 0)
+        return bus_error_set_last_virt_error(error);
+
+    return sd_bus_reply_method_return(message, "");
+}
+
+static const sd_bus_vtable virt_domain_vtable[] = {
+    SD_BUS_VTABLE_START(0),
+
+    SD_BUS_PROPERTY("Name", "s", domain_get_name, 0, 0),
+    SD_BUS_PROPERTY("UUID", "s", domain_get_uuid, 0, 0),
+    SD_BUS_PROPERTY("Id", "u", domain_get_id, 0, 0),
+    SD_BUS_PROPERTY("Vcpus", "u", domain_get_vcpus, 0, 0),
+    SD_BUS_PROPERTY("OSType", "s", domain_get_os_type, 0, 0),
+    SD_BUS_PROPERTY("Active", "b", domain_get_active, 0, 0),
+    SD_BUS_PROPERTY("Persistent", "b", domain_get_persistent, 0, 0),
+    SD_BUS_PROPERTY("State", "s", domain_get_state, 0, 0),
+    SD_BUS_PROPERTY("Autostart", "b", domain_get_autostart, 0, 0),
+
+    SD_BUS_METHOD("GetXMLDesc", "u", "s", domain_get_xml_desc, SD_BUS_VTABLE_UNPRIVILEGED),
+    SD_BUS_METHOD("GetStats", "uu", "a{sv}", domain_get_stats, SD_BUS_VTABLE_UNPRIVILEGED),
+    SD_BUS_METHOD("Shutdown", "", "", domain_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
+    SD_BUS_METHOD("Destroy", "", "", domain_destroy, SD_BUS_VTABLE_UNPRIVILEGED),
+    SD_BUS_METHOD("Reboot", "u", "", domain_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
+    SD_BUS_METHOD("Reset", "u", "", domain_reset, SD_BUS_VTABLE_UNPRIVILEGED),
+    SD_BUS_METHOD("Create", "", "", domain_create, SD_BUS_VTABLE_UNPRIVILEGED),
+    SD_BUS_METHOD("Undefine", "", "", domain_undefine, SD_BUS_VTABLE_UNPRIVILEGED),
+
+    SD_BUS_SIGNAL("DeviceAdded", "s", 0),
+    SD_BUS_SIGNAL("DeviceRemoved", "s", 0),
+    SD_BUS_SIGNAL("DiskChange", "ssss", 0),
+    SD_BUS_SIGNAL("TrayChange", "ss", 0),
+
+    SD_BUS_VTABLE_END
+};
+
+static int
+lookup_domain(sd_bus *bus,
+              const char *path,
+              const char *interface,
+              void *userdata,
+              void **found,
+              sd_bus_error *error)
+{
+    VirtManager *manager = userdata;
+    _cleanup_(freep) char *name = NULL;
+    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
+    int r;
+
+    r = sd_bus_path_decode(path, "/org/libvirt/domain", &name);
+    if (r < 0)
+        return r;
+
+    if (*name == '\0')
+        return 0;
+
+    domain = virDomainLookupByUUIDString(manager->connection, name);
+    if (!domain)
+        return 0;
+
+    /*
+     * There's no way to unref the pointer we're returning here. So,
+     * return the manager object and look up the domain again in the
+     * domain_* callbacks.
+     */
+    *found = manager;
+
+    return 1;
+}
+
+int
+domain_register(VirtManager *manager,
+                sd_bus *bus)
+{
+    return sd_bus_add_fallback_vtable(bus,
+                                      NULL,
+                                      "/org/libvirt/domain",
+                                      "org.libvirt.Domain",
+                                      virt_domain_vtable,
+                                      lookup_domain,
+                                      manager);
+}
diff --git a/src/domain.h b/src/domain.h
new file mode 100644
index 0000000..3f347e8
--- /dev/null
+++ b/src/domain.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "manager.h"
+
+#include <libvirt/libvirt.h>
+#include <systemd/sd-bus.h>
+
+int domain_register(VirtManager *manager,
+                    sd_bus *bus);
diff --git a/src/manager.c b/src/manager.c
index 0cf0f8e..a2709b4 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -1,3 +1,4 @@
+#include "domain.h"
 #include "manager.h"
 #include "util.h"
 
@@ -5,483 +6,6 @@
 #include <errno.h>
 #include <stdlib.h>
 
-struct VirtManager {
-    sd_bus *bus;
-    virConnectPtr connection;
-
-    int callback_ids[VIR_DOMAIN_EVENT_ID_LAST];
-};
-
-static int
-domain_get_name(sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    const char *name = "";
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "s", "");
-
-    name = virDomainGetName(domain);
-    if (name == NULL)
-        return sd_bus_message_append(reply, "s", "");
-
-    return sd_bus_message_append(reply, "s", name);
-}
-
-static int
-domain_get_uuid(sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    char uuid[VIR_UUID_STRING_BUFLEN] = "";
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "s", "");
-
-    virDomainGetUUIDString(domain, uuid);
-
-    return sd_bus_message_append(reply, "s", uuid);
-}
-
-static int
-domain_get_id(sd_bus *bus,
-              const char *path,
-              const char *interface,
-              const char *property,
-              sd_bus_message *reply,
-              void *userdata,
-              sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "u", 0);
-
-    return sd_bus_message_append(reply, "u", virDomainGetID(domain));
-}
-
-static int
-domain_get_vcpus(sd_bus *bus,
-                 const char *path,
-                 const char *interface,
-                 const char *property,
-                 sd_bus_message *reply,
-                 void *userdata,
-                 sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "u", 0);
-
-    return sd_bus_message_append(reply, "u", virDomainGetVcpusFlags(domain, VIR_DOMAIN_VCPU_CURRENT));
-}
-
-static int
-domain_get_os_type(sd_bus *bus,
-                   const char *path,
-                   const char *interface,
-                   const char *property,
-                   sd_bus_message *reply,
-                   void *userdata,
-                   sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    _cleanup_(freep) char *os_type = NULL;
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "s", "");
-
-    os_type = virDomainGetOSType(domain);
-    if (os_type == NULL)
-        return sd_bus_message_append(reply, "s", "");
-
-    return sd_bus_message_append(reply, "s", os_type);
-}
-
-static int
-domain_get_active(sd_bus *bus,
-                  const char *path,
-                  const char *interface,
-                  const char *property,
-                  sd_bus_message *reply,
-                  void *userdata,
-                  sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int active;
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "b", 0);
-
-    active = virDomainIsActive(domain);
-    if (active < 0)
-        return sd_bus_message_append(reply, "b", 0);
-
-    return sd_bus_message_append(reply, "b", active);
-}
-
-static int
-domain_get_persistent(sd_bus *bus,
-                      const char *path,
-                      const char *interface,
-                      const char *property,
-                      sd_bus_message *reply,
-                      void *userdata,
-                      sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int persistent;
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "b", 0);
-
-    persistent = virDomainIsPersistent(domain);
-    if (persistent < 0)
-        return sd_bus_message_append(reply, "b", 0);
-
-    return sd_bus_message_append(reply, "b", persistent);
-}
-
-static int
-domain_get_state(sd_bus *bus,
-                 const char *path,
-                 const char *interface,
-                 const char *property,
-                 sd_bus_message *reply,
-                 void *userdata,
-                 sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int state = 0;
-    const char *string;
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "s", "");
-
-    virDomainGetState(domain, &state, NULL, 0);
-
-    switch (state) {
-        case VIR_DOMAIN_NOSTATE:
-        default:
-            string = "nostate";
-            break;
-        case VIR_DOMAIN_RUNNING:
-            string = "running";
-            break;
-        case VIR_DOMAIN_BLOCKED:
-            string = "blocked";
-            break;
-        case VIR_DOMAIN_PAUSED:
-            string = "paused";
-            break;
-        case VIR_DOMAIN_SHUTDOWN:
-            string = "shutdown";
-            break;
-        case VIR_DOMAIN_SHUTOFF:
-            string = "shutoff";
-            break;
-        case VIR_DOMAIN_CRASHED:
-            string = "crashed";
-            break;
-        case VIR_DOMAIN_PMSUSPENDED:
-            string = "pmsuspended";
-            break;
-    }
-
-    return sd_bus_message_append(reply, "s", string);
-}
-
-static int
-domain_get_autostart(sd_bus *bus,
-                     const char *path,
-                     const char *interface,
-                     const char *property,
-                     sd_bus_message *reply,
-                     void *userdata,
-                     sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int autostart = 0;
-
-    domain = domain_from_bus_path(manager->connection, path);
-    if (domain == NULL)
-        return sd_bus_message_append(reply, "b", 0);
-
-    virDomainGetAutostart(domain, &autostart);
-
-    return sd_bus_message_append(reply, "b", autostart);
-}
-
-static int
-domain_get_xml_desc(sd_bus_message *message,
-                    void *userdata,
-                    sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    _cleanup_(freep) char *description = NULL;
-    uint32_t flags;
-    int r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    r = sd_bus_message_read(message, "u", &flags);
-    if (r < 0)
-        return r;
-
-    description = virDomainGetXMLDesc(domain, flags);
-    if (!description)
-        return bus_error_set_last_virt_error(error);
-
-    return sd_bus_reply_method_return(message, "s", description);
-}
-
-static void
-virDomainStatsRecordListFreep(virDomainStatsRecordPtr **statsp)
-{
-    if (*statsp)
-        virDomainStatsRecordListFree(*statsp);
-}
-
-static int
-domain_get_stats(sd_bus_message *message,
-                 void *userdata,
-                 sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    virDomainPtr domains[2];
-    _cleanup_(virDomainStatsRecordListFreep) virDomainStatsRecordPtr *records = NULL;
-    _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-    uint32_t flags, stats;
-    int r;
-
-    r = sd_bus_message_read(message, "uu", &stats, &flags);
-    if (r < 0)
-        return r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    domains[0] = domain;
-    domains[1] = NULL;
-
-    if (virDomainListGetStats(domains, stats, &records, flags) != 1)
-        return bus_error_set_last_virt_error(error);
-
-    r = sd_bus_message_new_method_return(message, &reply);
-    if (r < 0)
-        return r;
-
-    r = bus_message_append_typed_parameters(reply, records[0]->params, records[0]->nparams);
-    if (r < 0)
-        return r;
-
-    return sd_bus_send(NULL, reply, NULL);
-}
-
-static int
-domain_shutdown(sd_bus_message *message,
-                void *userdata,
-                sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    r = virDomainShutdown(domain);
-    if (r < 0)
-        return bus_error_set_last_virt_error(error);
-
-    return sd_bus_reply_method_return(message, "");
-}
-
-static int
-domain_destroy(sd_bus_message *message,
-               void *userdata,
-               sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    r = virDomainDestroy(domain);
-    if (r < 0)
-        return bus_error_set_last_virt_error(error);
-
-    return sd_bus_reply_method_return(message, "");
-}
-
-static int
-domain_reboot(sd_bus_message *message,
-               void *userdata,
-               sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    uint32_t flags;
-    int r;
-
-    r = sd_bus_message_read(message, "u", &flags);
-    if (r < 0)
-        return r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    r = virDomainReboot(domain, flags);
-    if (r < 0)
-        return bus_error_set_last_virt_error(error);
-
-    return sd_bus_reply_method_return(message, "");
-}
-
-static int
-domain_reset(sd_bus_message *message,
-             void *userdata,
-             sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    uint32_t flags;
-    int r;
-
-    r = sd_bus_message_read(message, "u", &flags);
-    if (r < 0)
-        return r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    r = virDomainReset(domain, flags);
-    if (r < 0)
-        return bus_error_set_last_virt_error(error);
-
-    return sd_bus_reply_method_return(message, "");
-}
-
-static int
-domain_create(sd_bus_message *message,
-              void *userdata,
-              sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    r = virDomainCreate(domain);
-    if (r < 0)
-        return bus_error_set_last_virt_error(error);
-
-    return sd_bus_reply_method_return(message, "");
-}
-
-static int
-domain_undefine(sd_bus_message *message,
-                void *userdata,
-                sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int r;
-
-    domain = domain_from_bus_path(manager->connection,
-                                  sd_bus_message_get_path(message));
-    if (domain == NULL) {
-        return sd_bus_reply_method_errorf(message,
-                                          SD_BUS_ERROR_UNKNOWN_OBJECT,
-                                          "Unknown object '%s'.",
-                                          sd_bus_message_get_path(message));
-    }
-
-    r = virDomainUndefine(domain);
-    if (r < 0)
-        return bus_error_set_last_virt_error(error);
-
-    return sd_bus_reply_method_return(message, "");
-}
-
 static int
 enumerate_domains(sd_bus *bus,
                   const char *path,
@@ -808,40 +332,6 @@ handle_domain_tray_change_event(virConnectPtr connection,
     return sd_bus_send(manager->bus, message, NULL);
 }
 
-static int
-lookup_domain(sd_bus *bus,
-              const char *path,
-              const char *interface,
-              void *userdata,
-              void **found,
-              sd_bus_error *error)
-{
-    VirtManager *manager = userdata;
-    _cleanup_(freep) char *name = NULL;
-    _cleanup_(virDomainFreep) virDomainPtr domain = NULL;
-    int r;
-
-    r = sd_bus_path_decode(path, "/org/libvirt/domain", &name);
-    if (r < 0)
-        return r;
-
-    if (*name == '\0')
-        return 0;
-
-    domain = virDomainLookupByUUIDString(manager->connection, name);
-    if (!domain)
-        return 0;
-
-    /*
-     * There's no way to unref the pointer we're returning here. So,
-     * return the manager object and look up the domain again in the
-     * domain_* callbacks.
-     */
-    *found = manager;
-
-    return 1;
-}
-
 static void
 virt_manager_register_event(VirtManager *manager,
                             int id,
@@ -877,36 +367,6 @@ static const sd_bus_vtable virt_manager_vtable[] = {
     SD_BUS_VTABLE_END
 };
 
-static const sd_bus_vtable virt_domain_vtable[] = {
-    SD_BUS_VTABLE_START(0),
-
-    SD_BUS_PROPERTY("Name", "s", domain_get_name, 0, 0),
-    SD_BUS_PROPERTY("UUID", "s", domain_get_uuid, 0, 0),
-    SD_BUS_PROPERTY("Id", "u", domain_get_id, 0, 0),
-    SD_BUS_PROPERTY("Vcpus", "u", domain_get_vcpus, 0, 0),
-    SD_BUS_PROPERTY("OSType", "s", domain_get_os_type, 0, 0),
-    SD_BUS_PROPERTY("Active", "b", domain_get_active, 0, 0),
-    SD_BUS_PROPERTY("Persistent", "b", domain_get_persistent, 0, 0),
-    SD_BUS_PROPERTY("State", "s", domain_get_state, 0, 0),
-    SD_BUS_PROPERTY("Autostart", "b", domain_get_autostart, 0, 0),
-
-    SD_BUS_METHOD("GetXMLDesc", "u", "s", domain_get_xml_desc, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_METHOD("GetStats", "uu", "a{sv}", domain_get_stats, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_METHOD("Shutdown", "", "", domain_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_METHOD("Destroy", "", "", domain_destroy, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_METHOD("Reboot", "u", "", domain_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_METHOD("Reset", "u", "", domain_reset, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_METHOD("Create", "", "", domain_create, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_METHOD("Undefine", "", "", domain_undefine, SD_BUS_VTABLE_UNPRIVILEGED),
-
-    SD_BUS_SIGNAL("DeviceAdded", "s", 0),
-    SD_BUS_SIGNAL("DeviceRemoved", "s", 0),
-    SD_BUS_SIGNAL("DiskChange", "ssss", 0),
-    SD_BUS_SIGNAL("TrayChange", "ss", 0),
-
-    SD_BUS_VTABLE_END
-};
-
 int
 virt_manager_new(VirtManager **managerp,
                  sd_bus *bus,
@@ -958,14 +418,7 @@ virt_manager_new(VirtManager **managerp,
     if (r < 0)
         return r;
 
-    r = sd_bus_add_fallback_vtable(bus,
-                                   NULL,
-                                   "/org/libvirt/domain",
-                                   "org.libvirt.Domain",
-                                   virt_domain_vtable,
-                                   lookup_domain,
-                                   manager);
-    if (r < 0)
+    if ((r = domain_register(manager, bus) < 0))
         return r;
 
     *managerp = manager;
diff --git a/src/manager.h b/src/manager.h
index 8f2aedb..06aaa04 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -5,6 +5,12 @@
 #include <libvirt/libvirt.h>
 #include <systemd/sd-bus.h>
 
+struct VirtManager {
+    sd_bus *bus;
+    virConnectPtr connection;
+
+    int callback_ids[VIR_DOMAIN_EVENT_ID_LAST];
+};
 typedef struct VirtManager VirtManager;
 
 int virt_manager_new(VirtManager **managerp,
-- 
2.13.3




More information about the libvir-list mailing list