[libvirt] [libvirt-dbus][PATCH v4 1/2] Introduce Domain Snapshot Interface

Simon Kobyda skobyda at redhat.com
Mon Nov 4 11:24:08 UTC 2019


Signed-off-by: Simon Kobyda <skobyda at redhat.com>
---
 data/meson.build                    |  1 +
 data/org.libvirt.DomainSnapshot.xml |  7 +++
 src/connect.c                       |  6 +++
 src/connect.h                       |  1 +
 src/domainsnapshot.c                | 75 +++++++++++++++++++++++++++++
 src/domainsnapshot.h                |  9 ++++
 src/meson.build                     |  1 +
 src/util.c                          | 53 ++++++++++++++++++++
 src/util.h                          | 16 ++++++
 9 files changed, 169 insertions(+)
 create mode 100644 data/org.libvirt.DomainSnapshot.xml
 create mode 100644 src/domainsnapshot.c
 create mode 100644 src/domainsnapshot.h

diff --git a/data/meson.build b/data/meson.build
index 42a6799..0bd6338 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -1,6 +1,7 @@
 install_data(
     'org.libvirt.Connect.xml',
     'org.libvirt.Domain.xml',
+    'org.libvirt.DomainSnapshot.xml',
     'org.libvirt.Interface.xml',
     'org.libvirt.Network.xml',
     'org.libvirt.NodeDevice.xml',
diff --git a/data/org.libvirt.DomainSnapshot.xml b/data/org.libvirt.DomainSnapshot.xml
new file mode 100644
index 0000000..8ba059f
--- /dev/null
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<node name="/org/libvirt/domainsnapshot">
+  <interface name="org.libvirt.DomainSnapshot">
+  </interface>
+</node>
diff --git a/src/connect.c b/src/connect.c
index f8f76a2..b40b0ba 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -1,5 +1,6 @@
 #include "connect.h"
 #include "domain.h"
+#include "domainsnapshot.h"
 #include "events.h"
 #include "interface.h"
 #include "network.h"
@@ -2002,6 +2003,7 @@ virtDBusConnectFree(virtDBusConnect *connect)
         virtDBusConnectClose(connect, TRUE);
 
     g_free(connect->domainPath);
+    g_free(connect->domainSnapshotPath);
     g_free(connect->interfacePath);
     g_free(connect->networkPath);
     g_free(connect->nodeDevPath);
@@ -2062,6 +2064,10 @@ virtDBusConnectNew(virtDBusConnect **connectp,
     if (error && *error)
         return;
 
+    virtDBusDomainSnapshotRegister(connect, error);
+    if (error && *error)
+        return;
+
     virtDBusInterfaceRegister(connect, error);
     if (error && *error)
         return;
diff --git a/src/connect.h b/src/connect.h
index 829bd57..74c89cf 100644
--- a/src/connect.h
+++ b/src/connect.h
@@ -13,6 +13,7 @@ struct virtDBusConnect {
     const gchar *uri;
     const gchar *connectPath;
     gchar *domainPath;
+    gchar *domainSnapshotPath;
     gchar *interfacePath;
     gchar *networkPath;
     gchar *nodeDevPath;
diff --git a/src/domainsnapshot.c b/src/domainsnapshot.c
new file mode 100644
index 0000000..c523c9e
--- /dev/null
+++ b/src/domainsnapshot.c
@@ -0,0 +1,75 @@
+#include "domainsnapshot.h"
+#include "util.h"
+
+#include <libvirt/libvirt.h>
+
+static virtDBusGDBusPropertyTable virtDBusDomainSnapshotPropertyTable[] = {
+    { 0 }
+};
+
+static virtDBusGDBusMethodTable virtDBusDomainSnapshotMethodTable[] = {
+    { 0 }
+};
+
+static gchar **
+virtDBusDomainSnapshotEnumerate(gpointer userData)
+{
+    virtDBusConnect *connect = userData;
+    g_autoptr(virDomainPtr) domains = NULL;
+    gint numDoms = 0;
+    GPtrArray *list = NULL;
+
+    if (!virtDBusConnectOpen(connect, NULL))
+        return NULL;
+
+    numDoms = virConnectListAllDomains(connect->connection, &domains, 0);
+    if (numDoms <= 0)
+        return NULL;
+
+    list = g_ptr_array_new();
+
+    for (gint i = 0; i < numDoms; i++) {
+        g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
+        gint numSnaps;
+
+        numSnaps = virDomainListAllSnapshots(domains[i], &domainSnapshots, 0);
+        if (numSnaps <= 0)
+            continue;
+
+        for (gint j = 0; j < numSnaps; j++) {
+            gchar *snapPath = virtDBusUtilBusPathForVirDomainSnapshot(domains[i],
+                                                                      domainSnapshots[j],
+                                                                      connect->domainSnapshotPath);
+            g_ptr_array_add(list, snapPath);
+        }
+    }
+
+    if (list->len > 0)
+        g_ptr_array_add(list, NULL);
+
+    return (gchar **)g_ptr_array_free(list, FALSE);
+}
+
+static GDBusInterfaceInfo *interfaceInfo = NULL;
+
+void
+virtDBusDomainSnapshotRegister(virtDBusConnect *connect,
+                               GError **error)
+{
+    connect->domainSnapshotPath = g_strdup_printf("%s/domainsnapshot", connect->connectPath);
+
+    if (!interfaceInfo) {
+        interfaceInfo = virtDBusGDBusLoadIntrospectData(VIRT_DBUS_DOMAIN_SNAPSHOT_INTERFACE,
+                                                        error);
+        if (!interfaceInfo)
+            return;
+    }
+
+    virtDBusGDBusRegisterSubtree(connect->bus,
+                                 connect->domainSnapshotPath,
+                                 interfaceInfo,
+                                 virtDBusDomainSnapshotEnumerate,
+                                 virtDBusDomainSnapshotMethodTable,
+                                 virtDBusDomainSnapshotPropertyTable,
+                                 connect);
+}
diff --git a/src/domainsnapshot.h b/src/domainsnapshot.h
new file mode 100644
index 0000000..7d8a938
--- /dev/null
+++ b/src/domainsnapshot.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "connect.h"
+
+#define VIRT_DBUS_DOMAIN_SNAPSHOT_INTERFACE "org.libvirt.DomainSnapshot"
+
+void
+virtDBusDomainSnapshotRegister(virtDBusConnect *connect,
+                               GError **error);
diff --git a/src/meson.build b/src/meson.build
index de96596..1839c79 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -16,6 +16,7 @@ exe_libvirt_dbus = executable(
     [
         'connect.c',
         'domain.c',
+        'domainsnapshot.c',
         'events.c',
         'gdbus.c',
         'interface.c',
diff --git a/src/util.c b/src/util.c
index 103bb29..71ffba5 100644
--- a/src/util.c
+++ b/src/util.c
@@ -3,6 +3,9 @@
 #include <libvirt/virterror.h>
 #include <string.h>
 
+/* result of strlen("_00000000_1111_2222_3333_444444444444") */
+#define VIRT_DBUS_UUID_LEN 37
+
 static const GDBusErrorEntry virtDBusUtilErrorEntries[] = {
     { VIRT_DBUS_ERROR_LIBVIRT, "org.libvirt.Error" },
 };
@@ -279,6 +282,56 @@ virtDBusUtilVirDomainListFree(virDomainPtr *domains)
     g_free(domains);
 }
 
+virDomainSnapshotPtr
+virtDBusUtilVirDomainSnapshotFromBusPath(virConnectPtr connection,
+                                         const gchar *path,
+                                         const gchar *domainSnapshotPath)
+{
+    g_autofree gchar *uuidStr = NULL;
+    g_autofree gchar *snapshotName = NULL;
+    g_autoptr(virDomain) domain = NULL;
+    gsize prefixLen = strlen(domainSnapshotPath) + 1;
+    g_autofree gchar *tmp = g_strdup(path + prefixLen);
+
+    tmp[VIRT_DBUS_UUID_LEN] = 0;
+
+    uuidStr = virtDBusUtilDecodeUUID(tmp);
+    snapshotName = virtDBusUtilDecodeStr(tmp + VIRT_DBUS_UUID_LEN + 1);
+
+    domain = virDomainLookupByUUIDString(connection, uuidStr);
+
+    return virDomainSnapshotLookupByName(domain, snapshotName, 0);
+}
+
+gchar *
+virtDBusUtilBusPathForVirDomainSnapshot(virDomainPtr domain,
+                                        virDomainSnapshotPtr domainSnapshot,
+                                        const gchar *domainSnapshotPath)
+{
+    const gchar *snapshotName = NULL;
+    gchar uuidStr[VIR_UUID_STRING_BUFLEN] = "";
+    g_autofree const gchar *encodedDomainNameStr = NULL;
+    g_autofree const gchar *encodedSnapshotNameStr = NULL;
+
+    virDomainGetUUIDString(domain, uuidStr);
+
+    snapshotName = virDomainSnapshotGetName(domainSnapshot);
+    encodedDomainNameStr = virtDBusUtilEncodeUUID(uuidStr);
+    encodedSnapshotNameStr = virtDBusUtilEncodeStr(snapshotName);
+
+    return g_strdup_printf("%s/%s_%s", domainSnapshotPath,
+                           encodedDomainNameStr, encodedSnapshotNameStr);
+}
+
+void
+virtDBusUtilVirDomainSnapshotListFree(virDomainSnapshotPtr* domainSnapshots)
+{
+    for (gint i = 0; domainSnapshots[i] != NULL; i++)
+        virDomainSnapshotFree(domainSnapshots[i]);
+
+    g_free(domainSnapshots);
+}
+
 virInterfacePtr
 virtDBusUtilVirInterfaceFromBusPath(virConnectPtr connection,
                                     const gchar *path,
diff --git a/src/util.h b/src/util.h
index b05c2fc..c0b314d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -65,6 +65,22 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainPtr, virtDBusUtilVirDomainListFree);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainStatsRecordPtr, virDomainStatsRecordListFree);
 
+virDomainSnapshotPtr
+virtDBusUtilVirDomainSnapshotFromBusPath(virConnectPtr connection,
+                                         const gchar *path,
+                                         const gchar *domainSnapshotPath);
+
+gchar *
+virtDBusUtilBusPathForVirDomainSnapshot(virDomainPtr domain,
+                                        virDomainSnapshotPtr domainSnapshot,
+                                        const gchar *domainSnapshotPath);
+
+void
+virtDBusUtilVirDomainSnapshotListFree(virDomainSnapshotPtr* domainSnapshots);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainSnapshot, virDomainSnapshotFree);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainSnapshotPtr, virtDBusUtilVirDomainSnapshotListFree);
+
 virInterfacePtr
 virtDBusUtilVirInterfaceFromBusPath(virConnectPtr connection,
                                     const gchar *path,
-- 
2.21.0




More information about the libvir-list mailing list