mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
storage file: add qcow2 data-file path parsing from header
In qcow2 header data file is represented by incompitible feature bit and its path is saved to header extension table. Thus, we implement here the logic similar to backing file probing. Signed-off-by: Nikolai Barybin <nikolai.barybin@virtuozzo.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
8799818036
commit
63481eca80
@ -69,6 +69,7 @@ VIR_ENUM_IMPL(virStorageFileFeature,
|
|||||||
VIR_STORAGE_FILE_FEATURE_LAST,
|
VIR_STORAGE_FILE_FEATURE_LAST,
|
||||||
"lazy_refcounts",
|
"lazy_refcounts",
|
||||||
"extended_l2",
|
"extended_l2",
|
||||||
|
"data_file",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ VIR_ENUM_DECL(virStorageFileFormat);
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS = 0,
|
VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS = 0,
|
||||||
VIR_STORAGE_FILE_FEATURE_EXTENDED_L2,
|
VIR_STORAGE_FILE_FEATURE_EXTENDED_L2,
|
||||||
|
VIR_STORAGE_FILE_FEATURE_DATA_FILE,
|
||||||
|
|
||||||
VIR_STORAGE_FILE_FEATURE_LAST
|
VIR_STORAGE_FILE_FEATURE_LAST
|
||||||
} virStorageFileFeature;
|
} virStorageFileFeature;
|
||||||
|
@ -106,6 +106,7 @@ qcow2GetClusterSize(const char *buf,
|
|||||||
size_t buf_size);
|
size_t buf_size);
|
||||||
static int qcowXGetBackingStore(char **, int *,
|
static int qcowXGetBackingStore(char **, int *,
|
||||||
const char *, size_t);
|
const char *, size_t);
|
||||||
|
static int qcow2GetDataFile(char **, virBitmap *, char *, size_t);
|
||||||
static int qcow2GetFeatures(virBitmap **features, int format,
|
static int qcow2GetFeatures(virBitmap **features, int format,
|
||||||
char *buf, ssize_t len);
|
char *buf, ssize_t len);
|
||||||
static int vmdk4GetBackingStore(char **, int *,
|
static int vmdk4GetBackingStore(char **, int *,
|
||||||
@ -127,6 +128,7 @@ qedGetBackingStore(char **, int *, const char *, size_t);
|
|||||||
|
|
||||||
#define QCOW2_HDR_EXTENSION_END 0
|
#define QCOW2_HDR_EXTENSION_END 0
|
||||||
#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
|
#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
|
||||||
|
#define QCOW2_HDR_EXTENSION_DATA_FILE_NAME 0x44415441
|
||||||
|
|
||||||
#define QCOW2v3_HDR_FEATURES_INCOMPATIBLE (QCOW2_HDR_TOTAL_SIZE)
|
#define QCOW2v3_HDR_FEATURES_INCOMPATIBLE (QCOW2_HDR_TOTAL_SIZE)
|
||||||
#define QCOW2v3_HDR_FEATURES_COMPATIBLE (QCOW2v3_HDR_FEATURES_INCOMPATIBLE+8)
|
#define QCOW2v3_HDR_FEATURES_COMPATIBLE (QCOW2v3_HDR_FEATURES_INCOMPATIBLE+8)
|
||||||
@ -314,7 +316,7 @@ static struct FileTypeInfo const fileTypeInfo[] = {
|
|||||||
qcow2EncryptionInfo,
|
qcow2EncryptionInfo,
|
||||||
qcow2GetClusterSize,
|
qcow2GetClusterSize,
|
||||||
qcowXGetBackingStore,
|
qcowXGetBackingStore,
|
||||||
NULL,
|
qcow2GetDataFile,
|
||||||
qcow2GetFeatures
|
qcow2GetFeatures
|
||||||
},
|
},
|
||||||
[VIR_STORAGE_FILE_QED] = {
|
[VIR_STORAGE_FILE_QED] = {
|
||||||
@ -361,7 +363,7 @@ enum qcow2IncompatibleFeature {
|
|||||||
static const virStorageFileFeature qcow2IncompatibleFeatureArray[] = {
|
static const virStorageFileFeature qcow2IncompatibleFeatureArray[] = {
|
||||||
VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_DIRTY */
|
VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_DIRTY */
|
||||||
VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_CORRUPT */
|
VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_CORRUPT */
|
||||||
VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_DATA_FILE */
|
VIR_STORAGE_FILE_FEATURE_DATA_FILE, /* QCOW2_INCOMPATIBLE_FEATURE_DATA_FILE */
|
||||||
VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_COMPRESSION */
|
VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_COMPRESSION */
|
||||||
VIR_STORAGE_FILE_FEATURE_EXTENDED_L2, /* QCOW2_INCOMPATIBLE_FEATURE_EXTL2 */
|
VIR_STORAGE_FILE_FEATURE_EXTENDED_L2, /* QCOW2_INCOMPATIBLE_FEATURE_EXTL2 */
|
||||||
};
|
};
|
||||||
@ -393,7 +395,8 @@ cowGetBackingStore(char **res,
|
|||||||
static int
|
static int
|
||||||
qcow2GetExtensions(const char *buf,
|
qcow2GetExtensions(const char *buf,
|
||||||
size_t buf_size,
|
size_t buf_size,
|
||||||
int *backingFormat)
|
int *backingFormat,
|
||||||
|
char **dataFilePath)
|
||||||
{
|
{
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t extension_start;
|
size_t extension_start;
|
||||||
@ -488,6 +491,15 @@ qcow2GetExtensions(const char *buf,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case QCOW2_HDR_EXTENSION_DATA_FILE_NAME: {
|
||||||
|
if (!dataFilePath)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*dataFilePath = g_new0(char, len + 1);
|
||||||
|
memcpy(*dataFilePath, buf + offset, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QCOW2_HDR_EXTENSION_END:
|
case QCOW2_HDR_EXTENSION_END:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -554,13 +566,33 @@ qcowXGetBackingStore(char **res,
|
|||||||
memcpy(*res, buf + offset, size);
|
memcpy(*res, buf + offset, size);
|
||||||
(*res)[size] = '\0';
|
(*res)[size] = '\0';
|
||||||
|
|
||||||
if (qcow2GetExtensions(buf, buf_size, format) < 0)
|
if (qcow2GetExtensions(buf, buf_size, format, NULL) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qcow2GetDataFile(char **res,
|
||||||
|
virBitmap *features,
|
||||||
|
char *buf,
|
||||||
|
size_t buf_size)
|
||||||
|
{
|
||||||
|
*res = NULL;
|
||||||
|
|
||||||
|
if (buf_size < QCOW2v3_HDR_FEATURES_INCOMPATIBLE + 8)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (features && virBitmapIsBitSet(features, VIR_STORAGE_FILE_FEATURE_DATA_FILE)) {
|
||||||
|
if (qcow2GetExtensions(buf, buf_size, NULL, res) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmdk4GetBackingStore(char **res,
|
vmdk4GetBackingStore(char **res,
|
||||||
int *format,
|
int *format,
|
||||||
@ -968,6 +1000,12 @@ virStorageFileProbeGetMetadata(virStorageSource *meta,
|
|||||||
fileTypeInfo[meta->format].getFeatures(&meta->features, meta->format, buf, len) < 0)
|
fileTypeInfo[meta->format].getFeatures(&meta->features, meta->format, buf, len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
VIR_FREE(meta->dataFileRaw);
|
||||||
|
if (fileTypeInfo[meta->format].getDataFile != NULL) {
|
||||||
|
fileTypeInfo[meta->format].getDataFile(&meta->dataFileRaw, meta->features,
|
||||||
|
buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
VIR_FREE(meta->compat);
|
VIR_FREE(meta->compat);
|
||||||
if (meta->format == VIR_STORAGE_FILE_QCOW2 && meta->features)
|
if (meta->format == VIR_STORAGE_FILE_QCOW2 && meta->features)
|
||||||
meta->compat = g_strdup("1.1");
|
meta->compat = g_strdup("1.1");
|
||||||
|
Loading…
Reference in New Issue
Block a user