mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-08-31 09:50:07 +03: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:
committed by
John Ferlan
parent
a63ea8141b
commit
91a3234f3a
@ -7799,6 +7799,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
|||||||
case VIR_DOMAIN_DEVICE_INPUT:
|
case VIR_DOMAIN_DEVICE_INPUT:
|
||||||
ret = qemuDomainDetachInputDevice(vm, dev->data.input);
|
ret = qemuDomainDetachInputDevice(vm, dev->data.input);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
||||||
|
ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev);
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
case VIR_DOMAIN_DEVICE_SOUND:
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
@ -7808,7 +7811,6 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
|||||||
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
||||||
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
||||||
case VIR_DOMAIN_DEVICE_NVRAM:
|
case VIR_DOMAIN_DEVICE_NVRAM:
|
||||||
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_TPM:
|
case VIR_DOMAIN_DEVICE_TPM:
|
||||||
case VIR_DOMAIN_DEVICE_PANIC:
|
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
|
int
|
||||||
qemuDomainRemoveDevice(virQEMUDriverPtr driver,
|
qemuDomainRemoveDevice(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
@ -4438,6 +4485,10 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
|
|||||||
ret = qemuDomainRemoveInputDevice(vm, dev->data.input);
|
ret = qemuDomainRemoveInputDevice(vm, dev->data.input);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
||||||
|
ret = qemuDomainRemoveRedirdevDevice(driver, vm, dev->data.redirdev);
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_LEASE:
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
@ -4446,7 +4497,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
|
|||||||
case VIR_DOMAIN_DEVICE_WATCHDOG:
|
case VIR_DOMAIN_DEVICE_WATCHDOG:
|
||||||
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
||||||
case VIR_DOMAIN_DEVICE_HUB:
|
case VIR_DOMAIN_DEVICE_HUB:
|
||||||
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
|
||||||
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
||||||
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
||||||
case VIR_DOMAIN_DEVICE_NVRAM:
|
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
|
int
|
||||||
qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
|
@ -126,6 +126,10 @@ int qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
|
|||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainWatchdogDefPtr watchdog);
|
virDomainWatchdogDefPtr watchdog);
|
||||||
|
|
||||||
|
int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainRedirdevDefPtr dev);
|
||||||
|
|
||||||
int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
|
int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainInputDefPtr input);
|
virDomainInputDefPtr input);
|
||||||
|
Reference in New Issue
Block a user