提交 fbcf7da9 编写于 作者: J Ján Tomko

Introduce struct _virStorageBackendQemuImgInfo

This will contain the data required for creating the qemu-img
command line without having access to the volume definition.
上级 a832735d
...@@ -796,41 +796,53 @@ virStorageBackendQEMUImgBackingFormat(const char *qemuimg) ...@@ -796,41 +796,53 @@ virStorageBackendQEMUImgBackingFormat(const char *qemuimg)
return ret; return ret;
} }
struct _virStorageBackendQemuImgInfo {
int format;
const char *path;
unsigned long long size_arg;
bool encryption;
bool preallocate;
const char *compat;
virBitmapPtr features;
bool nocow;
const char *backingPath;
int backingFormat;
const char *inputPath;
int inputFormat;
};
static int static int
virStorageBackendCreateQemuImgOpts(char **opts, virStorageBackendCreateQemuImgOpts(char **opts,
const char *backingType, struct _virStorageBackendQemuImgInfo info)
bool encryption,
bool preallocate,
int format,
const char *compat,
bool nocow,
virBitmapPtr features)
{ {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
size_t i; size_t i;
if (backingType) if (info.backingPath)
virBufferAsprintf(&buf, "backing_fmt=%s,", backingType); virBufferAsprintf(&buf, "backing_fmt=%s,",
if (encryption) virStorageFileFormatTypeToString(info.backingFormat));
if (info.encryption)
virBufferAddLit(&buf, "encryption=on,"); virBufferAddLit(&buf, "encryption=on,");
if (preallocate) if (info.preallocate)
virBufferAddLit(&buf, "preallocation=metadata,"); virBufferAddLit(&buf, "preallocation=metadata,");
if (nocow) if (info.nocow)
virBufferAddLit(&buf, "nocow=on,"); virBufferAddLit(&buf, "nocow=on,");
if (compat) if (info.compat)
virBufferAsprintf(&buf, "compat=%s,", compat); virBufferAsprintf(&buf, "compat=%s,", info.compat);
if (features && format == VIR_STORAGE_FILE_QCOW2) { if (info.features && info.format == VIR_STORAGE_FILE_QCOW2) {
for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) { for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) {
if (virBitmapIsBitSet(features, i)) { if (virBitmapIsBitSet(info.features, i)) {
switch ((virStorageFileFeature) i) { switch ((virStorageFileFeature) i) {
case VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS: case VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS:
if (STREQ_NULLABLE(compat, "0.10")) { if (STREQ_NULLABLE(info.compat, "0.10")) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Feature %s not supported with compat" _("Feature %s not supported with compat"
" level %s"), " level %s"),
virStorageFileFeatureTypeToString(i), virStorageFileFeatureTypeToString(i),
compat); info.compat);
goto error; goto error;
} }
break; break;
...@@ -871,75 +883,75 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, ...@@ -871,75 +883,75 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
int imgformat) int imgformat)
{ {
virCommandPtr cmd = NULL; virCommandPtr cmd = NULL;
bool do_encryption = (vol->target.encryption != NULL);
unsigned long long int size_arg;
bool preallocate = !!(flags & VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA);
const char *type; const char *type;
const char *backingType = NULL; const char *backingType = NULL;
const char *inputPath = NULL;
const char *inputType = NULL; const char *inputType = NULL;
const char *compat = vol->target.compat;
char *opts = NULL; char *opts = NULL;
bool convert = false; struct _virStorageBackendQemuImgInfo info = {
bool backing = false; .format = vol->target.format,
.path = vol->target.path,
.encryption = vol->target.encryption != NULL,
.preallocate = !!(flags & VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA),
.compat = vol->target.compat,
.features = vol->target.features,
.nocow = vol->target.nocow,
};
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL); virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
/* Treat output block devices as 'raw' format */ /* Treat output block devices as 'raw' format */
type = virStorageFileFormatTypeToString(vol->type == VIR_STORAGE_VOL_BLOCK ? if (vol->type == VIR_STORAGE_VOL_BLOCK)
VIR_STORAGE_FILE_RAW : info.format = VIR_STORAGE_FILE_RAW;
vol->target.format);
if (!type) { if (!(type = virStorageFileFormatTypeToString(info.format))) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol type %d"), _("unknown storage vol type %d"),
vol->target.format); info.format);
return NULL; return NULL;
} }
if (preallocate && vol->target.format != VIR_STORAGE_FILE_QCOW2) { if (info.preallocate && info.format != VIR_STORAGE_FILE_QCOW2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("metadata preallocation only available with qcow2")); _("metadata preallocation only available with qcow2"));
return NULL; return NULL;
} }
if (vol->target.compat && vol->target.format != VIR_STORAGE_FILE_QCOW2) { if (info.compat && info.format != VIR_STORAGE_FILE_QCOW2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("compatibility option only available with qcow2")); _("compatibility option only available with qcow2"));
return NULL; return NULL;
} }
if (vol->target.features && vol->target.format != VIR_STORAGE_FILE_QCOW2) { if (info.features && info.format != VIR_STORAGE_FILE_QCOW2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("format features only available with qcow2")); _("format features only available with qcow2"));
return NULL; return NULL;
} }
if (inputvol) { if (inputvol) {
if (!(inputPath = inputvol->target.path)) { if (!(info.inputPath = inputvol->target.path)) {
virReportError(VIR_ERR_INVALID_ARG, "%s", virReportError(VIR_ERR_INVALID_ARG, "%s",
_("missing input volume target path")); _("missing input volume target path"));
return NULL; return NULL;
} }
inputType = virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? info.inputFormat = inputvol->target.format;
VIR_STORAGE_FILE_RAW : if (inputvol->type == VIR_STORAGE_VOL_BLOCK)
inputvol->target.format); info.inputFormat = VIR_STORAGE_FILE_RAW;
if (!(inputType = virStorageFileFormatTypeToString(info.inputFormat))) {
if (!inputType) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol type %d"), _("unknown storage vol type %d"),
inputvol->target.format); info.inputFormat);
return NULL; return NULL;
} }
} }
if (vol->target.backingStore) { if (vol->target.backingStore) {
int accessRetCode = -1; int accessRetCode = -1;
char *absolutePath = NULL; char *absolutePath = NULL;
backingType = virStorageFileFormatTypeToString(vol->target.backingStore->format); info.backingFormat = vol->target.backingStore->format;
info.backingPath = vol->target.backingStore->path;
if (preallocate) { if (info.preallocate) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("metadata preallocation conflicts with backing" _("metadata preallocation conflicts with backing"
" store")); " store"));
...@@ -951,43 +963,41 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, ...@@ -951,43 +963,41 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
* may cause issues with lvm. Untested essentially. * may cause issues with lvm. Untested essentially.
*/ */
if (inputvol && inputvol->target.backingStore && if (inputvol && inputvol->target.backingStore &&
STRNEQ_NULLABLE(inputvol->target.backingStore->path, STRNEQ_NULLABLE(inputvol->target.backingStore->path, info.backingPath)) {
vol->target.backingStore->path)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("a different backing store cannot be specified.")); _("a different backing store cannot be specified."));
return NULL; return NULL;
} }
if (backingType == NULL) { if (!(backingType = virStorageFileFormatTypeToString(info.backingFormat))) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol backing store type %d"), _("unknown storage vol backing store type %d"),
vol->target.backingStore->format); info.backingFormat);
return NULL; return NULL;
} }
/* Convert relative backing store paths to absolute paths for access /* Convert relative backing store paths to absolute paths for access
* validation. * validation.
*/ */
if ('/' != *(vol->target.backingStore->path) && if ('/' != *(info.backingPath) &&
virAsprintf(&absolutePath, "%s/%s", pool->def->target.path, virAsprintf(&absolutePath, "%s/%s", pool->def->target.path,
vol->target.backingStore->path) < 0) info.backingPath) < 0)
return NULL; return NULL;
accessRetCode = access(absolutePath ? absolutePath accessRetCode = access(absolutePath ? absolutePath : info.backingPath, R_OK);
: vol->target.backingStore->path, R_OK);
VIR_FREE(absolutePath); VIR_FREE(absolutePath);
if (accessRetCode != 0) { if (accessRetCode != 0) {
virReportSystemError(errno, virReportSystemError(errno,
_("inaccessible backing store volume %s"), _("inaccessible backing store volume %s"),
vol->target.backingStore->path); info.backingPath);
return NULL; return NULL;
} }
} }
if (do_encryption) { if (info.encryption) {
virStorageEncryptionPtr enc; virStorageEncryptionPtr enc;
if (vol->target.format != VIR_STORAGE_FILE_QCOW && if (info.format != VIR_STORAGE_FILE_QCOW &&
vol->target.format != VIR_STORAGE_FILE_QCOW2) { info.format != VIR_STORAGE_FILE_QCOW2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("qcow volume encryption unsupported with " _("qcow volume encryption unsupported with "
"volume format %s"), type); "volume format %s"), type);
...@@ -1014,33 +1024,30 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, ...@@ -1014,33 +1024,30 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
} }
/* Size in KB */ /* Size in KB */
size_arg = VIR_DIV_UP(vol->target.capacity, 1024); info.size_arg = VIR_DIV_UP(vol->target.capacity, 1024);
cmd = virCommandNew(create_tool); cmd = virCommandNew(create_tool);
convert = !!inputvol; /* ignore the backing volume when we're converting a volume */
backing = !inputvol && vol->target.backingStore; if (info.inputPath) {
info.backingPath = NULL;
backingType = NULL;
}
if (convert) if (info.inputPath)
virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type, NULL); virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type, NULL);
else else
virCommandAddArgList(cmd, "create", "-f", type, NULL); virCommandAddArgList(cmd, "create", "-f", type, NULL);
if (backing) if (info.backingPath)
virCommandAddArgList(cmd, "-b", vol->target.backingStore->path, NULL); virCommandAddArgList(cmd, "-b", info.backingPath, NULL);
if (imgformat >= QEMU_IMG_BACKING_FORMAT_OPTIONS) { if (imgformat >= QEMU_IMG_BACKING_FORMAT_OPTIONS) {
if (vol->target.format == VIR_STORAGE_FILE_QCOW2 && !compat && if (info.format == VIR_STORAGE_FILE_QCOW2 && !info.compat &&
imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS_COMPAT) imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS_COMPAT)
compat = "0.10"; info.compat = "0.10";
if (virStorageBackendCreateQemuImgOpts(&opts, if (virStorageBackendCreateQemuImgOpts(&opts, info) < 0) {
backing ? backingType : NULL,
do_encryption, preallocate,
vol->target.format,
compat,
vol->target.nocow,
vol->target.features) < 0) {
virCommandFree(cmd); virCommandFree(cmd);
return NULL; return NULL;
} }
...@@ -1048,22 +1055,22 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, ...@@ -1048,22 +1055,22 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
virCommandAddArgList(cmd, "-o", opts, NULL); virCommandAddArgList(cmd, "-o", opts, NULL);
VIR_FREE(opts); VIR_FREE(opts);
} else { } else {
if (backing) { if (info.backingPath) {
if (imgformat == QEMU_IMG_BACKING_FORMAT_FLAG) if (imgformat == QEMU_IMG_BACKING_FORMAT_FLAG)
virCommandAddArgList(cmd, "-F", backingType, NULL); virCommandAddArgList(cmd, "-F", backingType, NULL);
else else
VIR_DEBUG("Unable to set backing store format for %s with %s", VIR_DEBUG("Unable to set backing store format for %s with %s",
vol->target.path, create_tool); info.path, create_tool);
} }
if (do_encryption) if (info.encryption)
virCommandAddArg(cmd, "-e"); virCommandAddArg(cmd, "-e");
} }
if (convert) if (info.inputPath)
virCommandAddArg(cmd, inputPath); virCommandAddArg(cmd, info.inputPath);
virCommandAddArg(cmd, vol->target.path); virCommandAddArg(cmd, info.path);
if (!convert && size_arg) if (!info.inputPath && info.size_arg)
virCommandAddArgFormat(cmd, "%lluK", size_arg); virCommandAddArgFormat(cmd, "%lluK", info.size_arg);
return cmd; return cmd;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册