Commit 9f5e53e introduced the ability to filter snapshots to
just roots, but it was never implemented for VBox until now.
The VBox documentation makes it appear that there can only be
at most one root snapshot, which will be found by searching
for the snapshot with a NULL uuid.
* src/vbox/vbox_tmpl.c (vboxDomainSnapshotNum)
(vboxDomainSnapshotListNames): Implement limiting list to root.
---
Caveat: I was only able to compile-test this. Nothing in the VBox
documentation that I read mentioned what happens if you try to call
IConsole::deleteSnapshot on the root snapshot with branched children
(well, it is obvious that prior to VBox 3.1, this will fail, because
branched snapshots in general were not supported before then). If,
like other hypervisors, it is possible to delete the root, leaving
multiple children as independent roots, then I have no idea how to
list those additional roots, since IMachine::findSnapshot is only
wired to return a single root when passed a NULL search string.
So I blindly assumed that at most 1 root is possible, and am hoping
that VBox rejects attempts to delete the root if it has multiple
children.
src/vbox/vbox_tmpl.c | 37 ++++++++++++++++++++++++++++++++-----
1 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index ba2252c..d1da6fd 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -5900,7 +5900,8 @@ vboxDomainSnapshotNum(virDomainPtr dom,
nsresult rc;
PRUint32 snapshotCount;
- virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
+ virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
+ VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
vboxIIDFromUUID(&iid, dom->uuid);
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
@@ -5924,7 +5925,11 @@ vboxDomainSnapshotNum(virDomainPtr dom,
goto cleanup;
}
- ret = snapshotCount;
+ /* VBox has at most one root snapshot. */
+ if (snapshotCount && (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS))
+ ret = 1;
+ else
+ ret = snapshotCount;
cleanup:
VBOX_RELEASE(machine);
@@ -5946,7 +5951,8 @@ vboxDomainSnapshotListNames(virDomainPtr dom,
int count = 0;
int i;
- virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
+ virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
+ VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
vboxIIDFromUUID(&iid, dom->uuid);
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
@@ -5961,8 +5967,29 @@ vboxDomainSnapshotListNames(virDomainPtr dom,
goto cleanup;
}
- if ((count = vboxDomainSnapshotGetAll(dom, machine, &snapshots)) < 0)
- goto cleanup;
+ if (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) {
+ vboxIID empty = VBOX_IID_INITIALIZER;
+
+ if (VIR_ALLOC_N(snapshots, 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+#if VBOX_API_VERSION < 4000
+ rc = machine->vtbl->GetSnapshot(machine, empty.value, snapshots);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = machine->vtbl->FindSnapshot(machine, empty.value, snapshots);
+#endif /* VBOX_API_VERSION >= 4000 */
+ if (NS_FAILED(rc) || !snapshots[0]) {
+ vboxError(VIR_ERR_INTERNAL_ERROR,
+ _("could not get root snapshot for domain %s"),
+ dom->name);
+ goto cleanup;
+ }
+ count = 1;
+ } else {
+ if ((count = vboxDomainSnapshotGetAll(dom, machine, &snapshots)) < 0)
+ goto cleanup;
+ }
for (i = 0; i < nameslen; i++) {
PRUnichar *nameUtf16;
--
1.7.4.4