提交 1c9a2fb1 编写于 作者: J Ján Tomko 提交者: Michal Privoznik

storage: allow metadata preallocation when creating qcow2 images

Add VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA flag to virStorageVolCreateXML
and virStorageVolCreateXMLFrom. This flag requests metadata
preallocation when creating/cloning qcow2 images, resulting in creating
a sparse file with qcow2 metadata. It has only slightly larger disk usage
compared to new image with no allocation, but offers higher performance.
上级 b718ded3
...@@ -2906,6 +2906,10 @@ virStorageVolPtr virStorageVolLookupByPath (virConnectPtr conn, ...@@ -2906,6 +2906,10 @@ virStorageVolPtr virStorageVolLookupByPath (virConnectPtr conn,
const char* virStorageVolGetName (virStorageVolPtr vol); const char* virStorageVolGetName (virStorageVolPtr vol);
const char* virStorageVolGetKey (virStorageVolPtr vol); const char* virStorageVolGetKey (virStorageVolPtr vol);
typedef enum {
VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA = 1 << 0,
} virStorageVolCreateFlags;
virStorageVolPtr virStorageVolCreateXML (virStoragePoolPtr pool, virStorageVolPtr virStorageVolCreateXML (virStoragePoolPtr pool,
const char *xmldesc, const char *xmldesc,
unsigned int flags); unsigned int flags);
......
...@@ -13382,11 +13382,16 @@ virStorageVolGetKey(virStorageVolPtr vol) ...@@ -13382,11 +13382,16 @@ virStorageVolGetKey(virStorageVolPtr vol)
* virStorageVolCreateXML: * virStorageVolCreateXML:
* @pool: pointer to storage pool * @pool: pointer to storage pool
* @xmlDesc: description of volume to create * @xmlDesc: description of volume to create
* @flags: extra flags; not used yet, so callers should always pass 0 * @flags: bitwise-OR of virStorageVolCreateFlags
* *
* Create a storage volume within a pool based * Create a storage volume within a pool based
* on an XML description. Not all pools support * on an XML description. Not all pools support
* creation of volumes * creation of volumes.
*
* Since 1.0.1 VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA
* in flags can be used to get higher performance with
* qcow2 image files which don't support full preallocation,
* by creating a sparse image file with metadata.
* *
* Returns the storage volume, or NULL on error * Returns the storage volume, or NULL on error
*/ */
...@@ -13433,13 +13438,18 @@ error: ...@@ -13433,13 +13438,18 @@ error:
* @pool: pointer to parent pool for the new volume * @pool: pointer to parent pool for the new volume
* @xmlDesc: description of volume to create * @xmlDesc: description of volume to create
* @clonevol: storage volume to use as input * @clonevol: storage volume to use as input
* @flags: extra flags; not used yet, so callers should always pass 0 * @flags: bitwise-OR of virStorageVolCreateFlags
* *
* Create a storage volume in the parent pool, using the * Create a storage volume in the parent pool, using the
* 'clonevol' volume as input. Information for the new * 'clonevol' volume as input. Information for the new
* volume (name, perms) are passed via a typical volume * volume (name, perms) are passed via a typical volume
* XML description. * XML description.
* *
* Since 1.0.1 VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA
* in flags can be used to get higher performance with
* qcow2 image files which don't support full preallocation,
* by creating a sparse image file with metadata.
*
* Returns the storage volume, or NULL on error * Returns the storage volume, or NULL on error
*/ */
virStorageVolPtr virStorageVolPtr
......
...@@ -668,8 +668,11 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, ...@@ -668,8 +668,11 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virCommandPtr cmd = NULL; virCommandPtr cmd = NULL;
bool do_encryption = (vol->target.encryption != NULL); bool do_encryption = (vol->target.encryption != NULL);
unsigned long long int size_arg; unsigned long long int size_arg;
bool preallocate = false;
virCheckFlags(0, -1); virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, -1);
preallocate = !!(flags & VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA);
const char *type = virStorageFileFormatTypeToString(vol->target.format); const char *type = virStorageFileFormatTypeToString(vol->target.format);
const char *backingType = vol->backingStore.path ? const char *backingType = vol->backingStore.path ?
...@@ -697,11 +700,23 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, ...@@ -697,11 +700,23 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
inputvol->target.format); inputvol->target.format);
return -1; return -1;
} }
if (preallocate && vol->target.format != VIR_STORAGE_FILE_QCOW2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("metadata preallocation only available with qcow2"));
return -1;
}
if (vol->backingStore.path) { if (vol->backingStore.path) {
int accessRetCode = -1; int accessRetCode = -1;
char *absolutePath = NULL; char *absolutePath = NULL;
if (preallocate) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("metadata preallocation conflicts with backing"
" store"));
return -1;
}
/* XXX: Not strictly required: qemu-img has an option a different /* XXX: Not strictly required: qemu-img has an option a different
* backing store, not really sure what use it serves though, and it * backing store, not really sure what use it serves though, and it
* may cause issues with lvm. Untested essentially. * may cause issues with lvm. Untested essentially.
...@@ -796,14 +811,15 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, ...@@ -796,14 +811,15 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type, virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type,
inputPath, vol->target.path, NULL); inputPath, vol->target.path, NULL);
if (do_encryption) { if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS &&
if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { (do_encryption || preallocate)) {
virCommandAddArgList(cmd, "-o", "encryption=on", NULL); virCommandAddArg(cmd, "-o");
} else { virCommandAddArgFormat(cmd, "%s%s%s", do_encryption ? "encryption=on" : "",
virCommandAddArg(cmd, "-e"); (do_encryption && preallocate) ? "," : "",
} preallocate ? "preallocation=metadata" : "");
} else if (do_encryption) {
virCommandAddArg(cmd, "-e");
} }
} else if (vol->backingStore.path) { } else if (vol->backingStore.path) {
virCommandAddArgList(cmd, "create", "-f", type, virCommandAddArgList(cmd, "create", "-f", type,
"-b", vol->backingStore.path, NULL); "-b", vol->backingStore.path, NULL);
...@@ -840,12 +856,14 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, ...@@ -840,12 +856,14 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
vol->target.path, NULL); vol->target.path, NULL);
virCommandAddArgFormat(cmd, "%lluK", size_arg); virCommandAddArgFormat(cmd, "%lluK", size_arg);
if (do_encryption) { if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS &&
if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { (do_encryption || preallocate)) {
virCommandAddArgList(cmd, "-o", "encryption=on", NULL); virCommandAddArg(cmd, "-o");
} else { virCommandAddArgFormat(cmd, "%s%s%s", do_encryption ? "encryption=on" : "",
virCommandAddArg(cmd, "-e"); (do_encryption && preallocate) ? "," : "",
} preallocate ? "preallocation=metadata" : "");
} else if (do_encryption) {
virCommandAddArg(cmd, "-e");
} }
} }
......
...@@ -37,7 +37,8 @@ typedef int (*virStorageBackendStopPool)(virConnectPtr conn, virStoragePoolObjPt ...@@ -37,7 +37,8 @@ typedef int (*virStorageBackendStopPool)(virConnectPtr conn, virStoragePoolObjPt
typedef int (*virStorageBackendDeletePool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags); typedef int (*virStorageBackendDeletePool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags);
typedef int (*virStorageBackendBuildVol)(virConnectPtr conn, typedef int (*virStorageBackendBuildVol)(virConnectPtr conn,
virStoragePoolObjPtr pool, virStorageVolDefPtr vol); virStoragePoolObjPtr pool, virStorageVolDefPtr vol,
unsigned int flags);
typedef int (*virStorageBackendCreateVol)(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol); typedef int (*virStorageBackendCreateVol)(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol);
typedef int (*virStorageBackendRefreshVol)(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol); typedef int (*virStorageBackendRefreshVol)(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol);
typedef int (*virStorageBackendDeleteVol)(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags); typedef int (*virStorageBackendDeleteVol)(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags);
......
...@@ -1052,7 +1052,8 @@ static int ...@@ -1052,7 +1052,8 @@ static int
_virStorageBackendFileSystemVolBuild(virConnectPtr conn, _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
virStoragePoolObjPtr pool, virStoragePoolObjPtr pool,
virStorageVolDefPtr vol, virStorageVolDefPtr vol,
virStorageVolDefPtr inputvol) virStorageVolDefPtr inputvol,
unsigned int flags)
{ {
virStorageBackendBuildVolFrom create_func; virStorageBackendBuildVolFrom create_func;
int tool_type; int tool_type;
...@@ -1085,7 +1086,7 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn, ...@@ -1085,7 +1086,7 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
return -1; return -1;
} }
if (create_func(conn, pool, vol, inputvol, 0) < 0) if (create_func(conn, pool, vol, inputvol, flags) < 0)
return -1; return -1;
return 0; return 0;
} }
...@@ -1098,8 +1099,11 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn, ...@@ -1098,8 +1099,11 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
static int static int
virStorageBackendFileSystemVolBuild(virConnectPtr conn, virStorageBackendFileSystemVolBuild(virConnectPtr conn,
virStoragePoolObjPtr pool, virStoragePoolObjPtr pool,
virStorageVolDefPtr vol) { virStorageVolDefPtr vol,
return _virStorageBackendFileSystemVolBuild(conn, pool, vol, NULL); unsigned int flags) {
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, -1);
return _virStorageBackendFileSystemVolBuild(conn, pool, vol, NULL, flags);
} }
/* /*
...@@ -1112,9 +1116,9 @@ virStorageBackendFileSystemVolBuildFrom(virConnectPtr conn, ...@@ -1112,9 +1116,9 @@ virStorageBackendFileSystemVolBuildFrom(virConnectPtr conn,
virStorageVolDefPtr inputvol, virStorageVolDefPtr inputvol,
unsigned int flags) unsigned int flags)
{ {
virCheckFlags(0, -1); virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, -1);
return _virStorageBackendFileSystemVolBuild(conn, pool, vol, inputvol); return _virStorageBackendFileSystemVolBuild(conn, pool, vol, inputvol, flags);
} }
/** /**
......
...@@ -1348,7 +1348,7 @@ storageVolumeCreateXML(virStoragePoolPtr obj, ...@@ -1348,7 +1348,7 @@ storageVolumeCreateXML(virStoragePoolPtr obj,
virStorageVolDefPtr voldef = NULL; virStorageVolDefPtr voldef = NULL;
virStorageVolPtr ret = NULL, volobj = NULL; virStorageVolPtr ret = NULL, volobj = NULL;
virCheckFlags(0, NULL); virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
storageDriverLock(driver); storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
...@@ -1425,7 +1425,7 @@ storageVolumeCreateXML(virStoragePoolPtr obj, ...@@ -1425,7 +1425,7 @@ storageVolumeCreateXML(virStoragePoolPtr obj,
voldef->building = 1; voldef->building = 1;
virStoragePoolObjUnlock(pool); virStoragePoolObjUnlock(pool);
buildret = backend->buildVol(obj->conn, pool, buildvoldef); buildret = backend->buildVol(obj->conn, pool, buildvoldef, flags);
storageDriverLock(driver); storageDriverLock(driver);
virStoragePoolObjLock(pool); virStoragePoolObjLock(pool);
...@@ -1473,7 +1473,7 @@ storageVolumeCreateXMLFrom(virStoragePoolPtr obj, ...@@ -1473,7 +1473,7 @@ storageVolumeCreateXMLFrom(virStoragePoolPtr obj,
virStorageVolPtr ret = NULL, volobj = NULL; virStorageVolPtr ret = NULL, volobj = NULL;
int buildret; int buildret;
virCheckFlags(0, NULL); virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
storageDriverLock(driver); storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册