This will contain the data required for creating the qemu-img command line without having access to the volume definition. --- src/storage/storage_backend.c | 165 ++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 79 deletions(-) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index fdda0dc..f5b95ec 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -796,41 +796,53 @@ virStorageBackendQEMUImgBackingFormat(const char *qemuimg) 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 virStorageBackendCreateQemuImgOpts(char **opts, - const char *backingType, - bool encryption, - bool preallocate, - int format, - const char *compat, - bool nocow, - virBitmapPtr features) + struct _virStorageBackendQemuImgInfo info) { virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; - if (backingType) - virBufferAsprintf(&buf, "backing_fmt=%s,", backingType); - if (encryption) + if (info.backingPath) + virBufferAsprintf(&buf, "backing_fmt=%s,", + virStorageFileFormatTypeToString(info.backingFormat)); + if (info.encryption) virBufferAddLit(&buf, "encryption=on,"); - if (preallocate) + if (info.preallocate) virBufferAddLit(&buf, "preallocation=metadata,"); - if (nocow) + if (info.nocow) virBufferAddLit(&buf, "nocow=on,"); - if (compat) - virBufferAsprintf(&buf, "compat=%s,", compat); - if (features && format == VIR_STORAGE_FILE_QCOW2) { + if (info.compat) + virBufferAsprintf(&buf, "compat=%s,", info.compat); + if (info.features && info.format == VIR_STORAGE_FILE_QCOW2) { for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) { - if (virBitmapIsBitSet(features, i)) { + if (virBitmapIsBitSet(info.features, i)) { switch ((virStorageFileFeature) i) { 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, _("Feature %s not supported with compat" " level %s"), virStorageFileFeatureTypeToString(i), - compat); + info.compat); goto error; } break; @@ -871,75 +883,75 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, int imgformat) { 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 *backingType = NULL; - const char *inputPath = NULL; const char *inputType = NULL; - const char *compat = vol->target.compat; char *opts = NULL; - bool convert = false; - bool backing = false; + struct _virStorageBackendQemuImgInfo info = { + .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); /* Treat output block devices as 'raw' format */ - type = virStorageFileFormatTypeToString(vol->type == VIR_STORAGE_VOL_BLOCK ? - VIR_STORAGE_FILE_RAW : - vol->target.format); + if (vol->type == VIR_STORAGE_VOL_BLOCK) + info.format = VIR_STORAGE_FILE_RAW; - if (!type) { + if (!(type = virStorageFileFormatTypeToString(info.format))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unknown storage vol type %d"), - vol->target.format); + info.format); 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", _("metadata preallocation only available with qcow2")); 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", _("compatibility option only available with qcow2")); 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", _("format features only available with qcow2")); return NULL; } if (inputvol) { - if (!(inputPath = inputvol->target.path)) { + if (!(info.inputPath = inputvol->target.path)) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("missing input volume target path")); return NULL; } - inputType = virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? - VIR_STORAGE_FILE_RAW : - inputvol->target.format); - - if (!inputType) { + info.inputFormat = inputvol->target.format; + if (inputvol->type == VIR_STORAGE_VOL_BLOCK) + info.inputFormat = VIR_STORAGE_FILE_RAW; + if (!(inputType = virStorageFileFormatTypeToString(info.inputFormat))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unknown storage vol type %d"), - inputvol->target.format); + info.inputFormat); return NULL; } - } if (vol->target.backingStore) { int accessRetCode = -1; 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", _("metadata preallocation conflicts with backing" " store")); @@ -951,43 +963,41 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, * may cause issues with lvm. Untested essentially. */ if (inputvol && inputvol->target.backingStore && - STRNEQ_NULLABLE(inputvol->target.backingStore->path, - vol->target.backingStore->path)) { + STRNEQ_NULLABLE(inputvol->target.backingStore->path, info.backingPath)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("a different backing store cannot be specified.")); return NULL; } - if (backingType == NULL) { + if (!(backingType = virStorageFileFormatTypeToString(info.backingFormat))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unknown storage vol backing store type %d"), - vol->target.backingStore->format); + info.backingFormat); return NULL; } /* Convert relative backing store paths to absolute paths for access * validation. */ - if ('/' != *(vol->target.backingStore->path) && + if ('/' != *(info.backingPath) && virAsprintf(&absolutePath, "%s/%s", pool->def->target.path, - vol->target.backingStore->path) < 0) + info.backingPath) < 0) return NULL; - accessRetCode = access(absolutePath ? absolutePath - : vol->target.backingStore->path, R_OK); + accessRetCode = access(absolutePath ? absolutePath : info.backingPath, R_OK); VIR_FREE(absolutePath); if (accessRetCode != 0) { virReportSystemError(errno, _("inaccessible backing store volume %s"), - vol->target.backingStore->path); + info.backingPath); return NULL; } } - if (do_encryption) { + if (info.encryption) { virStorageEncryptionPtr enc; - if (vol->target.format != VIR_STORAGE_FILE_QCOW && - vol->target.format != VIR_STORAGE_FILE_QCOW2) { + if (info.format != VIR_STORAGE_FILE_QCOW && + info.format != VIR_STORAGE_FILE_QCOW2) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("qcow volume encryption unsupported with " "volume format %s"), type); @@ -1014,33 +1024,30 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, } /* 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); - convert = !!inputvol; - backing = !inputvol && vol->target.backingStore; + /* ignore the backing volume when we're converting a volume */ + if (info.inputPath) { + info.backingPath = NULL; + backingType = NULL; + } - if (convert) + if (info.inputPath) virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type, NULL); else virCommandAddArgList(cmd, "create", "-f", type, NULL); - if (backing) - virCommandAddArgList(cmd, "-b", vol->target.backingStore->path, NULL); + if (info.backingPath) + virCommandAddArgList(cmd, "-b", info.backingPath, NULL); 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) - compat = "0.10"; - - if (virStorageBackendCreateQemuImgOpts(&opts, - backing ? backingType : NULL, - do_encryption, preallocate, - vol->target.format, - compat, - vol->target.nocow, - vol->target.features) < 0) { + info.compat = "0.10"; + + if (virStorageBackendCreateQemuImgOpts(&opts, info) < 0) { virCommandFree(cmd); return NULL; } @@ -1048,22 +1055,22 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, virCommandAddArgList(cmd, "-o", opts, NULL); VIR_FREE(opts); } else { - if (backing) { + if (info.backingPath) { if (imgformat == QEMU_IMG_BACKING_FORMAT_FLAG) virCommandAddArgList(cmd, "-F", backingType, NULL); else 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"); } - if (convert) - virCommandAddArg(cmd, inputPath); - virCommandAddArg(cmd, vol->target.path); - if (!convert && size_arg) - virCommandAddArgFormat(cmd, "%lluK", size_arg); + if (info.inputPath) + virCommandAddArg(cmd, info.inputPath); + virCommandAddArg(cmd, info.path); + if (!info.inputPath && info.size_arg) + virCommandAddArgFormat(cmd, "%lluK", info.size_arg); return cmd; } -- 2.0.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list