]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
storage_file_probe: Add image specific callback taking the whole virStorageSource
authorPeter Krempa <pkrempa@redhat.com>
Wed, 28 May 2025 13:59:33 +0000 (15:59 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 3 Jun 2025 11:11:03 +0000 (13:11 +0200)
The callbacks getting just some fields are not flexible and in some
cases cause the metadata to be probed multiple times.

Add a callback that will pass the whole virStorageSource struct being
probed so that the code can be written more efficiently.

As a first step we add just the callback. The specific format helpers
will be refactored and subsequently all the other callbacks will be
removed.

To simplify the refactors that will convert all the code to the new
callbacks the new callback is placed first but the calls to cleanup
previous metadata are moved before it. They'll be removed once the
refactors are complete together with the other callbacks.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/storage_file/storage_file_probe.c

index f8857fa9347744db578892ba6e30fc31aadf263a..29837792e4e366638617a7dbacb02b05cb21291f 100644 (file)
@@ -96,6 +96,9 @@ struct FileTypeInfo {
     int (*getDataFile)(char **res, virBitmap *features, char *buf, size_t buf_size);
     int (*getFeatures)(virBitmap **features, int format,
                        char *buf, ssize_t len);
+    int (*getImageSpecific)(virStorageSource *meta,
+                            const char *buf,
+                            size_t buf_size);
 };
 
 
@@ -241,18 +244,18 @@ static struct FileEncryptionInfo const qcow2EncryptionInfo[] = {
 
 static struct FileTypeInfo const fileTypeInfo[] = {
     [VIR_STORAGE_FILE_NONE] = { 0, NULL, LV_LITTLE_ENDIAN,
-                                -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
+                                -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_RAW] = { 0, NULL, LV_LITTLE_ENDIAN,
                                -1, 0, {0}, 0, 0, 0,
                                luksEncryptionInfo,
-                               NULL, NULL, NULL, NULL },
+                               NULL, NULL, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_DIR] = { 0, NULL, LV_LITTLE_ENDIAN,
-                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
+                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_BOCHS] = {
         /*"Bochs Virtual HD Image", */ /* Untested */
         0, NULL,
         LV_LITTLE_ENDIAN, 64, 4, {0x20000},
-        32+16+16+4+4+4+4+4, 8, 1, NULL, NULL, NULL, NULL, NULL
+        32+16+16+4+4+4+4+4, 8, 1, NULL, NULL, NULL, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_CLOOP] = {
         /* #!/bin/sh
@@ -261,7 +264,7 @@ static struct FileTypeInfo const fileTypeInfo[] = {
         */ /* Untested */
         0, NULL,
         LV_LITTLE_ENDIAN, -1, 0, {0},
-        -1, 0, 0, NULL, NULL, NULL, NULL, NULL
+        -1, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_DMG] = {
         /* XXX QEMU says there's no magic for dmg,
@@ -269,45 +272,45 @@ static struct FileTypeInfo const fileTypeInfo[] = {
          * would have to match) but then disables that check. */
         0, NULL,
         0, -1, 0, {0},
-        -1, 0, 0, NULL, NULL, NULL, NULL, NULL
+        -1, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_ISO] = {
         32769, "CD001",
         LV_LITTLE_ENDIAN, -2, 0, {0},
-        -1, 0, 0, NULL, NULL, NULL, NULL, NULL
+        -1, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_VPC] = {
         0, "conectix",
         LV_BIG_ENDIAN, 12, 4, {0x10000},
-        8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, NULL, NULL, NULL, NULL, NULL
+        8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, NULL, NULL, NULL, NULL, NULL, NULL
     },
     /* TODO: add getBackingStore function */
     [VIR_STORAGE_FILE_VDI] = {
         64, "\x7f\x10\xda\xbe",
         LV_LITTLE_ENDIAN, 68, 4, {0x00010001},
-        64 + 5 * 4 + 256 + 7 * 4, 8, 1, NULL, NULL, NULL, NULL, NULL},
+        64 + 5 * 4 + 256 + 7 * 4, 8, 1, NULL, NULL, NULL, NULL, NULL, NULL},
 
     /* Not direct file formats, but used for various drivers */
     [VIR_STORAGE_FILE_FAT] = { 0, NULL, LV_LITTLE_ENDIAN,
-                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
+                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_VHD] = { 0, NULL, LV_LITTLE_ENDIAN,
-                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
+                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_PLOOP] = { 0, "WithouFreSpacExt", LV_LITTLE_ENDIAN,
                                  -2, 0, {0}, PLOOP_IMAGE_SIZE_OFFSET, 8,
-                                 PLOOP_SIZE_MULTIPLIER, NULL, NULL, NULL, NULL, NULL },
+                                 PLOOP_SIZE_MULTIPLIER, NULL, NULL, NULL, NULL, NULL, NULL },
 
     /* All formats with a backing store probe below here */
     [VIR_STORAGE_FILE_COW] = {
         0, "OOOM",
         LV_BIG_ENDIAN, 4, 4, {2},
-        4+4+1024+4, 8, 1, NULL, NULL, cowGetBackingStore, NULL, NULL
+        4+4+1024+4, 8, 1, NULL, NULL, cowGetBackingStore, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_QCOW] = {
         0, "QFI",
         LV_BIG_ENDIAN, 4, 4, {1},
         QCOWX_HDR_IMAGE_SIZE, 8, 1,
         qcow1EncryptionInfo,
-        NULL, qcowXGetBackingStore, NULL, NULL
+        NULL, qcowXGetBackingStore, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_QCOW2] = {
         0, "QFI",
@@ -317,18 +320,19 @@ static struct FileTypeInfo const fileTypeInfo[] = {
         qcow2GetClusterSize,
         qcowXGetBackingStore,
         qcow2GetDataFile,
-        qcow2GetFeatures
+        qcow2GetFeatures,
+        NULL
     },
     [VIR_STORAGE_FILE_QED] = {
         /* https://wiki.qemu.org/Features/QED */
         0, "QED",
         LV_LITTLE_ENDIAN, -2, 0, {0},
-        QED_HDR_IMAGE_SIZE, 8, 1, NULL, NULL, qedGetBackingStore, NULL, NULL
+        QED_HDR_IMAGE_SIZE, 8, 1, NULL, NULL, qedGetBackingStore, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_VMDK] = {
         0, "KDMV",
         LV_LITTLE_ENDIAN, 4, 4, {1, 2, 3},
-        4+4+4, 8, 512, NULL, NULL, vmdk4GetBackingStore, NULL, NULL
+        4+4+4, 8, 512, NULL, NULL, vmdk4GetBackingStore, NULL, NULL, NULL
     },
 };
 G_STATIC_ASSERT(G_N_ELEMENTS(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
@@ -991,22 +995,27 @@ virStorageFileProbeGetMetadata(virStorageSource *meta,
         meta->capacity *= fileTypeInfo[meta->format].sizeMultiplier;
     }
 
+    VIR_FREE(meta->backingStoreRaw);
+    g_clear_pointer(&meta->features, virBitmapFree);
+    VIR_FREE(meta->dataFileRaw);
+
+    if (fileTypeInfo[meta->format].getImageSpecific &&
+        fileTypeInfo[meta->format].getImageSpecific(meta, buf, len) < 0)
+        return -1;
+
     if (fileTypeInfo[meta->format].getClusterSize != NULL)
         meta->clusterSize = fileTypeInfo[meta->format].getClusterSize(buf, len);
 
-    VIR_FREE(meta->backingStoreRaw);
     if (fileTypeInfo[meta->format].getBackingStore != NULL) {
         fileTypeInfo[meta->format].getBackingStore(&meta->backingStoreRaw,
                                                    &format, buf, len);
         meta->backingStoreRawFormat = format;
     }
 
-    g_clear_pointer(&meta->features, virBitmapFree);
     if (fileTypeInfo[meta->format].getFeatures != NULL &&
         fileTypeInfo[meta->format].getFeatures(&meta->features, meta->format, buf, len) < 0)
         return -1;
 
-    VIR_FREE(meta->dataFileRaw);
     if (fileTypeInfo[meta->format].getDataFile != NULL) {
         fileTypeInfo[meta->format].getDataFile(&meta->dataFileRaw, meta->features,
                                                buf, len);