Prepare for code sharing. No semantic change.
* src/qemu/qemu_driver.c (qemuFindQemuImgBinary)
(qemuDomainSnapshotDiscard): Float up.
(qemuDomainSnapshotDiscardDescendant): Likewise, and rename...
(qemuDomainSnapshotDiscardAll): ...for generic use.
(qemuDomainSnapshotDelete): Update caller.
---
src/qemu/qemu_driver.c | 253 ++++++++++++++++++++++++-----------------------
1 files changed, 129 insertions(+), 124 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 678ac1b..d9e88fe 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1574,6 +1574,134 @@ cleanup:
}
+struct snap_remove {
+ struct qemud_driver *driver;
+ virDomainObjPtr vm;
+ bool metadata_only;
+ int err;
+};
+
+/* Locate an appropriate 'qemu-img' binary. */
+static char *
+qemuFindQemuImgBinary(void)
+{
+ char *ret;
+
+ ret = virFindFileInPath("kvm-img");
+ if (ret == NULL)
+ ret = virFindFileInPath("qemu-img");
+ if (ret == NULL)
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("unable to find kvm-img or
qemu-img"));
+
+ return ret;
+}
+
+/* Discard one snapshot (or its metadata), without reparenting any children. */
+static int
+qemuDomainSnapshotDiscard(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainSnapshotObjPtr snap,
+ bool metadata_only)
+{
+ const char *qemuimgarg[] = { NULL, "snapshot", "-d", NULL, NULL,
NULL };
+ char *snapFile = NULL;
+ int ret = -1;
+ int i;
+ qemuDomainObjPrivatePtr priv;
+ virDomainSnapshotObjPtr parentsnap;
+
+ if (!metadata_only) {
+ if (!virDomainObjIsActive(vm)) {
+ qemuimgarg[0] = qemuFindQemuImgBinary();
+ if (qemuimgarg[0] == NULL)
+ /* qemuFindQemuImgBinary set the error */
+ goto cleanup;
+
+ qemuimgarg[3] = snap->def->name;
+
+ for (i = 0; i < vm->def->ndisks; i++) {
+ /* FIXME: we also need to handle LVM here */
+ if (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+ if (!vm->def->disks[i]->driverType ||
+ STRNEQ(vm->def->disks[i]->driverType,
"qcow2")) {
+ /* we continue on even in the face of error, since other
+ * disks in this VM may have this snapshot in place
+ */
+ continue;
+ }
+
+ qemuimgarg[4] = vm->def->disks[i]->src;
+
+ if (virRun(qemuimgarg, NULL) < 0) {
+ /* we continue on even in the face of error, since other
+ * disks in this VM may have this snapshot in place
+ */
+ continue;
+ }
+ }
+ }
+ } else {
+ priv = vm->privateData;
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ /* we continue on even in the face of error */
+ qemuMonitorDeleteSnapshot(priv->mon, snap->def->name);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ }
+ }
+
+ if (snap == vm->current_snapshot) {
+ if (snap->def->parent) {
+ parentsnap = virDomainSnapshotFindByName(&vm->snapshots,
+ snap->def->parent);
+ if (!parentsnap) {
+ qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
+ _("no domain snapshot parent with matching name
'%s'"),
+ snap->def->parent);
+ goto cleanup;
+ }
+
+ /* Now we set the new current_snapshot for the domain */
+ vm->current_snapshot = parentsnap;
+ } else {
+ vm->current_snapshot = NULL;
+ }
+ }
+
+ if (virAsprintf(&snapFile, "%s/%s/%s.xml", driver->snapshotDir,
+ vm->def->name, snap->def->name) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ unlink(snapFile);
+
+ virDomainSnapshotObjListRemove(&vm->snapshots, snap);
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(snapFile);
+ VIR_FREE(qemuimgarg[0]);
+
+ return ret;
+}
+
+/* Hash iterator callback to discard multiple snapshots. */
+static void
+qemuDomainSnapshotDiscardAll(void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ void *data)
+{
+ virDomainSnapshotObjPtr snap = payload;
+ struct snap_remove *curr = data;
+ int err;
+
+ err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap,
+ curr->metadata_only);
+ if (err && !curr->err)
+ curr->err = err;
+}
+
static int
qemuDomainDestroyFlags(virDomainPtr dom,
unsigned int flags)
@@ -8272,20 +8400,6 @@ cleanup:
return ret;
}
-static char *qemuFindQemuImgBinary(void)
-{
- char *ret;
-
- ret = virFindFileInPath("kvm-img");
- if (ret == NULL)
- ret = virFindFileInPath("qemu-img");
- if (ret == NULL)
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("unable to find kvm-img or
qemu-img"));
-
- return ret;
-}
-
static int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
virDomainSnapshotObjPtr snapshot,
char *snapshotDir)
@@ -8951,115 +9065,6 @@ cleanup:
return ret;
}
-static int qemuDomainSnapshotDiscard(struct qemud_driver *driver,
- virDomainObjPtr vm,
- virDomainSnapshotObjPtr snap,
- bool metadata_only)
-{
- const char *qemuimgarg[] = { NULL, "snapshot", "-d", NULL, NULL,
NULL };
- char *snapFile = NULL;
- int ret = -1;
- int i;
- qemuDomainObjPrivatePtr priv;
- virDomainSnapshotObjPtr parentsnap;
-
- if (!metadata_only) {
- if (!virDomainObjIsActive(vm)) {
- qemuimgarg[0] = qemuFindQemuImgBinary();
- if (qemuimgarg[0] == NULL)
- /* qemuFindQemuImgBinary set the error */
- goto cleanup;
-
- qemuimgarg[3] = snap->def->name;
-
- for (i = 0; i < vm->def->ndisks; i++) {
- /* FIXME: we also need to handle LVM here */
- if (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
- if (!vm->def->disks[i]->driverType ||
- STRNEQ(vm->def->disks[i]->driverType,
"qcow2")) {
- /* we continue on even in the face of error, since other
- * disks in this VM may have this snapshot in place
- */
- continue;
- }
-
- qemuimgarg[4] = vm->def->disks[i]->src;
-
- if (virRun(qemuimgarg, NULL) < 0) {
- /* we continue on even in the face of error, since other
- * disks in this VM may have this snapshot in place
- */
- continue;
- }
- }
- }
- } else {
- priv = vm->privateData;
- qemuDomainObjEnterMonitorWithDriver(driver, vm);
- /* we continue on even in the face of error */
- qemuMonitorDeleteSnapshot(priv->mon, snap->def->name);
- qemuDomainObjExitMonitorWithDriver(driver, vm);
- }
- }
-
- if (snap == vm->current_snapshot) {
- if (snap->def->parent) {
- parentsnap = virDomainSnapshotFindByName(&vm->snapshots,
- snap->def->parent);
- if (!parentsnap) {
- qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
- _("no domain snapshot parent with matching name
'%s'"),
- snap->def->parent);
- goto cleanup;
- }
-
- /* Now we set the new current_snapshot for the domain */
- vm->current_snapshot = parentsnap;
- } else {
- vm->current_snapshot = NULL;
- }
- }
-
- if (virAsprintf(&snapFile, "%s/%s/%s.xml", driver->snapshotDir,
- vm->def->name, snap->def->name) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- unlink(snapFile);
-
- virDomainSnapshotObjListRemove(&vm->snapshots, snap);
-
- ret = 0;
-
-cleanup:
- VIR_FREE(snapFile);
- VIR_FREE(qemuimgarg[0]);
-
- return ret;
-}
-
-struct snap_remove {
- struct qemud_driver *driver;
- virDomainObjPtr vm;
- bool metadata_only;
- int err;
-};
-
-static void
-qemuDomainSnapshotDiscardDescendant(void *payload,
- const void *name ATTRIBUTE_UNUSED,
- void *data)
-{
- virDomainSnapshotObjPtr snap = payload;
- struct snap_remove *curr = data;
- int err;
-
- err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap,
- curr->metadata_only);
- if (err && !curr->err)
- curr->err = err;
-}
-
struct snap_reparent {
struct qemud_driver *driver;
virDomainSnapshotObjPtr snap;
@@ -9139,7 +9144,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
rem.err = 0;
virDomainSnapshotForEachDescendant(&vm->snapshots,
snap,
- qemuDomainSnapshotDiscardDescendant,
+ qemuDomainSnapshotDiscardAll,
&rem);
if (rem.err < 0)
goto endjob;
--
1.7.4.4