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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list