]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu-hotplug: handle hotplugging of slirp-helper
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Thu, 8 Aug 2019 14:55:13 +0000 (18:55 +0400)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 6 Sep 2019 10:47:47 +0000 (12:47 +0200)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_hotplug.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h

index 69eeb50a2da14b597efe190c3006cc4b1f33ac2f..7d31b712fb7a0846cf40498a27ab6126a190e2eb 100644 (file)
@@ -1147,6 +1147,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     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;
@@ -1326,7 +1328,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:
@@ -1386,7 +1407,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
     if (!(netstr = qemuBuildHostNetStr(net, driver,
                                        tapfdName, tapfdSize,
                                        vhostfdName, vhostfdSize,
-                                       NULL)))
+                                       slirpfdName)))
         goto cleanup;
 
     qemuDomainObjEnterMonitor(driver, vm);
@@ -1402,7 +1423,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;
@@ -1517,6 +1539,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
     VIR_FREE(charDevAlias);
     virObjectUnref(conn);
     virDomainCCWAddressSetFree(ccwaddrs);
+    VIR_FORCE_CLOSE(slirpfd);
 
     return ret;
 
@@ -1526,6 +1549,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
 
     virErrorPreserveLast(&originalError);
     if (virAsprintf(&netdev_name, "host%s", net->info.alias) >= 0) {
+        if (QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp)
+            qemuSlirpStop(QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp, vm, driver, net, true);
         qemuDomainObjEnterMonitor(driver, vm);
         if (charDevPlugged &&
             qemuMonitorDetachCharDev(priv->mon, charDevAlias) < 0)
@@ -2196,7 +2221,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)
@@ -4669,6 +4694,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++) {
index 58ad109680d81297b99d481a1a881f802461e49c..aa230b330659cd30b0e25c0bf903ac6e658cea51 100644 (file)
@@ -2846,15 +2846,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);
 
@@ -2867,6 +2869,10 @@ qemuMonitorAddNetdev(qemuMonitorPtr mon,
             goto cleanup;
     }
 
+    if (slirpfd > 0 &&
+        qemuMonitorSendFileHandle(mon, slirpfdName, slirpfd) < 0)
+        goto cleanup;
+
     ret = qemuMonitorJSONAddNetdev(mon, netdevstr);
 
  cleanup:
@@ -2879,6 +2885,8 @@ qemuMonitorAddNetdev(qemuMonitorPtr mon,
             if (qemuMonitorCloseFileHandle(mon, vhostfdName[j]) < 0)
                 VIR_WARN("failed to close device handle '%s'", vhostfdName[j]);
         }
+        if (qemuMonitorCloseFileHandle(mon, slirpfdName) < 0)
+            VIR_WARN("failed to close device handle '%s'", slirpfdName);
     }
 
     return ret;
index de85a3ba0d3f398b9e9100694ed3ce0aa503f406..70000a1c72b2679702f2a8dbca8bc75d83c056ae 100644 (file)
@@ -886,7 +886,8 @@ int qemuMonitorRemoveFd(qemuMonitorPtr mon, int fdset, int fd);
 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 qemuMonitorRemoveNetdev(qemuMonitorPtr mon,
                             const char *alias);