]> xenbits.xensource.com Git - libvirt.git/commitdiff
snapshot: implement snapshot children listing in qemu
authorEric Blake <eblake@redhat.com>
Thu, 29 Sep 2011 18:42:36 +0000 (12:42 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 10 Oct 2011 23:31:06 +0000 (17:31 -0600)
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
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_driver.c

index 944cfa96f5aabf5a3b80999ae273244628f4afab..b9ddf26df0f0888b5a9e6a71439fef5d52b7a678 100644 (file)
@@ -12180,6 +12180,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;
@@ -12207,6 +12238,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)
index e07fd2f7187714bf585e1c59d9cc8fccc9a924e8..8765f32fde681e0332eb1cfd73b384171dc86d31 100644 (file)
@@ -1499,6 +1499,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,
index 1ac486fb5a72f52452b08b679846b574b8618695..a17623ac5cf9a9af8a09c9dd562c7a1eee8f8f5a 100644 (file)
@@ -415,7 +415,9 @@ virDomainSnapshotForEachChild;
 virDomainSnapshotForEachDescendant;
 virDomainSnapshotHasChildren;
 virDomainSnapshotObjListGetNames;
+virDomainSnapshotObjListGetNamesFrom;
 virDomainSnapshotObjListNum;
+virDomainSnapshotObjListNumFrom;
 virDomainSnapshotObjListRemove;
 virDomainSnapshotStateTypeFromString;
 virDomainSnapshotStateTypeToString;
index 5588d93faf7d2bb6b55b5f0d176621a6026fe969..4ea3236f871371876eccbdfff17d4a8640595666 100644 (file)
@@ -9446,6 +9446,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)
@@ -10568,6 +10653,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 */