Re: [PATCH v2 22/23] qemu-hotplug: handle hotplugging of slirp-helper

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

 



On 8/8/19 4:55 PM, marcandre.lureau@xxxxxxxxxx wrote:
From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx>

Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx>
---
  src/qemu/qemu_hotplug.c | 33 ++++++++++++++++++++++++++++++---
  src/qemu/qemu_monitor.c | 13 ++++++++++---
  src/qemu/qemu_monitor.h |  3 ++-
  3 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 43c3f0755b..fcbf7a8aa9 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1136,6 +1136,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
      virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_NET, { .net = net } };
      virErrorPtr originalError = NULL;
      VIR_AUTOFREE(char *) slirpfdName = NULL;
+    int slirpfd = -1;
      char **tapfdName = NULL;
      int *tapfd = NULL;
      size_t tapfdSize = 0;
@@ -1315,7 +1316,26 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
          break;
case VIR_DOMAIN_NET_TYPE_USER:
-        /* No preparation needed. */
+        if (!priv->disableSlirp &&
+            virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NET_SOCKET_DGRAM)) {
+            qemuSlirpPtr slirp = qemuInterfacePrepareSlirp(driver, net);
+
+            if (!slirp)
+                break;
+
+            QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
+
+            if (qemuSlirpOpen(slirp, driver, vm->def) < 0 ||
+                qemuSlirpStart(slirp, vm, driver, net, true, NULL) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               "%s", _("Failed to start slirp"));
+                goto cleanup;
+            }
+
+            slirpfd = qemuSlirpGetFD(slirp);
+            if (virAsprintf(&slirpfdName, "slirpfd-%s", net->info.alias) < 0)
+                goto cleanup;
+        }
          break;
case VIR_DOMAIN_NET_TYPE_SERVER:
@@ -1391,7 +1411,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
if (qemuMonitorAddNetdev(priv->mon, netstr,
                               tapfd, tapfdName, tapfdSize,
-                             vhostfd, vhostfdName, vhostfdSize) < 0) {
+                             vhostfd, vhostfdName, vhostfdSize,
+                             slirpfd, slirpfdName) < 0) {
          ignore_value(qemuDomainObjExitMonitor(driver, vm));
          virDomainAuditNet(vm, NULL, net, "attach", false);
          goto try_remove;
@@ -1506,6 +1527,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
      VIR_FREE(charDevAlias);
      virObjectUnref(conn);
      virDomainCCWAddressSetFree(ccwaddrs);
+    VIR_FORCE_CLOSE(slirpfd);
return ret; @@ -1516,6 +1538,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
      virErrorPreserveLast(&originalError);
      if (virAsprintf(&netdev_name, "host%s", net->info.alias) >= 0) {
          qemuDomainObjEnterMonitor(driver, vm);
+        if (QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp)
+            qemuSlirpStop(QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp, vm, driver, net, true);

This can be done outside of EnterMonitor(). qemuSlirpStop() will enter the monitor on its own.

          if (charDevPlugged &&
              qemuMonitorDetachCharDev(priv->mon, charDevAlias) < 0)
              VIR_WARN("Failed to remove associated chardev %s", charDevAlias);
@@ -2201,7 +2225,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
if (guestfwd) {
          if (qemuMonitorAddNetdev(priv->mon, devstr,
-                                 NULL, NULL, 0, NULL, NULL, 0) < 0)
+                                 NULL, NULL, 0, NULL, NULL, 0, -1, NULL) < 0)
              goto exit_monitor;
      } else {
          if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
@@ -4674,6 +4698,9 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
      if (qemuDomainObjExitMonitor(driver, vm) < 0)
          goto cleanup;
+ if (QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp)
+        qemuSlirpStop(QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp, vm, driver, net, true);
+
      virDomainAuditNet(vm, net, NULL, "detach", true);
for (i = 0; i < vm->def->nnets; i++) {
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index a880da3ab6..84af24958a 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2844,15 +2844,17 @@ int
  qemuMonitorAddNetdev(qemuMonitorPtr mon,
                       const char *netdevstr,
                       int *tapfd, char **tapfdName, int tapfdSize,
-                     int *vhostfd, char **vhostfdName, int vhostfdSize)
+                     int *vhostfd, char **vhostfdName, int vhostfdSize,
+                     int slirpfd, char *slirpfdName)
  {
      int ret = -1;
      size_t i = 0, j = 0;
VIR_DEBUG("netdevstr=%s tapfd=%p tapfdName=%p tapfdSize=%d"
-              "vhostfd=%p vhostfdName=%p vhostfdSize=%d",
+              "vhostfd=%p vhostfdName=%p vhostfdSize=%d"
+              "slirpfd=%d slirpfdName=%s",
                netdevstr, tapfd, tapfdName, tapfdSize,
-              vhostfd, vhostfdName, vhostfdSize);
+              vhostfd, vhostfdName, vhostfdSize, slirpfd, slirpfdName);
QEMU_CHECK_MONITOR(mon); @@ -2865,6 +2867,11 @@ qemuMonitorAddNetdev(qemuMonitorPtr mon,
              goto cleanup;
      }
+ if (slirpfd != -1) {
+        if (qemuMonitorSendFileHandle(mon, slirpfdName, slirpfd) < 0)
+            goto cleanup;
+    }
+
      ret = qemuMonitorJSONAddNetdev(mon, netdevstr);
cleanup:

If this function fails, we need to let qemu close the slirpfd:

  if (qemuMonitorCloseFileHandle(mon, slirpfdName) < 0)
    VIR_WARN("failed to close device handle '%s'", slirpfdName);

Reviewed-by: Michal Privoznik <mprivozn@xxxxxxxxxx>

Michal

--
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]

  Powered by Linux