From: Masayoshi Mizuma <m.mizuma@xxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxx> --- 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