mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-26 07:36:19 +00:00
snapshot: affect persistent xml after disk snapshot
For external snapshots to be useful on persistent domains, we must alter the persistent definition alongside the running definition. Thanks to the possibility of disk hotplug as well as of edits that only affect the persistent xml, we can't assume that vm->def and vm->newDef have the same disk at the same index, so we can only update the persistent copy if the device destination matches up. * src/qemu/qemu_driver.c (qemuDomainSnapshotCreateDiskActive) (qemuDomainSnapshotCreateSingleDiskActive): Also affect newDef, if present.
This commit is contained in:
parent
1726a736fb
commit
2895905a0b
@ -9107,12 +9107,15 @@ static int
|
|||||||
qemuDomainSnapshotCreateSingleDiskActive(struct qemud_driver *driver,
|
qemuDomainSnapshotCreateSingleDiskActive(struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainSnapshotDiskDefPtr snap,
|
virDomainSnapshotDiskDefPtr snap,
|
||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk,
|
||||||
|
virDomainDiskDefPtr persistDisk)
|
||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
char *source = NULL;
|
char *source = NULL;
|
||||||
char *driverType = NULL;
|
char *driverType = NULL;
|
||||||
|
char *persistSource = NULL;
|
||||||
|
char *persistDriverType = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
char *origsrc = NULL;
|
char *origsrc = NULL;
|
||||||
@ -9128,7 +9131,11 @@ qemuDomainSnapshotCreateSingleDiskActive(struct qemud_driver *driver,
|
|||||||
if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0 ||
|
if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0 ||
|
||||||
!(source = strdup(snap->file)) ||
|
!(source = strdup(snap->file)) ||
|
||||||
(STRNEQ_NULLABLE(disk->driverType, "qcow2") &&
|
(STRNEQ_NULLABLE(disk->driverType, "qcow2") &&
|
||||||
!(driverType = strdup("qcow2")))) {
|
!(driverType = strdup("qcow2"))) ||
|
||||||
|
(persistDisk &&
|
||||||
|
(!(persistSource = strdup(source)) ||
|
||||||
|
(STRNEQ_NULLABLE(persistDisk->driverType, "qcow2") &&
|
||||||
|
!(persistDriverType = strdup("qcow2")))))) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -9176,9 +9183,16 @@ qemuDomainSnapshotCreateSingleDiskActive(struct qemud_driver *driver,
|
|||||||
disk->driverType = driverType;
|
disk->driverType = driverType;
|
||||||
driverType = NULL;
|
driverType = NULL;
|
||||||
}
|
}
|
||||||
|
if (persistDisk) {
|
||||||
/* XXX Do we also need to update vm->newDef if there are pending
|
VIR_FREE(persistDisk->src);
|
||||||
* configuration changes awaiting the next boot? */
|
persistDisk->src = persistSource;
|
||||||
|
persistSource = NULL;
|
||||||
|
if (persistDriverType) {
|
||||||
|
VIR_FREE(persistDisk->driverType);
|
||||||
|
persistDisk->driverType = persistDriverType;
|
||||||
|
persistDriverType = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (origsrc) {
|
if (origsrc) {
|
||||||
@ -9190,6 +9204,8 @@ cleanup:
|
|||||||
VIR_FREE(device);
|
VIR_FREE(device);
|
||||||
VIR_FREE(source);
|
VIR_FREE(source);
|
||||||
VIR_FREE(driverType);
|
VIR_FREE(driverType);
|
||||||
|
VIR_FREE(persistSource);
|
||||||
|
VIR_FREE(persistDriverType);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9205,6 +9221,7 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
|
|||||||
bool resume = false;
|
bool resume = false;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int i;
|
int i;
|
||||||
|
bool persist = false;
|
||||||
|
|
||||||
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
|
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -9235,12 +9252,24 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
|
|||||||
* SNAPSHOT_EXTERNAL with a valid file name and qcow2 format. */
|
* SNAPSHOT_EXTERNAL with a valid file name and qcow2 format. */
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
for (i = 0; i < snap->def->ndisks; i++) {
|
for (i = 0; i < snap->def->ndisks; i++) {
|
||||||
|
virDomainDiskDefPtr persistDisk = NULL;
|
||||||
|
|
||||||
if (snap->def->disks[i].snapshot == VIR_DOMAIN_DISK_SNAPSHOT_NO)
|
if (snap->def->disks[i].snapshot == VIR_DOMAIN_DISK_SNAPSHOT_NO)
|
||||||
continue;
|
continue;
|
||||||
|
if (vm->newDef) {
|
||||||
|
int indx = virDomainDiskIndexByName(vm->newDef,
|
||||||
|
vm->def->disks[i]->dst,
|
||||||
|
false);
|
||||||
|
if (indx >= 0) {
|
||||||
|
persistDisk = vm->newDef->disks[indx];
|
||||||
|
persist = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
|
ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
|
||||||
&snap->def->disks[i],
|
&snap->def->disks[i],
|
||||||
vm->def->disks[i]);
|
vm->def->disks[i],
|
||||||
|
persistDisk);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -9275,7 +9304,9 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vm) {
|
if (vm) {
|
||||||
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
|
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0 ||
|
||||||
|
(persist &&
|
||||||
|
virDomainSaveConfig(driver->configDir, vm->newDef) < 0))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
if (qemuDomainObjEndJob(driver, vm) == 0) {
|
if (qemuDomainObjEndJob(driver, vm) == 0) {
|
||||||
/* Only possible if a transient vm quit while our locks were down,
|
/* Only possible if a transient vm quit while our locks were down,
|
||||||
|
Loading…
Reference in New Issue
Block a user