On Thu, Aug 08, 2019 at 06:00:40PM +0200, Peter Krempa wrote:
QEMU finally exposes an interface which allows us to instruct it to
format or create arbitrary images. This is required for blockdev
integration of block copy and snapshots as we need to pre-format images
prior to use with blockdev-add.
This path introduces job handling and also helpers for formatting and
attaching a whole image described by a virStorageSource.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_block.c | 250 ++++++++++++++++++
src/qemu/qemu_block.h | 14 +
src/qemu/qemu_blockjob.c | 88 +++++-
src/qemu/qemu_blockjob.h | 17 ++
src/qemu/qemu_domain.c | 34 ++-
src/qemu/qemu_driver.c | 1 +
.../blockjob-blockdev-in.xml | 45 ++++
7 files changed, 446 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 47661fb8bd..cb9a085e5d 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
[...]
+static int
+qemuBlockStorageSourceCreateStorage(virDomainObjPtr vm,
+ virStorageSourcePtr src,
+ virStorageSourcePtr chain,
+ qemuDomainAsyncJob asyncJob)
+{
+ int actualType = virStorageSourceGetActualType(src);
+ VIR_AUTOPTR(virJSONValue) createstorageprops = NULL;
+ int ret;
+
+ /* we need to do stuff only for remote storage and local raw files */
Rather than rewording the following condition, it would be better to say
why we do not need to do it.
+ if (actualType != VIR_STORAGE_TYPE_NETWORK &&
+ !(actualType == VIR_STORAGE_TYPE_FILE && src->format ==
VIR_STORAGE_FILE_RAW))
+ return 0;
+
+ if (qemuBlockStorageSourceCreateGetStorageProps(src, &createstorageprops) <
0)
+ return -1;
+
+ if (!createstorageprops) {
+ /* we can always try opening it to see whether it was existing */
+ return 0;
+ }
+
+ ret = qemuBlockStorageSourceCreateGeneric(vm, createstorageprops, src, chain,
+ true, asyncJob);
+ createstorageprops = NULL;
+
+ return ret;
+}
+
+
+static int
+qemuBlockStorageSourceCreateFormat(virDomainObjPtr vm,
+ virStorageSourcePtr src,
+ virStorageSourcePtr backingStore,
+ virStorageSourcePtr chain,
+ qemuDomainAsyncJob asyncJob)
+{
+ VIR_AUTOPTR(virJSONValue) createformatprops = NULL;
+ int ret;
+
+ if (src->format == VIR_STORAGE_FILE_RAW)
+ return 0;
+
+ if (qemuBlockStorageSourceCreateGetFormatProps(src, backingStore,
+ &createformatprops) < 0)
+ return -1;
+
+ if (!createformatprops) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("can't create storage format '%s'"),
+ virStorageFileFormatTypeToString(src->format));
+ return -1;
+ }
+
+ ret = qemuBlockStorageSourceCreateGeneric(vm, createformatprops, src, chain,
+ false, asyncJob);
+ createformatprops = NULL;
+
+ return ret;
+}
+
+
+/**
+ * qemuBlockStorageSourceCreate:
+ * @vm: domain object
+ * @src: storage source definition to create
+ * @backingStore: backingStore of the new image (used only in image metadata)
+ * @chain: backing chain to unplug in case of a long-running job failure
+ * @data: qemuBlockStorageSourceAttachData for @src so that it can be attached
+ * @asyncJob: qemu asynchronous job type
+ *
+ * Creates and formats a storage volume according to @src and attaches it to @vm.
+ * @data must provide attachment data as if @src was existing. @src is attached
+ * after successful return of this function. If libvirtd is restarted during
+ * the create job @chain is unplugged, otherwise it's left for the caller.
+ * If @backingStore is provided, the new image will refer to it as it's backing
*its
+ * store.
+ */
Reviewed-by: Ján Tomko <jtomko(a)redhat.com>
Jano