bool created; /* @src was created by the snapshot code */
bool prepared; /* @src was prepared using qemuDomainDiskChainElementPrepare */
virDomainDiskDefPtr disk;
+ char *relPath; /* relative path component to fill into original disk */
virStorageSourcePtr persistsrc;
virDomainDiskDefPtr persistdisk;
virStorageSourceFree(data[i].src);
}
virStorageSourceFree(data[i].persistsrc);
+ VIR_FREE(data[i].relPath);
}
VIR_FREE(data);
static qemuDomainSnapshotDiskDataPtr
qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr driver,
virDomainObjPtr vm,
- virDomainSnapshotObjPtr snap)
+ virDomainSnapshotObjPtr snap,
+ bool reuse)
{
size_t i;
qemuDomainSnapshotDiskDataPtr ret;
qemuDomainSnapshotDiskDataPtr dd;
+ char *backingStoreStr;
if (VIR_ALLOC_N(ret, snap->def->ndisks) < 0)
return NULL;
dd->initialized = true;
+ /* relative backing store paths need to be updated so that relative
+ * block commit still works */
+ if (reuse &&
+ (backingStoreStr = virStorageFileGetBackingStoreStr(dd->src))) {
+ if (virStorageIsRelative(backingStoreStr))
+ VIR_STEAL_PTR(dd->relPath, backingStoreStr);
+ else
+ VIR_FREE(backingStoreStr);
+ }
+
/* Note that it's unsafe to assume that the disks in the persistent
* definition match up with the disks in the live definition just by
* checking that the target name is the same. We've done that
if (dd->initialized)
virStorageFileDeinit(dd->src);
+ VIR_STEAL_PTR(dd->disk->src->relPath, dd->relPath);
VIR_STEAL_PTR(dd->src->backingStore, dd->disk->src);
VIR_STEAL_PTR(dd->disk->src, dd->src);
/* prepare a list of objects to use in the vm definition so that we don't
* have to roll back later */
- if (!(diskdata = qemuDomainSnapshotDiskDataCollect(driver, vm, snap)))
+ if (!(diskdata = qemuDomainSnapshotDiskDataCollect(driver, vm, snap, reuse)))
goto cleanup;
cfg = virQEMUDriverGetConfig(driver);