[RFC PATCH 6/7] qemu: Add check whether the transient disks are sharable

Masayoshi Mizuma msys.mizuma at gmail.com
Sat Jan 23 01:11:05 UTC 2021


From: Masayoshi Mizuma <m.mizuma at jp.fujitsu.com>

Check whether the transient disks are shareable or not.
If followings are true, the transient disks are shareable.

 - qemu has blockdev and hotplug feature
 - the all disk bus support hot-plug

Signed-off-by: Masayoshi Mizuma <m.mizuma at jp.fujitsu.com>
---
 src/qemu/qemu_command.c | 17 +++++++++++++----
 src/qemu/qemu_domain.h  |  3 +++
 src/qemu/qemu_process.c | 38 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 81a27703c5..d5958f46ef 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2063,10 +2063,14 @@ qemuBuildDiskCommandLine(virCommandPtr cmd,
                          const virDomainDef *def,
                          virDomainDiskDefPtr disk,
                          virQEMUCapsPtr qemuCaps,
-                         unsigned int bootindex)
+                         unsigned int bootindex,
+                         qemuDomainObjPrivatePtr priv)
 {
     g_autofree char *optstr = NULL;
 
+    if ((disk->transient) && (priv->TransientDiskSharable))
+        disk->src->readonly = true;
+
     if (qemuBuildDiskSourceCommandLine(cmd, disk, qemuCaps) < 0)
         return -1;
 
@@ -2084,6 +2088,10 @@ qemuBuildDiskCommandLine(virCommandPtr cmd,
     if (qemuCommandAddExtDevice(cmd, &disk->info) < 0)
         return -1;
 
+    /* All disks are hot-added later if TransientDiskSharable is true */
+    if (priv->TransientDiskSharable)
+        return 0;
+
     virCommandAddArg(cmd, "-device");
 
     if (!(optstr = qemuBuildDiskDeviceStr(def, disk, bootindex,
@@ -2098,7 +2106,8 @@ qemuBuildDiskCommandLine(virCommandPtr cmd,
 static int
 qemuBuildDisksCommandLine(virCommandPtr cmd,
                           const virDomainDef *def,
-                          virQEMUCapsPtr qemuCaps)
+                          virQEMUCapsPtr qemuCaps,
+                          qemuDomainObjPrivatePtr priv)
 {
     size_t i;
     unsigned int bootCD = 0;
@@ -2154,7 +2163,7 @@ qemuBuildDisksCommandLine(virCommandPtr cmd,
         if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
             bootindex = 0;
 
-        if (qemuBuildDiskCommandLine(cmd, def, disk, qemuCaps, bootindex) < 0)
+        if (qemuBuildDiskCommandLine(cmd, def, disk, qemuCaps, bootindex, priv) < 0)
             return -1;
     }
 
@@ -9935,7 +9944,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
                                               VIR_DOMAIN_CONTROLLER_TYPE_CCID) < 0)
         return NULL;
 
-    if (qemuBuildDisksCommandLine(cmd, def, qemuCaps) < 0)
+    if (qemuBuildDisksCommandLine(cmd, def, qemuCaps, priv) < 0)
         return NULL;
 
     if (qemuBuildFilesystemCommandLine(cmd, def, qemuCaps, priv) < 0)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 154339ef8f..37b050def4 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -267,6 +267,9 @@ struct _qemuDomainObjPrivate {
     /* prevent deletion of <transient> disk overlay files between startup and
      * succesful setup of the overlays */
     bool inhibitDiskTransientDelete;
+
+    /* True if the all transient disks are sharable */
+    bool TransientDiskSharable;
 };
 
 #define QEMU_DOMAIN_PRIVATE(vm) \
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f87a3c0f60..2e2d1c6fea 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6892,6 +6892,40 @@ qemuProcessEnablePerf(virDomainObjPtr vm)
     return 0;
 }
 
+static void
+qemuCheckTransientDiskSharable(virDomainObjPtr vm)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    bool hotplug = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG);
+    size_t i;
+
+    priv->TransientDiskSharable = false;
+
+    if (!hotplug)
+        return;
+
+    for (i = 0; i < vm->def->ndisks; i++) {
+        virDomainDiskDefPtr disk = vm->def->disks[i];
+
+        if (disk->transient && disk->bus != VIR_DOMAIN_DISK_BUS_LAST)
+             return;
+    }
+
+    priv->TransientDiskSharable = true;
+}
+
+static int
+qemuProcessCreateDisksTransient(virDomainObjPtr vm,
+                                qemuDomainAsyncJob asyncJob)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (priv->TransientDiskSharable)
+        return qemuHotplugCreateDisksTransient(vm, asyncJob);
+    else
+        return qemuSnapshotCreateDisksTransient(vm, asyncJob);
+}
+
 
 /**
  * qemuProcessLaunch:
@@ -6982,6 +7016,8 @@ qemuProcessLaunch(virConnectPtr conn,
                             incoming != NULL) < 0)
         goto cleanup;
 
+    qemuCheckTransientDiskSharable(vm);
+
     VIR_DEBUG("Building emulator command line");
     if (!(cmd = qemuBuildCommandLine(driver,
                                      qemuDomainLogContextGetManager(logCtxt),
@@ -7228,7 +7264,7 @@ qemuProcessLaunch(virConnectPtr conn,
         goto cleanup;
 
     VIR_DEBUG("Setting up transient disk");
-    if (qemuSnapshotCreateDisksTransient(vm, asyncJob) < 0)
+    if (qemuProcessCreateDisksTransient(vm, asyncJob) < 0)
         goto cleanup;
 
     ret = 0;
-- 
2.27.0




More information about the libvir-list mailing list