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);
};
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
*/ /* 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,
* 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",
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);
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);