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;
}
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
}
+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)
if (qemuProcessSetupDisksTransientSnapshot(vm, asyncJob) < 0)
return -1;
+ if (qemuProcessSetupDisksTransientHotplug(vm, asyncJob) < 0)
+ return -1;
+
return 0;
}
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;
}