[libvirt] [PATCH 0/3] Fix hot unplug of scsi_host hostdev

https://bugzilla.redhat.com/show_bug.cgi?id=1141732 Attempting to hot unplug a scsi_host device fails. The first patch resolves the issue (and has some details in the commit message). The second patch removes the now unnecessary virConnectPtr from various places. The third patch resolves a potential issue if aliases weren't defined and debugging is enabled by making the check for NULL first before trying to message rather than the other way around. John Ferlan (3): qemu: Fix hot unplug of SCSI_HOST device qemu: Remove need for virConnectPtr in hotunplug detach host, net qemu: Remove possible NULL deref in debug output src/qemu/qemu_driver.c | 4 +-- src/qemu/qemu_hotplug.c | 70 +++++++++++++++++++++++-------------------------- src/qemu/qemu_hotplug.h | 6 ++--- 3 files changed, 37 insertions(+), 43 deletions(-) -- 1.9.3

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@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); + 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; } -- 1.9.3

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@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; }

On 10/03/2014 12:06 PM, Laine Stump wrote:
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@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 @@ (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.
Oh yeah - right - this needs a "if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)" around it... $ git diff -w diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 55f4bb3..0bd4e8a 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2630,6 +2630,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, VIR_DEBUG("Removing host device %s from domain %p %s", hostdev->info->alias, vm, vm->def->name); + if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) { /* build the actual drive id string as generated during * qemuBuildSCSIHostdevDrvStr that is passed to qemu */ if (virAsprintf(&drivestr, "%s-%s", @@ -2640,6 +2641,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, qemuDomainObjEnterMonitor(driver, vm); qemuMonitorDriveDel(priv->mon, drivestr); qemuDomainObjExitMonitor(driver, vm); + } event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias); if (event) OK?
(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?)
To make them available to the host again? If I follow the history - I see commit '53f3739a' makes the standalone function 'qemuDomainRemoveSCSIHostDevice' from what used to be an inline call to ReAttach added by commit id '8f76ad99'. The original ReAttach was added via commit 'ea74c076' (searching for Scsi instead of SCSI). It seems from the commit id comment, the code was added to be just like PCI and USB. John
+ 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; }

