
From: Peter Krempa <pkrempa@redhat.com> A qcow2 image which uses a data file and the 'data_file_raw' flag is effectively a raw image with the qcow2 wrapper used only to store metadata (block dirty bitmaps). Since the dirty bitmaps are always migrated using the migration stream it's technically not required that the qcow2 overlay itself is shared between the destinations. Management tools like Kubevirt want to migrate VMs which have a qcow2 overlay with the above config stored in a location that is not shared, but the data file itself is. This patch adds code that skips the validation of the overlay since it's not needed to ensure data consistency in that very specific case. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 2e52e73f48..7d87b3073b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1779,19 +1779,47 @@ qemuMigrationSrcCheckStorageSourceSafety(virStorageSource *src, static bool -qemuMigrationSrcIsSafeDisk(virDomainDiskDef *disk, +qemuMigrationSrcIsSafeDisk(virDomainObj *vm, + virDomainDiskDef *disk, virQEMUCaps *qemuCaps, - virQEMUDriverConfig *cfg) + virQEMUDriverConfig *cfg, + GHashTable **blockNamedNodeData) { bool unsafe_storage = false; bool requires_safe_cache = false; + bool skip_overlay_check = false; /* Disks without any source (i.e. floppies and CD-ROMs) OR readonly are safe. */ if (virStorageSourceIsEmpty(disk->src) || disk->src->readonly) return true; - if (qemuMigrationSrcCheckStorageSourceSafety(disk->src, cfg, &unsafe_storage, + if (disk->src->dataFileStore && + !virStorageSourceHasBacking(disk->src)) { + qemuBlockNamedNodeData *nodedata; + + /* As a special case if the topmost disk image is a qcow2 with a + * data_file and the 'data_file_raw' option enabled, the overlay itself + * contains no useful data. Kubevirt uses this setup for migrations + * where the qcow2 overlay is used for block dirty bitmaps which are + * migrated using migration stream and kubevirt thus pre-creates the + * overlay rather than putting it on shared storage */ + + if (!*blockNamedNodeData && + !(*blockNamedNodeData = qemuBlockGetNamedNodeData(vm, + VIR_ASYNC_JOB_MIGRATION_OUT))) + return false; + + if ((nodedata = virHashLookup(*blockNamedNodeData, + qemuBlockStorageSourceGetFormatNodename(disk->src)))) { + + if (nodedata->qcow2dataFileRaw) + skip_overlay_check = true; + } + } + + if (!skip_overlay_check && + qemuMigrationSrcCheckStorageSourceSafety(disk->src, cfg, &unsafe_storage, &requires_safe_cache) < 0) return false; @@ -1831,6 +1859,7 @@ qemuMigrationSrcIsSafe(virDomainObj *vm, { qemuDomainObjPrivate *priv = vm->privateData; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver); + g_autoptr(GHashTable) blockNamedNodeData = NULL; bool storagemigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC); size_t i; @@ -1843,7 +1872,7 @@ qemuMigrationSrcIsSafe(virDomainObj *vm, qemuMigrationAnyCopyDisk(disk, migrate_disks)) continue; - if (!qemuMigrationSrcIsSafeDisk(disk, priv->qemuCaps, cfg)) + if (!qemuMigrationSrcIsSafeDisk(vm, disk, priv->qemuCaps, cfg, &blockNamedNodeData)) return false; } -- 2.51.0