From 416b12099e379ec4c19e55a0414a448d140f3dc1 Mon Sep 17 00:00:00 2001 Message-Id: <416b12099e379ec4c19e55a0414a448d140f3dc1@dist-git> From: Peter Krempa Date: Mon, 16 Mar 2020 22:12:16 +0100 Subject: [PATCH] qemu: block: implement helpers for blockdev-reopen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a set of helpers to call blockdev-reopen in certain scenarios Libvirt will use the QMP command to turn certain members of the backing chain read-write for bitmap manipulation and we'll also want to use it to replace/install the backing chain of a qcow2 format node. Signed-off-by: Peter Krempa Reviewed-by: Eric Blake (cherry picked from commit 96063ce280a398493d7a78a35f674ed25078d849) https://bugzilla.redhat.com/show_bug.cgi?id=1799013 Message-Id: Reviewed-by: Ján Tomko --- src/qemu/qemu_block.c | 101 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 9 ++++ 2 files changed, 110 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 141059ae81..b4da323610 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2986,3 +2986,104 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src, return 0; } + + +/** + * qemuBlockReopenFormat: + * @vm: domain object + * @src: storage source to reopen + * @asyncJob: qemu async job type + * + * Invokes the 'blockdev-reopen' command on the format layer of @src. This means + * that @src must be already properly configured for the desired outcome. The + * nodenames of @src are used to identify the specific image in qemu. + */ +static int +qemuBlockReopenFormat(virDomainObjPtr vm, + virStorageSourcePtr src, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + virQEMUDriverPtr driver = priv->driver; + g_autoptr(virJSONValue) reopenprops = NULL; + int rc; + + /* If we are lacking the object here, qemu might have opened an image with + * a node name unknown to us */ + if (!src->backingStore) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("can't reopen image with unknown presence of backing store")); + return -1; + } + + if (!(reopenprops = qemuBlockStorageSourceGetBlockdevProps(src, src->backingStore))) + return -1; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + rc = qemuMonitorBlockdevReopen(priv->mon, &reopenprops); + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + return -1; + + return 0; +} + + +/** + * qemuBlockReopenReadWrite: + * @vm: domain object + * @src: storage source to reopen + * @asyncJob: qemu async job type + * + * Wrapper that reopens @src read-write. We currently depend on qemu + * reopening the storage with 'auto-read-only' enabled for us. + * After successful reopen @src's 'readonly' flag is modified. Does nothing + * if @src is already read-write. + */ +int +qemuBlockReopenReadWrite(virDomainObjPtr vm, + virStorageSourcePtr src, + qemuDomainAsyncJob asyncJob) +{ + if (!src->readonly) + return 0; + + src->readonly = false; + if (qemuBlockReopenFormat(vm, src, asyncJob) < 0) { + src->readonly = true; + return -1; + } + + return 0; +} + + +/** + * qemuBlockReopenReadOnly: + * @vm: domain object + * @src: storage source to reopen + * @asyncJob: qemu async job type + * + * Wrapper that reopens @src read-only. We currently depend on qemu + * reopening the storage with 'auto-read-only' enabled for us. + * After successful reopen @src's 'readonly' flag is modified. Does nothing + * if @src is already read-only. + */ +int +qemuBlockReopenReadOnly(virDomainObjPtr vm, + virStorageSourcePtr src, + qemuDomainAsyncJob asyncJob) +{ + if (src->readonly) + return 0; + + src->readonly = true; + if (qemuBlockReopenFormat(vm, src, asyncJob) < 0) { + src->readonly = false; + return -1; + } + + return 0; +} diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 197f5dae97..e012052352 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -231,3 +231,12 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src, virHashTablePtr blockNamedNodeData, bool shallow, virJSONValuePtr *actions); + +int +qemuBlockReopenReadWrite(virDomainObjPtr vm, + virStorageSourcePtr src, + qemuDomainAsyncJob asyncJob); +int +qemuBlockReopenReadOnly(virDomainObjPtr vm, + virStorageSourcePtr src, + qemuDomainAsyncJob asyncJob); -- 2.25.1