On 10/06/2014 09:36 AM, John Ferlan wrote:
On 10/03/2014 12:06 PM, Laine Stump wrote:
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@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 @@ (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.
Oh yeah - right - this needs a "if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)" around it...
$ git diff -w diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 55f4bb3..0bd4e8a 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2630,6 +2630,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, VIR_DEBUG("Removing host device %s from domain %p %s", hostdev->info->alias, vm, vm->def->name);
+ if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) { /* build the actual drive id string as generated during * qemuBuildSCSIHostdevDrvStr that is passed to qemu */ if (virAsprintf(&drivestr, "%s-%s", @@ -2640,6 +2641,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, qemuDomainObjEnterMonitor(driver, vm); qemuMonitorDriveDel(priv->mon, drivestr); qemuDomainObjExitMonitor(driver, vm); + }
event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias); if (event)
OK?
OK. ACK. It's too bad that it can't just be a part of the switch statement further down in the same function, but I think this needs to be done prior to queuing the event.
(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?)
To make them available to the host again?
If I follow the history - I see commit '53f3739a' makes the standalone function 'qemuDomainRemoveSCSIHostDevice' from what used to be an inline call to ReAttach added by commit id '8f76ad99'. The original ReAttach was added via commit 'ea74c076' (searching for Scsi instead of SCSI).
Yeah, never mind. It had been just a tad too long since I looked at this code, and I forgot the confusing nomenclature of "ReAttach", which is talking about reattaching the device to a host-side driver, *not* reattaching it to the guest. (I suffered the same confusion the first time I dug into this code, you'd think that I would remember it from that...)
It seems from the commit id comment, the code was added to be just like PCI and USB.
John
+ 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; }

Prior patch removed the need for the virConnectPtr in the unplug detach host path which caused ripple effect to remove in multiple callers. The previous patch just left things as ATTRIBUTE_UNUSED - this patch will remove the variable. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_hotplug.h | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e73d4f9..c98e42f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6758,10 +6758,10 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, ret = qemuDomainDetachLease(driver, vm, dev->data.lease); break; case VIR_DOMAIN_DEVICE_NET: - ret = qemuDomainDetachNetDevice(dom->conn, driver, vm, dev); + ret = qemuDomainDetachNetDevice(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_HOSTDEV: - ret = qemuDomainDetachHostDevice(dom->conn, driver, vm, dev); + ret = qemuDomainDetachHostDevice(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr); diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 55c9333..1c9ca8f 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -78,12 +78,10 @@ int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -int qemuDomainDetachNetDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -int qemuDomainDetachHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); int qemuDomainAttachLease(virQEMUDriverPtr driver, -- 1.9.3

On 09/24/2014 09:11 AM, John Ferlan wrote:
Prior patch removed the need for the virConnectPtr in the unplug detach host path which caused ripple effect to remove in multiple callers. The previous patch just left things as ATTRIBUTE_UNUSED - this patch will remove the variable.
Signed-off-by: John Ferlan <jferlan@redhat.com>
UG.... Looks like I have to squash most parts of 3/3 into here... For review/build purposes just combine the two - I'll do the right thing for commit... Off for another cup o joe to see if that helps :-) John
--- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_hotplug.h | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e73d4f9..c98e42f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6758,10 +6758,10 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, ret = qemuDomainDetachLease(driver, vm, dev->data.lease); break; case VIR_DOMAIN_DEVICE_NET: - ret = qemuDomainDetachNetDevice(dom->conn, driver, vm, dev); + ret = qemuDomainDetachNetDevice(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_HOSTDEV: - ret = qemuDomainDetachHostDevice(dom->conn, driver, vm, dev); + ret = qemuDomainDetachHostDevice(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr); diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 55c9333..1c9ca8f 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -78,12 +78,10 @@ int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -int qemuDomainDetachNetDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -int qemuDomainDetachHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); int qemuDomainAttachLease(virQEMUDriverPtr driver,

Prior patch removed the need for the virConnectPtr in the unplug detach host path which caused ripple effect to remove in multiple callers. The previous patch just left things as ATTRIBUTE_UNUSED - this patch will remove the variable. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_hotplug.c | 20 ++++++++------------ src/qemu/qemu_hotplug.h | 6 ++---- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e73d4f9..c98e42f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6758,10 +6758,10 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, ret = qemuDomainDetachLease(driver, vm, dev->data.lease); break; case VIR_DOMAIN_DEVICE_NET: - ret = qemuDomainDetachNetDevice(dom->conn, driver, vm, dev); + ret = qemuDomainDetachNetDevice(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_HOSTDEV: - ret = qemuDomainDetachHostDevice(dom->conn, driver, vm, dev); + ret = qemuDomainDetachHostDevice(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index cf1e4dc..8011a83 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3323,8 +3323,7 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, } static int -qemuDomainDetachHostSCSIDevice(virConnectPtr conn ATTRIBUTE_UNUSED, - virQEMUDriverPtr driver, +qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainHostdevDefPtr detach) { @@ -3358,8 +3357,7 @@ qemuDomainDetachHostSCSIDevice(virConnectPtr conn ATTRIBUTE_UNUSED, } static int -qemuDomainDetachThisHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainHostdevDefPtr detach) { @@ -3373,7 +3371,7 @@ qemuDomainDetachThisHostDevice(virConnectPtr conn, ret = qemuDomainDetachHostUSBDevice(driver, vm, detach); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - ret = qemuDomainDetachHostSCSIDevice(conn, driver, vm, detach); + ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach); break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -3396,8 +3394,7 @@ qemuDomainDetachThisHostDevice(virConnectPtr conn, } /* search for a hostdev matching dev and detach it */ -int qemuDomainDetachHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev) { @@ -3466,14 +3463,13 @@ int qemuDomainDetachHostDevice(virConnectPtr conn, * function so that mac address / virtualport are reset */ if (detach->parent.type == VIR_DOMAIN_DEVICE_NET) - return qemuDomainDetachNetDevice(conn, driver, vm, &detach->parent); + return qemuDomainDetachNetDevice(driver, vm, &detach->parent); else - return qemuDomainDetachThisHostDevice(conn, driver, vm, detach); + return qemuDomainDetachThisHostDevice(driver, vm, detach); } int -qemuDomainDetachNetDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev) { @@ -3489,7 +3485,7 @@ qemuDomainDetachNetDevice(virConnectPtr conn, if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) { /* coverity[negative_returns] */ - ret = qemuDomainDetachThisHostDevice(conn, driver, vm, + ret = qemuDomainDetachThisHostDevice(driver, vm, virDomainNetGetActualHostdev(detach)); goto cleanup; } diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 55c9333..1c9ca8f 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -78,12 +78,10 @@ int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -int qemuDomainDetachNetDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -int qemuDomainDetachHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); int qemuDomainAttachLease(virQEMUDriverPtr driver, -- 1.9.3

On 09/24/2014 09:25 AM, John Ferlan wrote:
Prior patch removed the need for the virConnectPtr in the unplug detach host path which caused ripple effect to remove in multiple callers. The previous patch just left things as ATTRIBUTE_UNUSED - this patch will remove the variable.
Signed-off-by: John Ferlan <jferlan@redhat.com> ---
ACK.

Check for !dev->info.alias was done after a VIR_DEBUG() statement that already tried to print - just flip sequence Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_hotplug.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index cf1e4dc..d158a73 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1887,14 +1887,14 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver, int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; - VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate); - if (!dev->info.alias) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("can't change link state: device alias not found")); return -1; } + VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate); + qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate); @@ -3323,8 +3323,7 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, } static int -qemuDomainDetachHostSCSIDevice(virConnectPtr conn ATTRIBUTE_UNUSED, - virQEMUDriverPtr driver, +qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainHostdevDefPtr detach) { @@ -3358,8 +3357,7 @@ qemuDomainDetachHostSCSIDevice(virConnectPtr conn ATTRIBUTE_UNUSED, } static int -qemuDomainDetachThisHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainHostdevDefPtr detach) { @@ -3373,7 +3371,7 @@ qemuDomainDetachThisHostDevice(virConnectPtr conn, ret = qemuDomainDetachHostUSBDevice(driver, vm, detach); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - ret = qemuDomainDetachHostSCSIDevice(conn, driver, vm, detach); + ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach); break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -3396,8 +3394,7 @@ qemuDomainDetachThisHostDevice(virConnectPtr conn, } /* search for a hostdev matching dev and detach it */ -int qemuDomainDetachHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev) { @@ -3466,14 +3463,13 @@ int qemuDomainDetachHostDevice(virConnectPtr conn, * function so that mac address / virtualport are reset */ if (detach->parent.type == VIR_DOMAIN_DEVICE_NET) - return qemuDomainDetachNetDevice(conn, driver, vm, &detach->parent); + return qemuDomainDetachNetDevice(driver, vm, &detach->parent); else - return qemuDomainDetachThisHostDevice(conn, driver, vm, detach); + return qemuDomainDetachThisHostDevice(driver, vm, detach); } int -qemuDomainDetachNetDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev) { @@ -3489,7 +3485,7 @@ qemuDomainDetachNetDevice(virConnectPtr conn, if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) { /* coverity[negative_returns] */ - ret = qemuDomainDetachThisHostDevice(conn, driver, vm, + ret = qemuDomainDetachThisHostDevice(driver, vm, virDomainNetGetActualHostdev(detach)); goto cleanup; } -- 1.9.3

Check for !dev->info.alias was done after a VIR_DEBUG() statement that already tried to print - just flip sequence Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_hotplug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 8011a83..d158a73 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1887,14 +1887,14 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver, int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; - VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate); - if (!dev->info.alias) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("can't change link state: device alias not found")); return -1; } + VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate); + qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate); -- 1.9.3

