mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 23:25:24 +00:00
qemu: backup: Fix handling of backing store for backup target images
We always tried to install backing store for the image even if it didn't make sense, e.g. for a full backup into a raw image. Additionally we didn't record the backing file into the qcow2 metadata so the image itself contained the diff of data but reading from it would be incomplete as it depends on the backing image. This patch fixes both issues by carefully installing the correct backing file when appropriate and also recording it into the metadata when creating the image. https://bugzilla.redhat.com/show_bug.cgi?id=1813310 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
818652619d
commit
4aea6f42fe
@ -105,6 +105,8 @@ struct qemuBackupDiskData {
|
|||||||
virDomainDiskDefPtr domdisk;
|
virDomainDiskDefPtr domdisk;
|
||||||
qemuBlockJobDataPtr blockjob;
|
qemuBlockJobDataPtr blockjob;
|
||||||
virStorageSourcePtr store;
|
virStorageSourcePtr store;
|
||||||
|
virStorageSourcePtr terminator;
|
||||||
|
virStorageSourcePtr backingStore;
|
||||||
char *incrementalBitmap;
|
char *incrementalBitmap;
|
||||||
qemuBlockStorageSourceChainDataPtr crdata;
|
qemuBlockStorageSourceChainDataPtr crdata;
|
||||||
bool labelled;
|
bool labelled;
|
||||||
@ -146,6 +148,7 @@ qemuBackupDiskDataCleanupOne(virDomainObjPtr vm,
|
|||||||
qemuBlockJobStartupFinalize(vm, dd->blockjob);
|
qemuBlockJobStartupFinalize(vm, dd->blockjob);
|
||||||
|
|
||||||
qemuBlockStorageSourceChainDataFree(dd->crdata);
|
qemuBlockStorageSourceChainDataFree(dd->crdata);
|
||||||
|
virObjectUnref(dd->terminator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -295,6 +298,7 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
|
|||||||
virDomainBackupDiskDefPtr backupdisk,
|
virDomainBackupDiskDefPtr backupdisk,
|
||||||
struct qemuBackupDiskData *dd,
|
struct qemuBackupDiskData *dd,
|
||||||
virJSONValuePtr actions,
|
virJSONValuePtr actions,
|
||||||
|
bool pull,
|
||||||
virDomainMomentDefPtr *incremental,
|
virDomainMomentDefPtr *incremental,
|
||||||
virHashTablePtr blockNamedNodeData,
|
virHashTablePtr blockNamedNodeData,
|
||||||
virQEMUDriverConfigPtr cfg)
|
virQEMUDriverConfigPtr cfg)
|
||||||
@ -314,6 +318,19 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
|
|||||||
if (!dd->store->format)
|
if (!dd->store->format)
|
||||||
dd->store->format = VIR_STORAGE_FILE_QCOW2;
|
dd->store->format = VIR_STORAGE_FILE_QCOW2;
|
||||||
|
|
||||||
|
/* calculate backing store to use:
|
||||||
|
* push mode:
|
||||||
|
* full backups: no backing store
|
||||||
|
* incremental: original disk if format supports backing store
|
||||||
|
* pull mode:
|
||||||
|
* both: original disk
|
||||||
|
*/
|
||||||
|
if (pull || (incremental && dd->store->format >= VIR_STORAGE_FILE_BACKING)) {
|
||||||
|
dd->backingStore = dd->domdisk->src;
|
||||||
|
} else {
|
||||||
|
dd->backingStore = dd->terminator = virStorageSourceNew();
|
||||||
|
}
|
||||||
|
|
||||||
if (qemuDomainStorageFileInit(priv->driver, vm, dd->store, dd->domdisk->src) < 0)
|
if (qemuDomainStorageFileInit(priv->driver, vm, dd->store, dd->domdisk->src) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -337,7 +354,7 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
|
|||||||
|
|
||||||
/* use original disk as backing to prevent opening the backing chain */
|
/* use original disk as backing to prevent opening the backing chain */
|
||||||
if (!(dd->crdata = qemuBuildStorageSourceChainAttachPrepareBlockdevTop(dd->store,
|
if (!(dd->crdata = qemuBuildStorageSourceChainAttachPrepareBlockdevTop(dd->store,
|
||||||
dd->domdisk->src,
|
dd->backingStore,
|
||||||
priv->qemuCaps)))
|
priv->qemuCaps)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -398,6 +415,7 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm,
|
|||||||
struct qemuBackupDiskData *disks = NULL;
|
struct qemuBackupDiskData *disks = NULL;
|
||||||
ssize_t ndisks = 0;
|
ssize_t ndisks = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
bool pull = def->type == VIR_DOMAIN_BACKUP_TYPE_PULL;
|
||||||
|
|
||||||
disks = g_new0(struct qemuBackupDiskData, def->ndisks);
|
disks = g_new0(struct qemuBackupDiskData, def->ndisks);
|
||||||
|
|
||||||
@ -410,12 +428,12 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm,
|
|||||||
|
|
||||||
ndisks++;
|
ndisks++;
|
||||||
|
|
||||||
if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions,
|
if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions, pull,
|
||||||
incremental, blockNamedNodeData,
|
incremental, blockNamedNodeData,
|
||||||
cfg) < 0)
|
cfg) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (def->type == VIR_DOMAIN_BACKUP_TYPE_PULL) {
|
if (pull) {
|
||||||
if (qemuBackupDiskPrepareDataOnePull(actions, dd) < 0)
|
if (qemuBackupDiskPrepareDataOnePull(actions, dd) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
@ -480,7 +498,7 @@ qemuBackupDiskPrepareOneStorage(virDomainObjPtr vm,
|
|||||||
dd->store, dd->domdisk->src) < 0)
|
dd->store, dd->domdisk->src) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (qemuBlockStorageSourceCreate(vm, dd->store, NULL, NULL,
|
if (qemuBlockStorageSourceCreate(vm, dd->store, dd->backingStore, NULL,
|
||||||
dd->crdata->srcdata[0],
|
dd->crdata->srcdata[0],
|
||||||
QEMU_ASYNC_JOB_BACKUP) < 0)
|
QEMU_ASYNC_JOB_BACKUP) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user