mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-26 03:21:44 +03:00
storage: list more file types
When an image has no backing file, using VIR_STORAGE_FILE_AUTO for its type is a bit confusing. Additionally, a future patch would like to reserve a default value for the case of no file type specified in the XML, but different from the current use of -1 to imply probing, since probing is not always safe. Also, a couple of file types were missing compared to supported code: libxl supports 'vhd', and qemu supports 'fat' for directories passed through as a file system. * src/util/storage_file.h (virStorageFileFormat): Add VIR_STORAGE_FILE_NONE, VIR_STORAGE_FILE_FAT, VIR_STORAGE_FILE_VHD. * src/util/storage_file.c (virStorageFileMatchesVersion): Match documentation when version probing not supported. (cowGetBackingStore, qcowXGetBackingStore, qcow1GetBackingStore) (qcow2GetBackingStoreFormat, qedGetBackingStore) (virStorageFileGetMetadataFromBuf) (virStorageFileGetMetadataFromFD): Take NONE into account. * src/conf/domain_conf.c (virDomainDiskDefForeachPath): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo): Likewise. * src/conf/storage_conf.c (virStorageVolumeFormatFromString): New function. (poolTypeInfo): Use it.
This commit is contained in:
parent
7b21981cdb
commit
f772b3d91f
@ -14847,7 +14847,7 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
|||||||
if (STREQ(formatStr, "aio"))
|
if (STREQ(formatStr, "aio"))
|
||||||
formatStr = "raw"; /* Xen compat */
|
formatStr = "raw"; /* Xen compat */
|
||||||
|
|
||||||
if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) {
|
if ((format = virStorageFileFormatTypeFromString(formatStr)) <= 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("unknown disk format '%s' for %s"),
|
_("unknown disk format '%s' for %s"),
|
||||||
disk->driverType, disk->src);
|
disk->driverType, disk->src);
|
||||||
|
@ -135,6 +135,15 @@ struct _virStoragePoolTypeInfo {
|
|||||||
virStorageVolOptions volOptions;
|
virStorageVolOptions volOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageVolumeFormatFromString(const char *format)
|
||||||
|
{
|
||||||
|
int ret = virStorageFileFormatTypeFromString(format);
|
||||||
|
if (ret == VIR_STORAGE_FILE_NONE)
|
||||||
|
return -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static virStoragePoolTypeInfo poolTypeInfo[] = {
|
static virStoragePoolTypeInfo poolTypeInfo[] = {
|
||||||
{ .poolType = VIR_STORAGE_POOL_LOGICAL,
|
{ .poolType = VIR_STORAGE_POOL_LOGICAL,
|
||||||
.poolOptions = {
|
.poolOptions = {
|
||||||
@ -148,7 +157,7 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
|
|||||||
{ .poolType = VIR_STORAGE_POOL_DIR,
|
{ .poolType = VIR_STORAGE_POOL_DIR,
|
||||||
.volOptions = {
|
.volOptions = {
|
||||||
.defaultFormat = VIR_STORAGE_FILE_RAW,
|
.defaultFormat = VIR_STORAGE_FILE_RAW,
|
||||||
.formatFromString = virStorageFileFormatTypeFromString,
|
.formatFromString = virStorageVolumeFormatFromString,
|
||||||
.formatToString = virStorageFileFormatTypeToString,
|
.formatToString = virStorageFileFormatTypeToString,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -161,7 +170,7 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
|
|||||||
},
|
},
|
||||||
.volOptions = {
|
.volOptions = {
|
||||||
.defaultFormat = VIR_STORAGE_FILE_RAW,
|
.defaultFormat = VIR_STORAGE_FILE_RAW,
|
||||||
.formatFromString = virStorageFileFormatTypeFromString,
|
.formatFromString = virStorageVolumeFormatFromString,
|
||||||
.formatToString = virStorageFileFormatTypeToString,
|
.formatToString = virStorageFileFormatTypeToString,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -175,7 +184,7 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
|
|||||||
},
|
},
|
||||||
.volOptions = {
|
.volOptions = {
|
||||||
.defaultFormat = VIR_STORAGE_FILE_RAW,
|
.defaultFormat = VIR_STORAGE_FILE_RAW,
|
||||||
.formatFromString = virStorageFileFormatTypeFromString,
|
.formatFromString = virStorageVolumeFormatFromString,
|
||||||
.formatToString = virStorageFileFormatTypeToString,
|
.formatToString = virStorageFileFormatTypeToString,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -9303,7 +9303,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
|
|||||||
|
|
||||||
/* Probe for magic formats */
|
/* Probe for magic formats */
|
||||||
if (disk->driverType) {
|
if (disk->driverType) {
|
||||||
if ((format = virStorageFileFormatTypeFromString(disk->driverType)) < 0) {
|
if ((format = virStorageFileFormatTypeFromString(disk->driverType)) <= 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("unknown disk format %s for %s"),
|
_("unknown disk format %s for %s"),
|
||||||
disk->driverType, disk->src);
|
disk->driverType, disk->src);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* storage_file.c: file utility functions for FS storage backend
|
* storage_file.c: file utility functions for FS storage backend
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2011 Red Hat, Inc.
|
* Copyright (C) 2007-2012 Red Hat, Inc.
|
||||||
* Copyright (C) 2007-2008 Daniel P. Berrange
|
* Copyright (C) 2007-2008 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -45,9 +45,11 @@
|
|||||||
|
|
||||||
VIR_ENUM_IMPL(virStorageFileFormat,
|
VIR_ENUM_IMPL(virStorageFileFormat,
|
||||||
VIR_STORAGE_FILE_LAST,
|
VIR_STORAGE_FILE_LAST,
|
||||||
|
"none",
|
||||||
"raw", "dir", "bochs",
|
"raw", "dir", "bochs",
|
||||||
"cloop", "cow", "dmg", "iso",
|
"cloop", "cow", "dmg", "iso",
|
||||||
"qcow", "qcow2", "qed", "vmdk", "vpc")
|
"qcow", "qcow2", "qed", "vmdk", "vpc",
|
||||||
|
"fat", "vhd")
|
||||||
|
|
||||||
enum lv_endian {
|
enum lv_endian {
|
||||||
LV_LITTLE_ENDIAN = 1, /* 1234 */
|
LV_LITTLE_ENDIAN = 1, /* 1234 */
|
||||||
@ -123,8 +125,12 @@ qedGetBackingStore(char **, int *, const unsigned char *, size_t);
|
|||||||
|
|
||||||
|
|
||||||
static struct FileTypeInfo const fileTypeInfo[] = {
|
static struct FileTypeInfo const fileTypeInfo[] = {
|
||||||
[VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
|
[VIR_STORAGE_FILE_NONE] = { NULL, NULL, LV_LITTLE_ENDIAN,
|
||||||
[VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
|
-1, 0, 0, 0, 0, 0, NULL },
|
||||||
|
[VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN,
|
||||||
|
-1, 0, 0, 0, 0, 0, NULL },
|
||||||
|
[VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN,
|
||||||
|
-1, 0, 0, 0, 0, 0, NULL },
|
||||||
[VIR_STORAGE_FILE_BOCHS] = {
|
[VIR_STORAGE_FILE_BOCHS] = {
|
||||||
/*"Bochs Virtual HD Image", */ /* Untested */ NULL,
|
/*"Bochs Virtual HD Image", */ /* Untested */ NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@ -180,6 +186,11 @@ static struct FileTypeInfo const fileTypeInfo[] = {
|
|||||||
LV_BIG_ENDIAN, 12, 0x10000,
|
LV_BIG_ENDIAN, 12, 0x10000,
|
||||||
8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL
|
8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL
|
||||||
},
|
},
|
||||||
|
/* Not direct file formats, but used for various drivers */
|
||||||
|
[VIR_STORAGE_FILE_FAT] = { NULL, NULL, LV_LITTLE_ENDIAN,
|
||||||
|
-1, 0, 0, 0, 0, 0, NULL },
|
||||||
|
[VIR_STORAGE_FILE_VHD] = { NULL, NULL, LV_LITTLE_ENDIAN,
|
||||||
|
-1, 0, 0, 0, 0, 0, NULL },
|
||||||
};
|
};
|
||||||
verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
|
verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
|
||||||
|
|
||||||
@ -195,8 +206,10 @@ cowGetBackingStore(char **res,
|
|||||||
|
|
||||||
if (buf_size < 4+4+ COW_FILENAME_MAXLEN)
|
if (buf_size < 4+4+ COW_FILENAME_MAXLEN)
|
||||||
return BACKING_STORE_INVALID;
|
return BACKING_STORE_INVALID;
|
||||||
if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */
|
if (buf[4+4] == '\0') { /* cow_header_v2.backing_file[0] */
|
||||||
|
*format = VIR_STORAGE_FILE_NONE;
|
||||||
return BACKING_STORE_OK;
|
return BACKING_STORE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
*res = strndup ((const char*)buf + 4+4, COW_FILENAME_MAXLEN);
|
*res = strndup ((const char*)buf + 4+4, COW_FILENAME_MAXLEN);
|
||||||
if (*res == NULL) {
|
if (*res == NULL) {
|
||||||
@ -256,7 +269,8 @@ qcow2GetBackingStoreFormat(int *format,
|
|||||||
break;
|
break;
|
||||||
*format = virStorageFileFormatTypeFromString(
|
*format = virStorageFileFormatTypeFromString(
|
||||||
((const char *)buf)+offset);
|
((const char *)buf)+offset);
|
||||||
break;
|
if (*format <= VIR_STORAGE_FILE_NONE)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += len;
|
offset += len;
|
||||||
@ -298,8 +312,11 @@ qcowXGetBackingStore(char **res,
|
|||||||
| (buf[QCOWX_HDR_BACKING_FILE_SIZE+1] << 16)
|
| (buf[QCOWX_HDR_BACKING_FILE_SIZE+1] << 16)
|
||||||
| (buf[QCOWX_HDR_BACKING_FILE_SIZE+2] << 8)
|
| (buf[QCOWX_HDR_BACKING_FILE_SIZE+2] << 8)
|
||||||
| buf[QCOWX_HDR_BACKING_FILE_SIZE+3]); /* QCowHeader.backing_file_size */
|
| buf[QCOWX_HDR_BACKING_FILE_SIZE+3]); /* QCowHeader.backing_file_size */
|
||||||
if (size == 0)
|
if (size == 0) {
|
||||||
|
if (format)
|
||||||
|
*format = VIR_STORAGE_FILE_NONE;
|
||||||
return BACKING_STORE_OK;
|
return BACKING_STORE_OK;
|
||||||
|
}
|
||||||
if (offset + size > buf_size || offset + size < offset)
|
if (offset + size > buf_size || offset + size < offset)
|
||||||
return BACKING_STORE_INVALID;
|
return BACKING_STORE_INVALID;
|
||||||
if (size + 1 == 0)
|
if (size + 1 == 0)
|
||||||
@ -335,8 +352,10 @@ qcowXGetBackingStore(char **res,
|
|||||||
* between the end of the header (QCOW2_HDR_TOTAL_SIZE)
|
* between the end of the header (QCOW2_HDR_TOTAL_SIZE)
|
||||||
* and the start of the backingStoreName (offset)
|
* and the start of the backingStoreName (offset)
|
||||||
*/
|
*/
|
||||||
if (isQCow2 && format)
|
if (isQCow2 && format &&
|
||||||
qcow2GetBackingStoreFormat(format, buf, buf_size, QCOW2_HDR_TOTAL_SIZE, offset);
|
qcow2GetBackingStoreFormat(format, buf, buf_size, QCOW2_HDR_TOTAL_SIZE,
|
||||||
|
offset) < 0)
|
||||||
|
return BACKING_STORE_INVALID;
|
||||||
|
|
||||||
return BACKING_STORE_OK;
|
return BACKING_STORE_OK;
|
||||||
}
|
}
|
||||||
@ -348,10 +367,15 @@ qcow1GetBackingStore(char **res,
|
|||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
size_t buf_size)
|
size_t buf_size)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* QCow1 doesn't have the extensions capability
|
/* QCow1 doesn't have the extensions capability
|
||||||
* used to store backing format */
|
* used to store backing format */
|
||||||
*format = VIR_STORAGE_FILE_AUTO;
|
*format = VIR_STORAGE_FILE_AUTO;
|
||||||
return qcowXGetBackingStore(res, NULL, buf, buf_size, false);
|
ret = qcowXGetBackingStore(res, NULL, buf, buf_size, false);
|
||||||
|
if (ret == 0 && *buf == '\0')
|
||||||
|
*format = VIR_STORAGE_FILE_NONE;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -401,6 +425,7 @@ vmdk4GetBackingStore(char **res,
|
|||||||
desc[len] = '\0';
|
desc[len] = '\0';
|
||||||
start = strstr(desc, prefix);
|
start = strstr(desc, prefix);
|
||||||
if (start == NULL) {
|
if (start == NULL) {
|
||||||
|
*format = VIR_STORAGE_FILE_NONE;
|
||||||
ret = BACKING_STORE_OK;
|
ret = BACKING_STORE_OK;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -411,6 +436,7 @@ vmdk4GetBackingStore(char **res,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (end == start) {
|
if (end == start) {
|
||||||
|
*format = VIR_STORAGE_FILE_NONE;
|
||||||
ret = BACKING_STORE_OK;
|
ret = BACKING_STORE_OK;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -464,8 +490,10 @@ qedGetBackingStore(char **res,
|
|||||||
if (buf_size < QED_HDR_FEATURES_OFFSET+8)
|
if (buf_size < QED_HDR_FEATURES_OFFSET+8)
|
||||||
return BACKING_STORE_INVALID;
|
return BACKING_STORE_INVALID;
|
||||||
flags = qedGetHeaderULL(buf + QED_HDR_FEATURES_OFFSET);
|
flags = qedGetHeaderULL(buf + QED_HDR_FEATURES_OFFSET);
|
||||||
if (!(flags & QED_F_BACKING_FILE))
|
if (!(flags & QED_F_BACKING_FILE)) {
|
||||||
|
*format = VIR_STORAGE_FILE_NONE;
|
||||||
return BACKING_STORE_OK;
|
return BACKING_STORE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the backing file */
|
/* Parse the backing file */
|
||||||
if (buf_size < QED_HDR_BACKING_FILE_OFFSET+8)
|
if (buf_size < QED_HDR_BACKING_FILE_OFFSET+8)
|
||||||
@ -485,12 +513,10 @@ qedGetBackingStore(char **res,
|
|||||||
memcpy(*res, buf + offset, size);
|
memcpy(*res, buf + offset, size);
|
||||||
(*res)[size] = '\0';
|
(*res)[size] = '\0';
|
||||||
|
|
||||||
if (format) {
|
|
||||||
if (flags & QED_F_BACKING_FORMAT_NO_PROBE)
|
if (flags & QED_F_BACKING_FORMAT_NO_PROBE)
|
||||||
*format = virStorageFileFormatTypeFromString("raw");
|
*format = VIR_STORAGE_FILE_RAW;
|
||||||
else
|
else
|
||||||
*format = VIR_STORAGE_FILE_AUTO_SAFE;
|
*format = VIR_STORAGE_FILE_AUTO_SAFE;
|
||||||
}
|
|
||||||
|
|
||||||
return BACKING_STORE_OK;
|
return BACKING_STORE_OK;
|
||||||
}
|
}
|
||||||
@ -564,7 +590,7 @@ virStorageFileMatchesVersion(int format,
|
|||||||
|
|
||||||
/* Validate version number info */
|
/* Validate version number info */
|
||||||
if (fileTypeInfo[format].versionOffset == -1)
|
if (fileTypeInfo[format].versionOffset == -1)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if ((fileTypeInfo[format].versionOffset + 4) > buflen)
|
if ((fileTypeInfo[format].versionOffset + 4) > buflen)
|
||||||
return false;
|
return false;
|
||||||
@ -607,7 +633,9 @@ virStorageFileGetMetadataFromBuf(int format,
|
|||||||
/* XXX we should consider moving virStorageBackendUpdateVolInfo
|
/* XXX we should consider moving virStorageBackendUpdateVolInfo
|
||||||
* code into this method, for non-magic files
|
* code into this method, for non-magic files
|
||||||
*/
|
*/
|
||||||
if (!fileTypeInfo[format].magic) {
|
if (format <= VIR_STORAGE_FILE_NONE ||
|
||||||
|
format >= VIR_STORAGE_FILE_LAST ||
|
||||||
|
!fileTypeInfo[format].magic) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,7 +710,7 @@ virStorageFileGetMetadataFromBuf(int format,
|
|||||||
meta->backingStoreFormat = backingFormat;
|
meta->backingStoreFormat = backingFormat;
|
||||||
} else {
|
} else {
|
||||||
meta->backingStore = NULL;
|
meta->backingStore = NULL;
|
||||||
meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
|
meta->backingStoreFormat = VIR_STORAGE_FILE_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -867,7 +895,7 @@ virStorageFileGetMetadataFromFD(const char *path,
|
|||||||
if (format == VIR_STORAGE_FILE_AUTO)
|
if (format == VIR_STORAGE_FILE_AUTO)
|
||||||
format = virStorageFileProbeFormatFromBuf(path, head, len);
|
format = virStorageFileProbeFormatFromBuf(path, head, len);
|
||||||
|
|
||||||
if (format < 0 ||
|
if (format <= VIR_STORAGE_FILE_NONE ||
|
||||||
format >= VIR_STORAGE_FILE_LAST) {
|
format >= VIR_STORAGE_FILE_LAST) {
|
||||||
virReportSystemError(EINVAL, _("unknown storage file format %d"),
|
virReportSystemError(EINVAL, _("unknown storage file format %d"),
|
||||||
format);
|
format);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* storage_file.c: file utility functions for FS storage backend
|
* storage_file.c: file utility functions for FS storage backend
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009 Red Hat, Inc.
|
* Copyright (C) 2007-2009, 2012 Red Hat, Inc.
|
||||||
* Copyright (C) 2007-2008 Daniel P. Berrange
|
* Copyright (C) 2007-2008 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -29,7 +29,8 @@
|
|||||||
enum virStorageFileFormat {
|
enum virStorageFileFormat {
|
||||||
VIR_STORAGE_FILE_AUTO_SAFE = -2,
|
VIR_STORAGE_FILE_AUTO_SAFE = -2,
|
||||||
VIR_STORAGE_FILE_AUTO = -1,
|
VIR_STORAGE_FILE_AUTO = -1,
|
||||||
VIR_STORAGE_FILE_RAW = 0,
|
VIR_STORAGE_FILE_NONE = 0,
|
||||||
|
VIR_STORAGE_FILE_RAW,
|
||||||
VIR_STORAGE_FILE_DIR,
|
VIR_STORAGE_FILE_DIR,
|
||||||
VIR_STORAGE_FILE_BOCHS,
|
VIR_STORAGE_FILE_BOCHS,
|
||||||
VIR_STORAGE_FILE_CLOOP,
|
VIR_STORAGE_FILE_CLOOP,
|
||||||
@ -41,6 +42,9 @@ enum virStorageFileFormat {
|
|||||||
VIR_STORAGE_FILE_QED,
|
VIR_STORAGE_FILE_QED,
|
||||||
VIR_STORAGE_FILE_VMDK,
|
VIR_STORAGE_FILE_VMDK,
|
||||||
VIR_STORAGE_FILE_VPC,
|
VIR_STORAGE_FILE_VPC,
|
||||||
|
VIR_STORAGE_FILE_FAT,
|
||||||
|
VIR_STORAGE_FILE_VHD,
|
||||||
|
|
||||||
VIR_STORAGE_FILE_LAST,
|
VIR_STORAGE_FILE_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user