mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 01:45:17 +00:00
qemu: Allow <transient> disks with images shared accross VMs
Implement this behaviour by skipping the disks on traditional commandline and hotplug them before resuming CPUs. That allows to use the support for hotplugging of transient disks which inherently allows sharing of the backing image as we open it read-only. This commit implements the validation code to allow it only with buses supporting hotplug and the hotplug code while starting up the VM. When we have such disk we need to issue a system-reset so that firmware tables are regenerated to allow booting from such device. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
parent
be63e8703c
commit
75871da0ec
@ -2164,6 +2164,12 @@ qemuBuildDisksCommandLine(virCommand *cmd,
|
||||
for (i = 0; i < def->ndisks; i++) {
|
||||
virDomainDiskDef *disk = def->disks[i];
|
||||
|
||||
/* transient disks with shared backing image will be hotplugged after
|
||||
* the VM is started */
|
||||
if (disk->transient &&
|
||||
disk->transientShareBacking == VIR_TRISTATE_BOOL_YES)
|
||||
continue;
|
||||
|
||||
if (qemuBuildDiskCommandLine(cmd, def, disk, qemuCaps) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
@ -7016,7 +7016,8 @@ qemuProcessSetupDisksTransientSnapshot(virDomainObj *vm,
|
||||
virDomainDiskDef *domdisk = vm->def->disks[i];
|
||||
g_autoptr(virDomainSnapshotDiskDef) snapdisk = NULL;
|
||||
|
||||
if (!domdisk->transient)
|
||||
if (!domdisk->transient ||
|
||||
domdisk->transientShareBacking == VIR_TRISTATE_BOOL_YES)
|
||||
continue;
|
||||
|
||||
/* validation code makes sure that we do this only for local disks
|
||||
@ -7048,6 +7049,45 @@ qemuProcessSetupDisksTransientSnapshot(virDomainObj *vm,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuProcessSetupDisksTransientHotplug(virDomainObj *vm,
|
||||
qemuDomainAsyncJob asyncJob)
|
||||
{
|
||||
qemuDomainObjPrivate *priv = vm->privateData;
|
||||
bool hasHotpluggedDisk = false;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < vm->def->ndisks; i++) {
|
||||
virDomainDiskDef *domdisk = vm->def->disks[i];
|
||||
|
||||
if (!domdisk->transient ||
|
||||
domdisk->transientShareBacking != VIR_TRISTATE_BOOL_YES)
|
||||
continue;
|
||||
|
||||
if (qemuDomainAttachDiskGeneric(priv->driver, vm, domdisk, asyncJob) < 0)
|
||||
return -1;
|
||||
|
||||
hasHotpluggedDisk = true;
|
||||
}
|
||||
|
||||
/* in order to allow booting from such disks we need to issue a system-reset
|
||||
* so that the firmware tables recording bootable devices are regerated */
|
||||
if (hasHotpluggedDisk) {
|
||||
int rc;
|
||||
|
||||
if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0)
|
||||
return -1;
|
||||
|
||||
rc = qemuMonitorSystemReset(priv->mon);
|
||||
|
||||
if (qemuDomainObjExitMonitor(priv->driver, vm) < 0 || rc < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuProcessSetupDisksTransient(virDomainObj *vm,
|
||||
qemuDomainAsyncJob asyncJob)
|
||||
@ -7060,6 +7100,9 @@ qemuProcessSetupDisksTransient(virDomainObj *vm,
|
||||
if (qemuProcessSetupDisksTransientSnapshot(vm, asyncJob) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuProcessSetupDisksTransientHotplug(vm, asyncJob) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2980,6 +2980,30 @@ qemuValidateDomainDeviceDefDiskTransient(const virDomainDiskDef *disk,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (disk->transientShareBacking == VIR_TRISTATE_BOOL_YES) {
|
||||
/* sharing the backing file requires hotplug of the disk in the qemu driver */
|
||||
switch (disk->bus) {
|
||||
case VIR_DOMAIN_DISK_BUS_USB:
|
||||
case VIR_DOMAIN_DISK_BUS_VIRTIO:
|
||||
case VIR_DOMAIN_DISK_BUS_SCSI:
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DISK_BUS_IDE:
|
||||
case VIR_DOMAIN_DISK_BUS_FDC:
|
||||
case VIR_DOMAIN_DISK_BUS_XEN:
|
||||
case VIR_DOMAIN_DISK_BUS_UML:
|
||||
case VIR_DOMAIN_DISK_BUS_SATA:
|
||||
case VIR_DOMAIN_DISK_BUS_SD:
|
||||
case VIR_DOMAIN_DISK_BUS_NONE:
|
||||
case VIR_DOMAIN_DISK_BUS_LAST:
|
||||
default:
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("disk bus '%s' doesn't support transiend disk backing image sharing"),
|
||||
virDomainDiskBusTypeToString(disk->bus));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user