]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu_hotplug: Close FDs in QEMU on failed chardev hotplug
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 18 Jul 2022 14:29:07 +0000 (16:29 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 22 Jul 2022 13:14:44 +0000 (15:14 +0200)
When hotplugging a chardev, Libvirt opens corresponding
file/binds to a socket/does whatever necessary to obtain an FD
that is later passed to QEMU. However, if something fails after
the FDs were transferred to QEMU and before chardev is actually
added via monitor, these FDs are never closed in QEMU. This is
rather suboptimal.

Fixes: 15bdced9b3d0b86a48506bfb1c27d6b2d5377dc2
Fixes: ad81aa8ad07e52c9bd4840de84d2ed59998b4d2a
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Kristina Hanicova <khanicov@redhat.com>
src/qemu/qemu_hotplug.c

index ed63624cf6e62ad0053d47972a6e43a46c615c6f..1c404ad5a50f777927c010f3b2763059e3a67388 100644 (file)
@@ -2132,17 +2132,6 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver,
     if (qemuProcessPrepareHostBackendChardevHotplug(vm, dev) < 0)
         goto cleanup;
 
-    if (charpriv->sourcefd || charpriv->logfd || charpriv->directfd) {
-        qemuDomainObjEnterMonitor(driver, vm);
-
-        if (qemuFDPassTransferMonitor(charpriv->sourcefd, priv->mon) < 0 ||
-            qemuFDPassTransferMonitor(charpriv->logfd, priv->mon) < 0 ||
-            qemuFDPassDirectTransferMonitor(charpriv->directfd, priv->mon) < 0)
-            goto exit_monitor;
-
-        qemuDomainObjExitMonitor(vm);
-    }
-
     if (guestfwd) {
         if (!(netdevprops = qemuBuildChannelGuestfwdNetdevProps(chr)))
             goto cleanup;
@@ -2164,6 +2153,11 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver,
 
     qemuDomainObjEnterMonitor(driver, vm);
 
+    if (qemuFDPassTransferMonitor(charpriv->sourcefd, priv->mon) < 0 ||
+        qemuFDPassTransferMonitor(charpriv->logfd, priv->mon) < 0 ||
+        qemuFDPassDirectTransferMonitor(charpriv->directfd, priv->mon) < 0)
+        goto exit_monitor;
+
     if (qemuHotplugChardevAttach(priv->mon, charAlias, chr->source) < 0)
         goto exit_monitor;
     chardevAttached = true;
@@ -2209,6 +2203,7 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver,
         qemuMonitorDetachCharDev(priv->mon, charAlias);
     qemuFDPassTransferMonitorRollback(charpriv->sourcefd, priv->mon);
     qemuFDPassTransferMonitorRollback(charpriv->logfd, priv->mon);
+    qemuFDPassDirectTransferMonitorRollback(charpriv->directfd, priv->mon);
     qemuDomainObjExitMonitor(vm);
     virErrorRestore(&orig_err);