]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: block: Add support for 'data-file' feature of qcow2
authorNikolai Barybin <nikolai.barybin@virtuozzo.com>
Wed, 20 Nov 2024 15:48:48 +0000 (18:48 +0300)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 25 Nov 2024 21:31:18 +0000 (22:31 +0100)
Add the block infrastructure for detecting and landling the data file
for images and starting qemu with the configuration.

Signed-off-by: Nikolai Barybin <nikolai.barybin@virtuozzo.com>
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
src/qemu/qemu_block.c
src/qemu/qemu_command.c
src/qemu/qemu_domain.c

index 3c1305ec84ac5de876e0cd87e7eb242334d42fd6..dab9ce4dc2cd6f7fe3e2869dca211c588ec69f83 100644 (file)
@@ -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 <dataStore> feature is not supported"));
+        return -1;
+    }
+
     if (qemuBlockStorageSourceCreateGetFormatProps(src, backingStore,
                                                    &createformatprops) < 0)
         return -1;
index f4430275dc425a04aed55f8b274586921abad3f8..98211f4cd665a84da8fef2d4977ea1b126c43a60 100644 (file)
@@ -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);
index 2e3f33cc9f29bca5626bae6a3424fc5b1412961c..d28ff0cd2207868f8359b3c3598f8da8711d3b44 100644 (file)
@@ -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;