On Mon, Mar 11, 2019 at 09:38:39PM -0500, Eric Blake wrote:
Implement the new API calls for bulk snapshot dump and import. This
borrows from ideas in the test driver, but import is further
complicated by the fact that qemu writes snapshot XML to disk, and
thus must do additional validation after the initial parse to ensure
the user didn't attempt to create a snapshot with "../" or similar.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/qemu/qemu_driver.c | 116 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 115 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d679587819..e1be3d0c5e 100644
+static int
+qemuDomainImportSnapshotsXML(virDomainPtr domain,
+ const char *xmlDesc,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = domain->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ unsigned int parse_flags = VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE |
+ VIR_DOMAIN_SNAPSHOT_PARSE_DISKS;
+ struct qemuDomainSnapshotBulk bulk = { .driver = driver, };
+ virQEMUDriverConfigPtr cfg = NULL;
+
+ virCheckFlags(0, -1);
+
+ if (!(vm = qemuDomObjFromDomain(domain)))
+ return -1;
+
+ if (virDomainImportSnapshotsXMLEnsureACL(domain->conn, vm->def) < 0)
+ goto cleanup;
+
+ cfg = virQEMUDriverGetConfig(driver);
+
+ ret = virDomainSnapshotObjListParse(xmlDesc, vm->def->uuid, vm->snapshots,
+ &vm->current_snapshot, driver->caps,
+ driver->xmlopt, parse_flags);
+ if (ret < 0)
+ goto cleanup;
+
+ /* Validate and save the snapshots to disk. Since we don't get
+ * here unless there were no snapshots beforehand, just delete
+ * everything on the first failure, ignoring further errors. */
+ bulk.vm = vm;
+ bulk.snapshotDir = cfg->snapshotDir;
+ if (virDomainSnapshotForEach(vm->snapshots, false,
+ qemuDomainSnapshotBulkRedefine, &bulk) < 0) {
+ virErrorPtr orig_err = NULL;
+
+ virErrorPreserveLast(&orig_err);
+ qemuDomainSnapshotDiscardAllMetadata(driver, vm);
+ virErrorRestore(&orig_err);
+ ret = 0;
ret = -1;
Alternatively, use a separate 'rc' variable for the return value of
virDomainSnapshotObjListParse
+ goto cleanup;
+ }
and add:
ret = rc;
here to only have two places where we modify this function's return
value.
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ virObjectUnref(cfg);
+ return ret;
+}
+
Reviewed-by: Ján Tomko <jtomko(a)redhat.com>
Jano