156 lines
4.9 KiB
Diff
156 lines
4.9 KiB
Diff
|
From 416b12099e379ec4c19e55a0414a448d140f3dc1 Mon Sep 17 00:00:00 2001
|
||
|
Message-Id: <416b12099e379ec4c19e55a0414a448d140f3dc1@dist-git>
|
||
|
From: Peter Krempa <pkrempa@redhat.com>
|
||
|
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 <pkrempa@redhat.com>
|
||
|
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||
|
(cherry picked from commit 96063ce280a398493d7a78a35f674ed25078d849)
|
||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1799013
|
||
|
Message-Id: <f7b3a9cc523a22b9f1678483b6b8bf302ae7e1cc.1584391727.git.pkrempa@redhat.com>
|
||
|
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
||
|
---
|
||
|
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
|
||
|
|