[libvirt] [PATCH 4/4] snapshot: implement snapshot children listing in qemu

Eric Blake eblake at redhat.com
Thu Sep 29 19:02:30 UTC 2011


Not too hard to wire up.  The trickiest part is realizing that
listing children of a snapshot cannot use SNAPSHOT_LIST_ROOTS,
and that we overloaded that bit to also mean SNAPSHOT_LIST_DESCENDANTS;
we use that bit to decide which iteration to use, but don't want
the existing counting/listing functions to see that bit.

* src/conf/domain_conf.h (virDomainSnapshotObjListNumFrom)
(virDomainSnapshotObjListGetNamesFrom): New prototypes.
* src/conf/domain_conf.c (virDomainSnapshotObjListNumFrom)
(virDomainSnapshotObjListGetNamesFrom): New functions.
* src/libvirt_private.syms (domain_conf.h): Export them.
* src/qemu/qemu_driver.c (qemuDomainSnapshotNumChildren)
(qemuDomainSnapshotListChildrenNames): New functions.
---
 src/conf/domain_conf.c   |   51 +++++++++++++++++++++++++++
 src/conf/domain_conf.h   |    7 ++++
 src/libvirt_private.syms |    2 +
 src/qemu/qemu_driver.c   |   87 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+), 0 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1871974..40b3589 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12132,6 +12132,37 @@ cleanup:
     return -1;
 }

+int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
+                                         virDomainSnapshotObjListPtr snapshots,
+                                         char **const names, int maxnames,
+                                         unsigned int flags)
+{
+    struct virDomainSnapshotNameData data = { 0, 0, maxnames, names, 0 };
+    int i;
+
+    data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
+
+    if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
+        virDomainSnapshotForEachDescendant(snapshots, snapshot,
+                                           virDomainSnapshotObjListCopyNames,
+                                           &data);
+    else
+        virDomainSnapshotForEachChild(snapshots, snapshot,
+                                      virDomainSnapshotObjListCopyNames, &data);
+
+    if (data.oom) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    return data.numnames;
+
+cleanup:
+    for (i = 0; i < data.numnames; i++)
+        VIR_FREE(data.names[i]);
+    return -1;
+}
+
 struct virDomainSnapshotNumData {
     int count;
     unsigned int flags;
@@ -12159,6 +12190,26 @@ int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
     return data.count;
 }

+int
+virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
+                                virDomainSnapshotObjListPtr snapshots,
+                                unsigned int flags)
+{
+    struct virDomainSnapshotNumData data = { 0, 0 };
+
+    data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
+
+    if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
+        virDomainSnapshotForEachDescendant(snapshots, snapshot,
+                                           virDomainSnapshotObjListCount,
+                                           &data);
+    else
+        virDomainSnapshotForEachChild(snapshots, snapshot,
+                                      virDomainSnapshotObjListCount, &data);
+
+    return data.count;
+}
+
 virDomainSnapshotObjPtr
 virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
                             const char *name)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 4126d58..1d490d0 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1488,6 +1488,13 @@ int virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots,
                                      unsigned int flags);
 int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
                                 unsigned int flags);
+int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
+                                         virDomainSnapshotObjListPtr snapshots,
+                                         char **const names, int maxnames,
+                                         unsigned int flags);
+int virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
+                                    virDomainSnapshotObjListPtr snapshots,
+                                    unsigned int flags);
 virDomainSnapshotObjPtr virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
                                                     const char *name);
 void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6505eae..3c7e44d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -419,7 +419,9 @@ virDomainSnapshotForEachChild;
 virDomainSnapshotForEachDescendant;
 virDomainSnapshotHasChildren;
 virDomainSnapshotObjListGetNames;
+virDomainSnapshotObjListGetNamesFrom;
 virDomainSnapshotObjListNum;
+virDomainSnapshotObjListNumFrom;
 virDomainSnapshotObjListRemove;
 virDomainSnapshotStateTypeFromString;
 virDomainSnapshotStateTypeToString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b459b73..eccb48d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9448,6 +9448,91 @@ cleanup:
     return n;
 }

+static int
+qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
+                                    char **names,
+                                    int nameslen,
+                                    unsigned int flags)
+{
+    struct qemud_driver *driver = snapshot->domain->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    virDomainSnapshotObjPtr snap = NULL;
+    int n = -1;
+
+    virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
+                  VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(snapshot->domain->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
+    if (!snap) {
+        qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
+                        _("no domain snapshot with matching name '%s'"),
+                        snapshot->name);
+        goto cleanup;
+    }
+
+    n = virDomainSnapshotObjListGetNamesFrom(snap, &vm->snapshots,
+                                             names, nameslen, flags);
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return n;
+}
+
+static int
+qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
+                              unsigned int flags)
+{
+    struct qemud_driver *driver = snapshot->domain->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    virDomainSnapshotObjPtr snap = NULL;
+    int n = -1;
+
+    virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
+                  VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(snapshot->domain->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
+    if (!snap) {
+        qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
+                        _("no domain snapshot with matching name '%s'"),
+                        snapshot->name);
+        goto cleanup;
+    }
+
+    /* All qemu snapshots have libvirt metadata, so
+     * VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our
+     * answer.  */
+
+    n = virDomainSnapshotObjListNumFrom(snap, &vm->snapshots, flags);
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return n;
+}
+
 static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain,
                                                            const char *name,
                                                            unsigned int flags)
@@ -10538,6 +10623,8 @@ static virDriver qemuDriver = {
     .domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */
     .domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */
     .domainSnapshotListNames = qemuDomainSnapshotListNames, /* 0.8.0 */
+    .domainSnapshotNumChildren = qemuDomainSnapshotNumChildren, /* 0.9.7 */
+    .domainSnapshotListChildrenNames = qemuDomainSnapshotListChildrenNames, /* 0.9.7 */
     .domainSnapshotLookupByName = qemuDomainSnapshotLookupByName, /* 0.8.0 */
     .domainHasCurrentSnapshot = qemuDomainHasCurrentSnapshot, /* 0.8.0 */
     .domainSnapshotGetParent = qemuDomainSnapshotGetParent, /* 0.9.7 */
-- 
1.7.4.4




More information about the libvir-list mailing list