Pablo Greco 40546a
From a86cb3601add390b718377be021128fc18e4c9b2 Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <a86cb3601add390b718377be021128fc18e4c9b2@dist-git>
Pablo Greco 40546a
From: Michal Privoznik <mprivozn@redhat.com>
Pablo Greco 40546a
Date: Thu, 27 Jun 2019 14:44:47 +0200
Pablo Greco 40546a
Subject: [PATCH] qemu_hotplug: Detach guestfwd using netdev_del
Pablo Greco 40546a
Pablo Greco 40546a
The guestfwd channels are -netdevs really. Hotunplug them as
Pablo Greco 40546a
such. Also, DEVICE_DELETED event is not triggered (surprisingly,
Pablo Greco 40546a
since we're not issuing device_del rather than netdev_del) and
Pablo Greco 40546a
associated chardev is removed automagically too. This means that
Pablo Greco 40546a
we need to do qemuDomainRemoveChrDevice() minus monitor call to
Pablo Greco 40546a
remove the chardev.
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Pablo Greco 40546a
Reviewed-by: John Ferlan <jferlan@redhat.com>
Pablo Greco 40546a
(cherry picked from commit 112f3a8d0f324c0705326957cca4508602b25eba)
Pablo Greco 40546a
Pablo Greco 40546a
https://bugzilla.redhat.com/show_bug.cgi?id=1624204
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Pablo Greco 40546a
Message-Id: <de45d53975997bcdbb4260055664a7b0a0079bbe.1561639408.git.mprivozn@redhat.com>
Pablo Greco 40546a
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/qemu/qemu_hotplug.c | 48 ++++++++++++++++++++++++++++-------------
Pablo Greco 40546a
 1 file changed, 33 insertions(+), 15 deletions(-)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
Pablo Greco 40546a
index 468389fa7a..05489cf116 100644
Pablo Greco 40546a
--- a/src/qemu/qemu_hotplug.c
Pablo Greco 40546a
+++ b/src/qemu/qemu_hotplug.c
Pablo Greco 40546a
@@ -4355,25 +4355,28 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
Pablo Greco 40546a
                           virDomainObjPtr vm,
Pablo Greco 40546a
-                          virDomainChrDefPtr chr)
Pablo Greco 40546a
+                          virDomainChrDefPtr chr,
Pablo Greco 40546a
+                          bool monitor)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     virObjectEventPtr event;
Pablo Greco 40546a
     char *charAlias = NULL;
Pablo Greco 40546a
     qemuDomainObjPrivatePtr priv = vm->privateData;
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
-    int rc;
Pablo Greco 40546a
+    int rc = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
     VIR_DEBUG("Removing character device %s from domain %p %s",
Pablo Greco 40546a
               chr->info.alias, vm, vm->def->name);
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias)))
Pablo Greco 40546a
-        goto cleanup;
Pablo Greco 40546a
+    if (monitor) {
Pablo Greco 40546a
+        if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias)))
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    qemuDomainObjEnterMonitor(driver, vm);
Pablo Greco 40546a
-    rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
Pablo Greco 40546a
+        qemuDomainObjEnterMonitor(driver, vm);
Pablo Greco 40546a
+        rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
Pablo Greco 40546a
-        goto cleanup;
Pablo Greco 40546a
+        if (qemuDomainObjExitMonitor(driver, vm) < 0)
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (rc == 0 &&
Pablo Greco 40546a
         qemuDomainDelChardevTLSObjects(driver, vm, chr->source, charAlias) < 0)
Pablo Greco 40546a
@@ -4674,7 +4677,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
Pablo Greco 40546a
         break;
Pablo Greco 40546a
 
Pablo Greco 40546a
     case VIR_DOMAIN_DEVICE_CHR:
Pablo Greco 40546a
-        ret = qemuDomainRemoveChrDevice(driver, vm, dev->data.chr);
Pablo Greco 40546a
+        ret = qemuDomainRemoveChrDevice(driver, vm, dev->data.chr, true);
Pablo Greco 40546a
         break;
Pablo Greco 40546a
     case VIR_DOMAIN_DEVICE_RNG:
Pablo Greco 40546a
         ret = qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng);
Pablo Greco 40546a
@@ -5749,6 +5752,7 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
Pablo Greco 40546a
     virDomainDefPtr vmdef = vm->def;
Pablo Greco 40546a
     virDomainChrDefPtr tmpChr;
Pablo Greco 40546a
     char *devstr = NULL;
Pablo Greco 40546a
+    bool guestfwd = false;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
Pablo Greco 40546a
         virReportError(VIR_ERR_DEVICE_MISSING,
Pablo Greco 40546a
@@ -5758,6 +5762,11 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
+    /* guestfwd channels are not really -device rather than
Pablo Greco 40546a
+     * -netdev. We need to treat them slightly differently. */
Pablo Greco 40546a
+    guestfwd = tmpChr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
Pablo Greco 40546a
+               tmpChr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD;
Pablo Greco 40546a
+
Pablo Greco 40546a
     if (!tmpChr->info.alias && qemuAssignDeviceChrAlias(vmdef, tmpChr, -1) < 0)
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -5766,22 +5775,31 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
Pablo Greco 40546a
     if (qemuBuildChrDeviceStr(&devstr, vmdef, tmpChr, priv->qemuCaps) < 0)
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (!async)
Pablo Greco 40546a
+    if (!async && !guestfwd)
Pablo Greco 40546a
         qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
Pablo Greco 40546a
 
Pablo Greco 40546a
     qemuDomainObjEnterMonitor(driver, vm);
Pablo Greco 40546a
-    if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
Pablo Greco 40546a
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
Pablo Greco 40546a
-        goto cleanup;
Pablo Greco 40546a
+    if (guestfwd) {
Pablo Greco 40546a
+        if (qemuMonitorRemoveNetdev(priv->mon, tmpChr->info.alias) < 0) {
Pablo Greco 40546a
+            ignore_value(qemuDomainObjExitMonitor(driver, vm));
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    } else {
Pablo Greco 40546a
+        if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
Pablo Greco 40546a
+            ignore_value(qemuDomainObjExitMonitor(driver, vm));
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
     }
Pablo Greco 40546a
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (async) {
Pablo Greco 40546a
+    if (guestfwd) {
Pablo Greco 40546a
+        ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr, false);
Pablo Greco 40546a
+    } else if (async) {
Pablo Greco 40546a
         ret = 0;
Pablo Greco 40546a
     } else {
Pablo Greco 40546a
         if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
Pablo Greco 40546a
-            ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr);
Pablo Greco 40546a
+            ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr, true);
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a