[libvirt] [PATCH 1/3] qemu: Fix hot unplug of SCSI_HOST device
Laine Stump
laine at laine.org
Fri Oct 3 16:06:41 UTC 2014
On 09/24/2014 09:11 AM, John Ferlan wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1141732
>
> Introduced by commit id '8f76ad99' the logic to detach a scsi_host
> device (SCSI or iSCSI) fails when attempting to remove the 'drive'
> because as I found in my investigation - the DelDevice takes care of
> that for us.
>
> The investigation turned up commits to adjust the logic for the
> qemuMonitorDelDevice and qemuMonitorDriveDel processing for interfaces
> (commit id '81f76598'), disk bus=VIRTIO,SCSI,USB (commit id '0635785b'),
> and chr devices (commit id '55b21f9b'), but nothing with the host devices.
>
> This commit uses the model for the previous set of changes and applies
> it to the hostdev path. The call to qemuDomainDetachHostSCSIDevice will
> return to qemuDomainDetachThisHostDevice handling either the audit of
> the failure or the wait for the removal and then call into
> qemuDomainRemoveHostDevice for the event, removal from the domain hostdev
> list, and audit of the removal similar to other paths.
>
> NOTE: For now the 'conn' param to +qemuDomainDetachHostSCSIDevice is left
> as ATTRIBUTE_UNUSED. Removing requires a cascade of other changes to be
> left for a future patch.
>
> Signed-off-by: John Ferlan <jferlan at redhat.com>
> ---
> src/qemu/qemu_hotplug.c | 48 ++++++++++++++++++++++++------------------------
> 1 file changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 7bc19cd..cf1e4dc 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -2623,10 +2623,24 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
> virDomainNetDefPtr net = NULL;
> virObjectEventPtr event;
> size_t i;
> + int ret = -1;
> + qemuDomainObjPrivatePtr priv = vm->privateData;
> + char *drivestr;
>
> VIR_DEBUG("Removing host device %s from domain %p %s",
> hostdev->info->alias, vm, vm->def->name);
>
> + /* build the actual drive id string as generated during
> + * qemuBuildSCSIHostdevDrvStr that is passed to qemu */
> + if (virAsprintf(&drivestr, "%s-%s",
> + virDomainDeviceAddressTypeToString(hostdev->info->type),
> + hostdev->info->alias) < 0)
> + goto cleanup;
> +
> + qemuDomainObjEnterMonitor(driver, vm);
> + qemuMonitorDriveDel(priv->mon, drivestr);
> + qemuDomainObjExitMonitor(driver, vm);
I think this function is used by devices other than just SCSI host
devices, which I *think* means you are breaking proper detach of those
other kinds of devices.
(beyond that, but unrelated to your changes - I don't understand why
qemuDomainRemoveSCSIHostDevice() (which is already called by
qemuDomainRemoveHostDevice in the switch at the bottom) calls
qemuDomain*ReAttach*HostSCSIDevices(). What's up with that?)
> +
> event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias);
> if (event)
> qemuDomainEventQueue(driver, event);
> @@ -2679,8 +2693,12 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
> networkReleaseActualDevice(vm->def, net);
> virDomainNetDefFree(net);
> }
> + ret = 0;
> +
> + cleanup:
> + VIR_FREE(drivestr);
> virObjectUnref(cfg);
> - return 0;
> + return ret;
> }
>
>
> @@ -3305,14 +3323,12 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
> }
>
> static int
> -qemuDomainDetachHostSCSIDevice(virConnectPtr conn,
> +qemuDomainDetachHostSCSIDevice(virConnectPtr conn ATTRIBUTE_UNUSED,
> virQEMUDriverPtr driver,
> virDomainObjPtr vm,
> virDomainHostdevDefPtr detach)
> {
> qemuDomainObjPrivatePtr priv = vm->privateData;
> - char *drvstr = NULL;
> - char *devstr = NULL;
> int ret = -1;
>
> if (!detach->info->alias) {
> @@ -3327,33 +3343,17 @@ qemuDomainDetachHostSCSIDevice(virConnectPtr conn,
> return -1;
> }
>
> - if (!(drvstr = qemuBuildSCSIHostdevDrvStr(conn, detach, priv->qemuCaps,
> - &buildCommandLineCallbacks)))
> - goto cleanup;
> - if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
> - goto cleanup;
> -
> qemuDomainMarkDeviceForRemoval(vm, detach->info);
>
> qemuDomainObjEnterMonitor(driver, vm);
> - if ((ret = qemuMonitorDelDevice(priv->mon, detach->info->alias)) == 0) {
> - if ((ret = qemuMonitorDriveDel(priv->mon, drvstr)) < 0) {
> - virErrorPtr orig_err = virSaveLastError();
> - if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
> - VIR_WARN("Unable to add device %s (%s) after failed "
> - "qemuMonitorDriveDel",
> - drvstr, devstr);
> - if (orig_err) {
> - virSetError(orig_err);
> - virFreeError(orig_err);
> - }
> - }
> + if (qemuMonitorDelDevice(priv->mon, detach->info->alias) < 0) {
> + qemuDomainObjExitMonitor(driver, vm);
> + goto cleanup;
> }
> qemuDomainObjExitMonitor(driver, vm);
> + ret = 0;
>
> cleanup:
> - VIR_FREE(drvstr);
> - VIR_FREE(devstr);
> return ret;
> }
>
More information about the libvir-list
mailing list