From 59b1408860f339e5e46f878cc0d2a9edc73b3df7 Mon Sep 17 00:00:00 2001 From: Nikolai Barybin Date: Wed, 20 Nov 2024 18:48:48 +0300 Subject: [PATCH] qemu: block: Add support for 'data-file' feature of qcow2 Add the block infrastructure for detecting and landling the data file for images and starting qemu with the configuration. Signed-off-by: Nikolai Barybin Signed-off-by: Peter Krempa Reviewed-by: Peter Krempa --- src/qemu/qemu_block.c | 20 ++++++++++++++++++++ src/qemu/qemu_command.c | 5 +++++ src/qemu/qemu_domain.c | 20 +++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 3c1305ec84..dab9ce4dc2 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1302,6 +1302,13 @@ qemuBlockStorageSourceGetFormatQcow2Props(virStorageSource *src, NULL) < 0) return -1; + if (src->dataFileStore) { + if (virJSONValueObjectAdd(&props, + "s:data-file", qemuBlockStorageSourceGetEffectiveNodename(src->dataFileStore), + NULL) < 0) + return -1; + } + return 0; } @@ -1859,6 +1866,13 @@ qemuBlockStorageSourceChainDetachPrepareBlockdev(virStorageSource *src) return NULL; VIR_APPEND_ELEMENT(data->srcdata, data->nsrcdata, backend); + + if (n->dataFileStore) { + if (!(backend = qemuBlockStorageSourceDetachPrepare(n->dataFileStore))) + return NULL; + + VIR_APPEND_ELEMENT(data->srcdata, data->nsrcdata, backend); + } } return g_steal_pointer(&data); @@ -2589,6 +2603,12 @@ qemuBlockStorageSourceCreateFormat(virDomainObj *vm, if (qemuBlockStorageSourceIsRaw(src)) return 0; + if (src->dataFileStore) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("creation of storage images with feature is not supported")); + return -1; + } + if (qemuBlockStorageSourceCreateGetFormatProps(src, backingStore, &createformatprops) < 0) return -1; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f4430275dc..98211f4cd6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -11018,6 +11018,11 @@ qemuBuildStorageSourceChainAttachPrepareBlockdev(virStorageSource *top) if (qemuBuildStorageSourceChainAttachPrepareBlockdevOne(data, n, n->backingStore) < 0) return NULL; + + /* the dataStore must not have a backing image so we pass NULL */ + if (n->dataFileStore && + qemuBuildStorageSourceChainAttachPrepareBlockdevOne(data, n->dataFileStore, NULL) < 0) + return NULL; } return g_steal_pointer(&data); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 2e3f33cc9f..d28ff0cd22 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6158,6 +6158,7 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver, virStorageSource *disksrc) { g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + bool hadDataStore = false; virStorageSource *src; /* iterator for the backing chain declared in XML */ virStorageSource *n; /* iterator for the backing chain detected from disk */ uid_t uid; @@ -6237,14 +6238,27 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver, qemuDomainGetImageIds(cfg, vm->def, src, disksrc, &uid, &gid); + hadDataStore = !!src->dataFileStore; + if (virStorageSourceGetMetadata(src, uid, gid, QEMU_DOMAIN_STORAGE_SOURCE_CHAIN_MAX_DEPTH, true) < 0) return -1; + /* As we perform image properties detection on the last member of the + * backing chain we need to also consider the data store part of the current + * image */ + if (src->dataFileStore && !hadDataStore && + qemuDomainPrepareStorageSource(src->dataFileStore, vm, disk, cfg) < 0) + return -1; + for (n = src->backingStore; virStorageSourceIsBacking(n); n = n->backingStore) { if (qemuDomainPrepareStorageSource(n, vm, disk, cfg) < 0) return -1; + + if (n->dataFileStore && + qemuDomainPrepareStorageSource(n->dataFileStore, vm, disk, cfg) < 0) + return -1; } if (qemuDomainStorageSourceValidateDepth(disksrc, 0, disk->dst) < 0) @@ -9484,7 +9498,7 @@ qemuDomainPrepareDiskSourceData(virDomainDiskDef *disk, return; /* transfer properties valid only for the top level image */ - if (src == disk->src) + if (src == disk->src || src == disk->src->dataFileStore) src->detect_zeroes = disk->detect_zeroes; /* transfer properties valid for the full chain */ @@ -9713,6 +9727,10 @@ qemuDomainPrepareDiskSourceBlockdev(virDomainDiskDef *disk, for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { if (qemuDomainPrepareStorageSourceBlockdev(disk, n, priv, cfg) < 0) return -1; + + if (n->dataFileStore && + qemuDomainPrepareStorageSourceBlockdev(disk, n->dataFileStore, priv, cfg) < 0) + return -1; } return 0;