return 0;
}
-static int qemuDomainSnapshotSetActive(virDomainObjPtr vm,
- char *snapshotDir);
-static int qemuDomainSnapshotSetInactive(virDomainObjPtr vm,
- char *snapshotDir);
+static int qemuDomainSnapshotSetCurrentActive(virDomainObjPtr vm,
+ char *snapshotDir);
+static int qemuDomainSnapshotSetCurrentInactive(virDomainObjPtr vm,
+ char *snapshotDir);
#define START_POSTFIX ": starting up\n"
vm->current_snapshot, vmop)))
goto cleanup;
- if (qemuDomainSnapshotSetInactive(vm, driver->snapshotDir) < 0)
+ if (qemuDomainSnapshotSetCurrentInactive(vm, driver->snapshotDir) < 0)
goto cleanup;
/* now that we know it is about to start call the hook if present */
return ret;
}
-static int qemuDomainSnapshotWriteSnapshotMetadata(virDomainObjPtr vm,
- char *snapshotDir)
+static int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
+ virDomainSnapshotObjPtr snapshot,
+ char *snapshotDir)
{
int fd = -1;
char *newxml = NULL;
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(vm->def->uuid, uuidstr);
- newxml = virDomainSnapshotDefFormat(uuidstr, vm->current_snapshot->def, 1);
+ newxml = virDomainSnapshotDefFormat(uuidstr, snapshot->def, 1);
if (newxml == NULL) {
virReportOOMError();
return -1;
goto cleanup;
}
- if (virAsprintf(&snapFile, "%s/%s.xml", snapDir,
- vm->current_snapshot->def->name) < 0) {
+ if (virAsprintf(&snapFile, "%s/%s.xml", snapDir, snapshot->def->name) < 0) {
virReportOOMError();
goto cleanup;
}
return ret;
}
-static int qemuDomainSnapshotSetActive(virDomainObjPtr vm,
- char *snapshotDir)
+static int qemuDomainSnapshotSetCurrentActive(virDomainObjPtr vm,
+ char *snapshotDir)
{
if (vm->current_snapshot) {
vm->current_snapshot->def->active = 1;
- return qemuDomainSnapshotWriteSnapshotMetadata(vm, snapshotDir);
+ return qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
+ snapshotDir);
}
return 0;
}
-static int qemuDomainSnapshotSetInactive(virDomainObjPtr vm,
- char *snapshotDir)
+static int qemuDomainSnapshotSetCurrentInactive(virDomainObjPtr vm,
+ char *snapshotDir)
{
if (vm->current_snapshot) {
vm->current_snapshot->def->active = 0;
- return qemuDomainSnapshotWriteSnapshotMetadata(vm, snapshotDir);
+ return qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
+ snapshotDir);
}
return 0;
/* Now we set the new current_snapshot for the domain */
vm->current_snapshot = snap;
- if (qemuDomainSnapshotWriteSnapshotMetadata(vm, driver->snapshotDir) < 0)
- /* qemuDomainSnapshotWriteSnapshotMetadata set the error */
+ if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
+ driver->snapshotDir) < 0)
+ /* qemuDomainSnapshotWriteMetadata set the error */
goto cleanup;
snapshot = virGetDomainSnapshot(domain, snap->def->name);
goto endjob;
}
else {
- if (qemuDomainSnapshotSetActive(vm, driver->snapshotDir) < 0)
+ if (qemuDomainSnapshotSetCurrentActive(vm, driver->snapshotDir) < 0)
goto endjob;
rc = qemudStartVMDaemon(snapshot->domain->conn, driver, vm, NULL,
false, -1, NULL, VIR_VM_OP_CREATE);
qemuDomainStartAudit(vm, "from-snapshot", rc >= 0);
- if (qemuDomainSnapshotSetInactive(vm, driver->snapshotDir) < 0)
+ if (qemuDomainSnapshotSetCurrentInactive(vm, driver->snapshotDir) < 0)
goto endjob;
if (rc < 0)
goto endjob;
}
}
- if (qemuDomainSnapshotSetActive(vm, driver->snapshotDir) < 0)
+ if (qemuDomainSnapshotSetCurrentActive(vm, driver->snapshotDir) < 0)
goto endjob;
}
}
}
+struct snap_reparent {
+ struct qemud_driver *driver;
+ virDomainSnapshotObjPtr snap;
+ virDomainObjPtr vm;
+ int err;
+};
+
+static void
+qemuDomainSnapshotReparentChildren(void *payload,
+ const char *name ATTRIBUTE_UNUSED,
+ void *data)
+{
+ virDomainSnapshotObjPtr snap = payload;
+ struct snap_reparent *rep = data;
+
+ if (rep->err < 0) {
+ return;
+ }
+
+ if (snap->def->parent && STREQ(snap->def->parent, rep->snap->def->name)) {
+ VIR_FREE(snap->def->parent);
+
+ if (rep->snap->def->parent != NULL) {
+ snap->def->parent = strdup(rep->snap->def->parent);
+
+ if (snap->def->parent == NULL) {
+ virReportOOMError();
+ rep->err = -1;
+ return;
+ }
+ }
+
+ rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap,
+ rep->driver->snapshotDir);
+ }
+}
+
static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
unsigned int flags)
{
virDomainSnapshotObjPtr snap = NULL;
char uuidstr[VIR_UUID_STRING_BUFLEN];
struct snap_remove rem;
+ struct snap_reparent rep;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, -1);
&rem);
if (rem.err < 0)
goto endjob;
+ } else {
+ rep.driver = driver;
+ rep.snap = snap;
+ rep.vm = vm;
+ rep.err = 0;
+ virHashForEach(vm->snapshots.objs, qemuDomainSnapshotReparentChildren,
+ &rep);
+ if (rep.err < 0)
+ goto endjob;
}
ret = qemuDomainSnapshotDiscard(driver, vm, snap);