mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 19:45:21 +00:00
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:
parent
a63ea8141b
commit
91a3234f3a
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user