qemu: Add support for hot unplugging redirdev device

Commit id '162efa1a' added support hotplug a redirdev, but
did not add the hot unplug. This patch will add that support
to allow usage of the detach-device --live on the device.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
This commit is contained in:
Chen Hanxiao 2018-01-05 10:47:47 +08:00 committed by John Ferlan
parent a63ea8141b
commit 91a3234f3a
3 changed files with 101 additions and 2 deletions

View File

@ -7799,6 +7799,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_INPUT:
ret = qemuDomainDetachInputDevice(vm, dev->data.input);
break;
case VIR_DOMAIN_DEVICE_REDIRDEV:
ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev);
break;
case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_SOUND:
@ -7808,7 +7811,6 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_REDIRDEV:
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:

View File

@ -4399,6 +4399,53 @@ qemuDomainRemoveInputDevice(virDomainObjPtr vm,
}
static int
qemuDomainRemoveRedirdevDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainRedirdevDefPtr dev)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
virObjectEventPtr event;
char *charAlias = NULL;
ssize_t idx;
int ret = -1;
VIR_DEBUG("Removing redirdev device %s from domain %p %s",
dev->info.alias, vm, vm->def->name);
if (!(charAlias = qemuAliasChardevFromDevAlias(dev->info.alias)))
goto cleanup;
qemuDomainObjEnterMonitor(driver, vm);
/* DeviceDel from Detach may remove chardev,
* so we cannot rely on return status to delete TLS chardevs.
*/
ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup;
if (qemuDomainDelChardevTLSObjects(driver, vm, dev->source, charAlias) < 0)
goto cleanup;
virDomainAuditRedirdev(vm, dev, "detach", true);
event = virDomainEventDeviceRemovedNewFromObj(vm, dev->info.alias);
qemuDomainEventQueue(driver, event);
if ((idx = virDomainRedirdevDefFind(vm->def, dev)) >= 0)
virDomainRedirdevDefRemove(vm->def, idx);
qemuDomainReleaseDeviceAddress(vm, &dev->info, NULL);
virDomainRedirdevDefFree(dev);
ret = 0;
cleanup:
VIR_FREE(charAlias);
return ret;
}
int
qemuDomainRemoveDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
@ -4438,6 +4485,10 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
ret = qemuDomainRemoveInputDevice(vm, dev->data.input);
break;
case VIR_DOMAIN_DEVICE_REDIRDEV:
ret = qemuDomainRemoveRedirdevDevice(driver, vm, dev->data.redirdev);
break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_FS:
@ -4446,7 +4497,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_DEVICE_WATCHDOG:
case VIR_DOMAIN_DEVICE_GRAPHICS:
case VIR_DOMAIN_DEVICE_HUB:
case VIR_DOMAIN_DEVICE_REDIRDEV:
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
@ -5139,6 +5189,49 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
}
int
qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainRedirdevDefPtr dev)
{
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainRedirdevDefPtr tmpRedirdevDef;
ssize_t idx;
if ((idx = virDomainRedirdevDefFind(vm->def, dev)) < 0) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("no matching redirdev was not found"));
return -1;
}
tmpRedirdevDef = vm->def->redirdevs[idx];
if (!tmpRedirdevDef->info.alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("alias not set for redirdev device"));
return -1;
}
qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) {
ignore_value(qemuDomainObjExitMonitor(driver, vm));
goto cleanup;
}
if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
cleanup:
qemuDomainResetDeviceRemoval(vm);
return ret;
}
int
qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,

View File

@ -126,6 +126,10 @@ int qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainWatchdogDefPtr watchdog);
int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainRedirdevDefPtr dev);
int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainInputDefPtr input);