From 105794cd434d815e483f87732f2084f55ae62c42 Mon Sep 17 00:00:00 2001 From: Boris Fiuczynski Date: Mon, 30 Nov 2015 12:06:01 +0100 Subject: [PATCH] qemu: Automatic SCSI controller creation in SCSI disk hotplug broken When a SCSI disk is hotplugged to a domain that does not have the required SCSI controller already defined and loaded the following internal error occurs error: Failed to attach device from scsi_disk.xml error: internal error: Could not find scsi controller with index 0 required for device Commit 0260506c added in method qemuBuildDriveDevStr a lookup of the controller alias. The internal error occurs because in method qemuDomainAttachSCSIDisk the automatic creation of the potentially missing SCSI controller occurs after calling qemuBuildDriveDevStr. This patch reverses the calling sequence. Signed-off-by: Boris Fiuczynski Reviewed-by: Bjoern Walk Reviewed-by: Stefan Zimmermann --- src/qemu/qemu_hotplug.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 8804d3d493..1a61701c49 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -607,16 +607,10 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn, goto error; } - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) - goto error; - if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps))) - goto error; - } - - if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps))) - goto error; - + /* Let's make sure our disk has a controller defined and loaded + * before trying add the disk. The controller the disk is going + * to use must exist before a qemu command line string is generated. + */ for (i = 0; i <= disk->info.addr.drive.controller; i++) { cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, i); if (!cont) @@ -628,6 +622,16 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn, and hence the above loop must iterate at least once. */ sa_assert(cont); + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) + goto error; + if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps))) + goto error; + } + + if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps))) + goto error; + if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) goto error;