From: Peter Krempa <pkrempa(a)redhat.com>
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(a)redhat.com>
---
src/storage_file/storage_file_probe.c | 49 ++++++++++++++++-----------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/src/storage_file/storage_file_probe.c
b/src/storage_file/storage_file_probe.c
index f8857fa934..29837792e4 100644
--- a/src/storage_file/storage_file_probe.c
+++ b/src/storage_file/storage_file_probe.c
@@ -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);
--
2.49.0