From: Masayoshi Mizuma <m.mizuma(a)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(a)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