On 09/24/2014 09:27 AM, John Ferlan wrote:
Check for !dev->info.alias was done after a VIR_DEBUG() statement that already tried to print - just flip sequence
Signed-off-by: John Ferlan <jferlan@redhat.com> ---
ACK to this re-arranged version
src/qemu/qemu_hotplug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 8011a83..d158a73 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1887,14 +1887,14 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver, int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData;
- VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate); - if (!dev->info.alias) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("can't change link state: device alias not found")); return -1; }
+ VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate); + qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);

On 09/24/2014 09:11 AM, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1141732
Attempting to hot unplug a scsi_host device fails. The first patch resolves the issue (and has some details in the commit message). The second patch removes the now unnecessary virConnectPtr from various places. The third patch resolves a potential issue if aliases weren't defined and debugging is enabled by making the check for NULL first before trying to message rather than the other way around.
John Ferlan (3): qemu: Fix hot unplug of SCSI_HOST device qemu: Remove need for virConnectPtr in hotunplug detach host, net qemu: Remove possible NULL deref in debug output
src/qemu/qemu_driver.c | 4 +-- src/qemu/qemu_hotplug.c | 70 +++++++++++++++++++++++-------------------------- src/qemu/qemu_hotplug.h | 6 ++--- 3 files changed, 37 insertions(+), 43 deletions(-)
Now that 1.2.9 is out - ping? Tks, John

On 09/24/2014 09:11 AM, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1141732
Attempting to hot unplug a scsi_host device fails. The first patch resolves the issue (and has some details in the commit message). The second patch removes the now unnecessary virConnectPtr from various places. The third patch resolves a potential issue if aliases weren't defined and debugging is enabled by making the check for NULL first before trying to message rather than the other way around.
John Ferlan (3): qemu: Fix hot unplug of SCSI_HOST device qemu: Remove need for virConnectPtr in hotunplug detach host, net qemu: Remove possible NULL deref in debug output
src/qemu/qemu_driver.c | 4 +-- src/qemu/qemu_hotplug.c | 70 +++++++++++++++++++++++-------------------------- src/qemu/qemu_hotplug.h | 6 ++--- 3 files changed, 37 insertions(+), 43 deletions(-)
Series pushed - thanks for review John
participants (2)
-
John Ferlan
-
Laine Stump