Prepare for code sharing. No semantic change.
* src/qemu/qemu_driver.c (qemuFindQemuImgBinary)
(qemuDomainSnapshotWriteMetadata)
(qemuDomainSnapshotDiscard): Float up.
(qemuDomainSnapshotDiscardDescendant): Likewise, and rename...
(qemuDomainSnapshotDiscardAll): ...for generic use.
(qemuDomainSnapshotDelete): Update caller.
---
src/qemu/qemu_driver.c | 370 ++++++++++++++++++++++++------------------------
1 files changed, 187 insertions(+), 183 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 754ab71..3977135 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1580,6 +1580,192 @@ 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;
+}
+
+static int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
+ virDomainSnapshotObjPtr snapshot,
+ char *snapshotDir)
+{
+ int fd = -1;
+ char *newxml = NULL;
+ int ret = -1;
+ char *snapDir = NULL;
+ char *snapFile = NULL;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ newxml = virDomainSnapshotDefFormat(uuidstr, snapshot->def, 1);
+ if (newxml == NULL) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (virAsprintf(&snapDir, "%s/%s", snapshotDir, vm->def->name)
< 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ if (virFileMakePath(snapDir) < 0) {
+ virReportSystemError(errno, _("cannot create snapshot directory
'%s'"),
+ snapDir);
+ goto cleanup;
+ }
+
+ if (virAsprintf(&snapFile, "%s/%s.xml", snapDir,
snapshot->def->name) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ fd = open(snapFile, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
+ if (fd < 0) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("failed to create snapshot file '%s'"),
snapFile);
+ goto cleanup;
+ }
+ if (safewrite(fd, newxml, strlen(newxml)) != strlen(newxml)) {
+ virReportSystemError(errno, _("Failed to write snapshot data to %s"),
+ snapFile);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(snapFile);
+ VIR_FREE(snapDir);
+ VIR_FREE(newxml);
+ VIR_FORCE_CLOSE(fd);
+ 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 (virAsprintf(&snapFile, "%s/%s/%s.xml", driver->snapshotDir,
+ vm->def->name, snap->def->name) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (snap == vm->current_snapshot) {
+ if (snap->def->parent) {
+ parentsnap = virDomainSnapshotFindByName(&vm->snapshots,
+ snap->def->parent);
+ if (!parentsnap) {
+ VIR_WARN("missing parent snapshot matching name '%s'",
+ snap->def->parent);
+ } else {
+ parentsnap->def->current = true;
+ if (qemuDomainSnapshotWriteMetadata(vm, snap,
+ driver->snapshotDir) < 0) {
+ VIR_WARN("failed to set parent snapshot '%s' as
current",
+ snap->def->parent);
+ parentsnap->def->current = false;
+ parentsnap = NULL;
+ }
+ }
+ }
+ vm->current_snapshot = parentsnap;
+ }
+
+ if (unlink(snapFile) < 0)
+ VIR_WARN("Failed to unlink %s", 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)
@@ -8278,75 +8464,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)
-{
- int fd = -1;
- char *newxml = NULL;
- int ret = -1;
- char *snapDir = NULL;
- char *snapFile = NULL;
- char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- virUUIDFormat(vm->def->uuid, uuidstr);
- newxml = virDomainSnapshotDefFormat(uuidstr, snapshot->def, 1);
- if (newxml == NULL) {
- virReportOOMError();
- return -1;
- }
-
- if (virAsprintf(&snapDir, "%s/%s", snapshotDir, vm->def->name)
< 0) {
- virReportOOMError();
- goto cleanup;
- }
- if (virFileMakePath(snapDir) < 0) {
- virReportSystemError(errno, _("cannot create snapshot directory
'%s'"),
- snapDir);
- goto cleanup;
- }
-
- if (virAsprintf(&snapFile, "%s/%s.xml", snapDir,
snapshot->def->name) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- fd = open(snapFile, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
- if (fd < 0) {
- qemuReportError(VIR_ERR_OPERATION_FAILED,
- _("failed to create snapshot file '%s'"),
snapFile);
- goto cleanup;
- }
- if (safewrite(fd, newxml, strlen(newxml)) != strlen(newxml)) {
- virReportSystemError(errno, _("Failed to write snapshot data to %s"),
- snapFile);
- goto cleanup;
- }
-
- ret = 0;
-
-cleanup:
- VIR_FREE(snapFile);
- VIR_FREE(snapDir);
- VIR_FREE(newxml);
- VIR_FORCE_CLOSE(fd);
- return ret;
-}
-
-
static int qemuDomainSnapshotIsAllowed(virDomainObjPtr vm)
{
int i;
@@ -8965,119 +9082,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 = NULL;
-
- 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 (virAsprintf(&snapFile, "%s/%s/%s.xml", driver->snapshotDir,
- vm->def->name, snap->def->name) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- if (snap == vm->current_snapshot) {
- if (snap->def->parent) {
- parentsnap = virDomainSnapshotFindByName(&vm->snapshots,
- snap->def->parent);
- if (!parentsnap) {
- VIR_WARN("missing parent snapshot matching name '%s'",
- snap->def->parent);
- } else {
- parentsnap->def->current = true;
- if (qemuDomainSnapshotWriteMetadata(vm, snap,
- driver->snapshotDir) < 0) {
- VIR_WARN("failed to set parent snapshot '%s' as
current",
- snap->def->parent);
- parentsnap->def->current = false;
- parentsnap = NULL;
- }
- }
- }
- vm->current_snapshot = parentsnap;
- }
-
- if (unlink(snapFile) < 0)
- VIR_WARN("Failed to unlink %s", 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;
const char *parent;
@@ -9155,7 +9159,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