From 55b21f9b23a330bdc581dd99d23987642235fcde Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Tue, 27 May 2014 13:30:04 +0200 Subject: [PATCH] qemu: Remove character device backend only after frontend is gone In general, we should only remove a backend after seeing DEVICE_DELETED event for a corresponding frontend. Signed-off-by: Jiri Denemark --- src/qemu/qemu_hotplug.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f3368040ec..9ea9ff64c1 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2742,22 +2742,40 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver, } -static void +static int qemuDomainRemoveChrDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainChrDefPtr chr) { virObjectEventPtr event; + char *charAlias = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret = -1; VIR_DEBUG("Removing character device %s from domain %p %s", chr->info.alias, vm, vm->def->name); + if (virAsprintf(&charAlias, "char%s", chr->info.alias) < 0) + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); + if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) { + qemuDomainObjExitMonitor(driver, vm); + goto cleanup; + } + qemuDomainObjExitMonitor(driver, vm); + event = virDomainEventDeviceRemovedNewFromObj(vm, chr->info.alias); if (event) qemuDomainEventQueue(driver, event); qemuDomainChrRemove(vm->def, chr); virDomainChrDefFree(chr); + ret = 0; + + cleanup: + VIR_FREE(charAlias); + return ret; } @@ -3596,7 +3614,6 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; virDomainDefPtr vmdef = vm->def; virDomainChrDefPtr tmpChr; - char *charAlias = NULL; char *devstr = NULL; int rc; @@ -3609,9 +3626,6 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0) return ret; - if (virAsprintf(&charAlias, "char%s", tmpChr->info.alias) < 0) - goto cleanup; - qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info); qemuDomainObjEnterMonitor(driver, vm); @@ -3619,21 +3633,16 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, qemuDomainObjExitMonitor(driver, vm); goto cleanup; } - - if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) { - qemuDomainObjExitMonitor(driver, vm); - goto cleanup; - } qemuDomainObjExitMonitor(driver, vm); rc = qemuDomainWaitForDeviceRemoval(vm); if (rc == 0 || rc == 1) - qemuDomainRemoveChrDevice(driver, vm, tmpChr); - ret = 0; + ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr); + else + ret = 0; cleanup: qemuDomainResetDeviceRemoval(vm); VIR_FREE(devstr); - VIR_FREE(charAlias); return ret; } -- GitLab