]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu-domain: save and restore slirp state
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Thu, 8 Aug 2019 14:55:06 +0000 (18:55 +0400)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 6 Sep 2019 10:47:47 +0000 (12:47 +0200)
Save & restore the slirp helper PID associated with a network
interface & the probed features.

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_domain.c
src/qemu/qemu_domain.h

index 5b3835abf9bc0f33ea2d2b1f143b0f6cd318f5fa..ec80905c899f494d8974681c9713660bbd8ac147 100644 (file)
@@ -32,6 +32,7 @@
 #include "qemu_migration.h"
 #include "qemu_migration_params.h"
 #include "qemu_security.h"
+#include "qemu_slirp.h"
 #include "qemu_extdevice.h"
 #include "qemu_blockjob.h"
 #include "viralloc.h"
@@ -1302,6 +1303,9 @@ qemuDomainNetworkPrivateNew(void)
 static void
 qemuDomainNetworkPrivateDispose(void *obj ATTRIBUTE_UNUSED)
 {
+    qemuDomainNetworkPrivatePtr priv = obj;
+
+    qemuSlirpFree(priv->slirp);
 }
 
 
@@ -2651,6 +2655,63 @@ qemuDomainObjPrivateXMLFormatJob(virBufferPtr buf,
 }
 
 
+static bool
+qemuDomainHasSlirp(virDomainObjPtr vm)
+{
+    size_t i;
+
+    for (i = 0; i < vm->def->nnets; i++) {
+        virDomainNetDefPtr net = vm->def->nets[i];
+
+        if (QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp)
+            return true;
+    }
+
+    return false;
+}
+
+
+static int
+qemuDomainObjPrivateXMLFormatSlirp(virBufferPtr buf,
+                                   virDomainObjPtr vm)
+{
+    size_t i;
+
+    if (!qemuDomainHasSlirp(vm))
+        return 0;
+
+    virBufferAddLit(buf, "<slirp>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < vm->def->nnets; i++) {
+        virDomainNetDefPtr net = vm->def->nets[i];
+        qemuSlirpPtr slirp = QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp;
+        size_t j;
+
+        if (!slirp)
+            continue;
+
+        virBufferAsprintf(buf, "<helper alias='%s' pid='%d'>\n",
+                          net->info.alias, slirp->pid);
+
+        virBufferAdjustIndent(buf, 2);
+        for (j = 0; j < QEMU_SLIRP_FEATURE_LAST; j++) {
+            if (qemuSlirpHasFeature(slirp, j)) {
+                virBufferAsprintf(buf, "<feature name='%s'/>\n",
+                                  qemuSlirpFeatureTypeToString(j));
+            }
+        }
+        virBufferAdjustIndent(buf, -2);
+        virBufferAddLit(buf, "</helper>\n");
+    }
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</slirp>\n");
+
+
+    return 0;
+}
+
 static int
 qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
                               virDomainObjPtr vm)
@@ -2752,6 +2813,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
     if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0)
         return -1;
 
+    if (qemuDomainObjPrivateXMLFormatSlirp(buf, vm) < 0)
+        return -1;
+
     return 0;
 }
 
@@ -3309,6 +3373,45 @@ qemuDomainObjPrivateXMLParseJob(virDomainObjPtr vm,
 }
 
 
+static int
+qemuDomainObjPrivateXMLParseSlirpFeatures(xmlNodePtr featuresNode,
+                                          xmlXPathContextPtr ctxt,
+                                          qemuSlirpPtr slirp)
+{
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    VIR_AUTOFREE(xmlNodePtr *) nodes = NULL;
+    size_t i;
+    int n;
+
+    ctxt->node = featuresNode;
+
+    if ((n = virXPathNodeSet("./feature", ctxt, &nodes)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("failed to parse slirp-helper features"));
+        return -1;
+    }
+
+    for (i = 0; i < n; i++) {
+        VIR_AUTOFREE(char *) str = virXMLPropString(nodes[i], "name");
+        int feature;
+
+        if (!str)
+            continue;
+
+        feature = qemuSlirpFeatureTypeFromString(str);
+        if (feature < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Unknown slirp feature %s"), str);
+            return -1;
+        }
+
+        qemuSlirpSetFeature(slirp, feature);
+    }
+
+    return 0;
+}
+
+
 static int
 qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
                              virDomainObjPtr vm,
@@ -3447,6 +3550,35 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
     }
     VIR_FREE(nodes);
 
+    if ((n = virXPathNodeSet("./slirp/helper", ctxt, &nodes)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("failed to parse slirp helper list"));
+        goto error;
+    }
+    for (i = 0; i < n; i++) {
+        VIR_AUTOFREE(char *) alias = virXMLPropString(nodes[i], "alias");
+        VIR_AUTOFREE(char *) pid = virXMLPropString(nodes[i], "pid");
+        VIR_AUTOPTR(qemuSlirp) slirp = qemuSlirpNew();
+        virDomainDeviceDef dev;
+
+        if (!alias || !pid || !slirp ||
+            virStrToLong_i(pid, NULL, 10, &slirp->pid) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("failed to parse slirp helper list"));
+            goto error;
+        }
+
+        if (virDomainDefFindDevice(vm->def, alias, &dev, true) < 0 ||
+            dev.type != VIR_DOMAIN_DEVICE_NET)
+            goto error;
+
+        if (qemuDomainObjPrivateXMLParseSlirpFeatures(nodes[i], ctxt, slirp) < 0)
+            goto error;
+
+        VIR_STEAL_PTR(QEMU_DOMAIN_NETWORK_PRIVATE(dev.data.net)->slirp, slirp);
+    }
+    VIR_FREE(nodes);
+
     if (qemuDomainObjPrivateXMLParseAutomaticPlacement(ctxt, priv, driver) < 0)
         goto error;
 
index bb73c7a3755c2ce1a13bc6a5fde84d138b16fae9..d297cb3a961e203aa1cae4d602c1ff09ab8a9459 100644 (file)
@@ -33,6 +33,7 @@
 #include "qemu_conf.h"
 #include "qemu_capabilities.h"
 #include "qemu_migration_params.h"
+#include "qemu_slirp.h"
 #include "virmdev.h"
 #include "virchrdev.h"
 #include "virobject.h"
@@ -520,7 +521,7 @@ typedef qemuDomainNetworkPrivate *qemuDomainNetworkPrivatePtr;
 struct _qemuDomainNetworkPrivate {
     virObject parent;
 
-    bool tmp_to_be_larger_than_parent;
+    qemuSlirpPtr slirp;
 };