/* Returns:
* -1 on error
* 0 when DEVICE_DELETED event is unsupported
- * 1 when device removal finished
- * 2 device removal did not finish in QEMU_REMOVAL_WAIT_TIME
+ * 1 when DEVICE_DELETED arrived before the timeout and the caller is
+ * responsible for finishing the removal
+ * 2 device removal did not finish in qemuDomainRemoveDeviceWaitTime
*/
static int
qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
return 1;
}
-void
+/* Returns:
+ * true there was a thread waiting for devAlias to be removed and this
+ * thread will take care of finishing the removal
+ * false the thread that started the removal is already gone and delegate
+ * finishing the removal to a new thread
+ */
+bool
qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
const char *devAlias)
{
if (STREQ_NULLABLE(priv->unpluggingDevice, devAlias)) {
qemuDomainResetDeviceRemoval(vm);
virCondSignal(&priv->unplugFinished);
+ return true;
}
+ return false;
}
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
char *drivestr = NULL;
+ int rc;
if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
virReportError(VIR_ERR_OPERATION_FAILED,
qemuDomainObjExitMonitor(driver, vm);
- if (!qemuDomainWaitForDeviceRemoval(vm))
+ rc = qemuDomainWaitForDeviceRemoval(vm);
+ if (rc == 0 || rc == 1)
qemuDomainRemoveDiskDevice(driver, vm, detach);
ret = 0;
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
char *drivestr = NULL;
+ int rc;
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
virReportError(VIR_ERR_OPERATION_FAILED,
qemuDomainObjExitMonitor(driver, vm);
- if (!qemuDomainWaitForDeviceRemoval(vm))
+ rc = qemuDomainWaitForDeviceRemoval(vm);
+ if (rc == 0 || rc == 1)
qemuDomainRemoveDiskDevice(driver, vm, detach);
ret = 0;
int idx, ret = -1;
virDomainControllerDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ int rc;
if ((idx = virDomainControllerFind(vm->def,
dev->data.controller->type,
}
qemuDomainObjExitMonitor(driver, vm);
- if (!qemuDomainWaitForDeviceRemoval(vm))
+ rc = qemuDomainWaitForDeviceRemoval(vm);
+ if (rc == 0 || rc == 1)
qemuDomainRemoveControllerDevice(driver, vm, detach);
ret = 0;
return -1;
}
- if (ret < 0)
+ if (ret < 0) {
virDomainAuditHostdev(vm, detach, "detach", false);
- else if (!qemuDomainWaitForDeviceRemoval(vm))
- qemuDomainRemoveHostDevice(driver, vm, detach);
+ } else {
+ int rc = qemuDomainWaitForDeviceRemoval(vm);
+ if (rc == 0 || rc == 1)
+ qemuDomainRemoveHostDevice(driver, vm, detach);
+ }
qemuDomainResetDeviceRemoval(vm);
qemuDomainObjPrivatePtr priv = vm->privateData;
int vlan;
char *hostnet_name = NULL;
+ int rc;
if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
goto cleanup;
}
qemuDomainObjExitMonitor(driver, vm);
- if (!qemuDomainWaitForDeviceRemoval(vm))
+ rc = qemuDomainWaitForDeviceRemoval(vm);
+ if (rc == 0 || rc == 1)
qemuDomainRemoveNetDevice(driver, vm, detach);
ret = 0;
virDomainChrDefPtr tmpChr;
char *charAlias = NULL;
char *devstr = NULL;
+ int rc;
if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
}
qemuDomainObjExitMonitor(driver, vm);
- if (!qemuDomainWaitForDeviceRemoval(vm))
+ rc = qemuDomainWaitForDeviceRemoval(vm);
+ if (rc == 0 || rc == 1)
qemuDomainRemoveChrDevice(driver, vm, tmpChr);
ret = 0;