On Fri, Dec 22, 2017 at 04:04:03PM +0800, Chen Hanxiao wrote:
From: Chen Hanxiao <chenhanxiao(a)gmail.com>
We lacked of hot unplugging redirdev device.
This patch add support for it.
We could use detach-device --live now.
Signed-off-by: Chen Hanxiao <chenhanxiao(a)gmail.com>
---
v3:
use helper qemuDomainDelChardevTLSObjects
address John's comments
v2:
rebase on master
src/qemu/qemu_driver.c | 4 ++-
src/qemu/qemu_hotplug.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_hotplug.h | 4 +++
3 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97b194b05..a91288d4b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7787,6 +7787,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:
@@ -7796,7 +7799,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:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b79807300..724ee4f3f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4388,6 +4388,54 @@ 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,
@@ -5128,6 +5176,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);
If qemuDomainWaitForDeviceRemoval returns 0 (QEMU supports
DEVICE_DEL_EVENT and did not unplug the device in 5 seconds),
then libvirtd should remove the device asynchronnously, when the device
deletion event arrives.
qemuDomainRemoveRedirdevDevice needs to be also called from
qemuDomainRemoveDevice for that to happen.
Jan
+
+ cleanup:
+ qemuDomainResetDeviceRemoval(vm);
+ return ret;
+}
+
+
int
qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 3e0d618e0..9a0c057f1 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -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);
--
2.14.3
--
libvir-list mailing list
libvir-list(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list