[PATCH] qemu: simplify PCI configfd handling in monitor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is also a bug fix - on the error path, qemu_hotplug would
leave the configfd file leaked into qemu.  At least the next
attempt to hotplug a PCI device would reuse the same fdname,
and when the qemu getfd monitor command gets a new fd by the
same name as an earlier one, it closes the earlier one, so there
is no risk of qemu running out of fds.

* src/qemu/qemu_monitor.h (qemuMonitorAddDeviceWithFd): New
prototype.
* src/qemu/qemu_monitor.c (qemuMonitorAddDevice): Move guts...
(qemuMonitorAddDeviceWithFd): ...to new function, and add support
for fd passing.
* src/qemu/qemu_hotplug.c (qemuDomainAttachHostPciDevice): Use it
to simplify code.
---

> > It is a nice idea todo the SendFileHAndle/CloseFileHandle
> > calls from here, rather than in the qemu_driver code
> > itself. It makes the latter much clearer - we should think
> > about whether it makes sense to rewrite the NIC hotplug
> > code to work this way too.

> Agreed; I'll submit a patch for that shortly.

Thanks for requesting this - I found and plugged a resource leak
in the process.  NIC hotplug cleanup coming next.

 src/qemu/qemu_hotplug.c |   19 +++++++++----------
 src/qemu/qemu_monitor.c |   24 +++++++++++++++++++++---
 src/qemu/qemu_monitor.h |    5 +++++
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e4ba526..40e4159 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -829,21 +829,19 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver,
         if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &hostdev->info) < 0)
             goto error;
         if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
-            configfd = qemuOpenPCIConfig(hostdev);
+            if (priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
+                qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                _("pci configfd file cannot be attached: "
+                                  "qemu is not using a unix socket monitor"));
+            } else {
+                configfd = qemuOpenPCIConfig(hostdev);
+            }
             if (configfd >= 0) {
                 if (virAsprintf(&configfd_name, "fd-%s",
                                 hostdev->info.alias) < 0) {
                     virReportOOMError();
                     goto error;
                 }
-
-                qemuDomainObjEnterMonitorWithDriver(driver, vm);
-                if (qemuMonitorSendFileHandle(priv->mon, configfd_name,
-                                              configfd) < 0) {
-                    qemuDomainObjExitMonitorWithDriver(driver, vm);
-                    goto error;
-                }
-                qemuDomainObjExitMonitorWithDriver(driver, vm);
             }
         }

@@ -858,7 +856,8 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver,
             goto error;

         qemuDomainObjEnterMonitorWithDriver(driver, vm);
-        ret = qemuMonitorAddDevice(priv->mon, devstr);
+        ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
+                                         configfd, configfd_name);
         qemuDomainObjExitMonitorWithDriver(driver, vm);
     } else {
         virDomainDevicePCIAddress guestAddr;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index da38096..f2b1721 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2016,10 +2016,13 @@ int qemuMonitorDelDevice(qemuMonitorPtr mon,
 }


-int qemuMonitorAddDevice(qemuMonitorPtr mon,
-                         const char *devicestr)
+int qemuMonitorAddDeviceWithFd(qemuMonitorPtr mon,
+                               const char *devicestr,
+                               int fd,
+                               const char *fdname)
 {
-    VIR_DEBUG("mon=%p device=%s", mon, devicestr);
+    VIR_DEBUG("mon=%p device=%s fd=%d fdname=%s", mon, devicestr, fd,
+              NULLSTR(fdname));
     int ret;

     if (!mon) {
@@ -2028,13 +2031,28 @@ int qemuMonitorAddDevice(qemuMonitorPtr mon,
         return -1;
     }

+    if (fd >= 0 && qemuMonitorSendFileHandle(mon, fdname, fd) < 0)
+        return -1;
+
     if (mon->json)
         ret = qemuMonitorJSONAddDevice(mon, devicestr);
     else
         ret = qemuMonitorTextAddDevice(mon, devicestr);
+
+    if (ret < 0 && fd >= 0) {
+        if (qemuMonitorCloseFileHandle(mon, fdname) < 0)
+            VIR_WARN("failed to close device handle '%s'", fdname);
+    }
+
     return ret;
 }

+int qemuMonitorAddDevice(qemuMonitorPtr mon,
+                         const char *devicestr)
+{
+    return qemuMonitorAddDeviceWithFd(mon, devicestr, -1, NULL);
+}
+
 int qemuMonitorAddDrive(qemuMonitorPtr mon,
                         const char *drivestr)
 {
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 7bea083..a20ff8e 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -390,6 +390,11 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon,
 int qemuMonitorAddDevice(qemuMonitorPtr mon,
                          const char *devicestr);

+int qemuMonitorAddDeviceWithFd(qemuMonitorPtr mon,
+                               const char *devicestr,
+                               int fd,
+                               const char *fdname);
+
 int qemuMonitorDelDevice(qemuMonitorPtr mon,
                          const char *devalias);

-- 
1.7.4

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]