[libvirt] [PATCH v2 15/23] qemu-domain: save and restore slirp state

marcandre.lureau@redhat.com posted 23 patches 6 years, 6 months ago
[libvirt] [PATCH v2 15/23] qemu-domain: save and restore slirp state
Posted by marcandre.lureau@redhat.com 6 years, 6 months ago
From: Marc-André Lureau <marcandre.lureau@redhat.com>

Save & restore the slirp helper PID associated with a network
interface & the probed features.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 src/qemu/qemu_domain.c | 137 +++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h |   2 +-
 2 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7315fe103e..b6f7e8bacc 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -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"
@@ -1304,6 +1305,11 @@ qemuDomainNetworkPrivateNew(void)
 static void
 qemuDomainNetworkPrivateDispose(void *obj ATTRIBUTE_UNUSED)
 {
+    qemuDomainNetworkPrivatePtr priv = obj;
+
+    if (priv->slirp) {
+        qemuSlirpFree(priv->slirp);
+    }
 }
 
 
@@ -2630,6 +2636,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)
@@ -2731,6 +2794,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
     if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0)
         return -1;
 
+    if (qemuDomainObjPrivateXMLFormatSlirp(buf, vm) < 0)
+        return -1;
+
     return 0;
 }
 
@@ -3258,6 +3324,46 @@ qemuDomainObjPrivateXMLParseJob(virDomainObjPtr vm,
 }
 
 
+static int
+qemuDomainObjPrivateXMLParseSlirpFeatures(xmlXPathContextPtr ctxt,
+                                          size_t h,
+                                          qemuSlirpPtr slirp)
+{
+    VIR_AUTOFREE(char *) path = NULL;
+    VIR_AUTOFREE(xmlNodePtr *) nodes = NULL;
+    size_t i;
+    int n;
+
+    if (virAsprintf(&path, "./slirp/helper[%ld]/feature", h + 1) < 0)
+        return -1;
+
+    if ((n = virXPathNodeSet(path, 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,
@@ -3396,6 +3502,37 @@ 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;
+    }
+    if (n > 0) {
+        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(ctxt, i, 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;
 
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 7293c87d7c..84c39dfb54 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -521,7 +521,7 @@ typedef qemuDomainNetworkPrivate *qemuDomainNetworkPrivatePtr;
 struct _qemuDomainNetworkPrivate {
     virObject parent;
 
-    bool tmp_to_be_larger_than_parent;
+    qemuSlirpPtr slirp;
 };
 
 
-- 
2.23.0.rc1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 15/23] qemu-domain: save and restore slirp state
Posted by Michal Privoznik 6 years, 5 months ago
On 8/8/19 4:55 PM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Save & restore the slirp helper PID associated with a network
> interface & the probed features.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   src/qemu/qemu_domain.c | 137 +++++++++++++++++++++++++++++++++++++++++
>   src/qemu/qemu_domain.h |   2 +-
>   2 files changed, 138 insertions(+), 1 deletion(-)
> 
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 7315fe103e..b6f7e8bacc 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -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"
> @@ -1304,6 +1305,11 @@ qemuDomainNetworkPrivateNew(void)
>   static void
>   qemuDomainNetworkPrivateDispose(void *obj ATTRIBUTE_UNUSED)
>   {
> +    qemuDomainNetworkPrivatePtr priv = obj;
> +
> +    if (priv->slirp) {
> +        qemuSlirpFree(priv->slirp);

Needless NULL check.

> +    }
>   }
>   
>   
> @@ -2630,6 +2636,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)
> @@ -2731,6 +2794,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
>       if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0)
>           return -1;
>   
> +    if (qemuDomainObjPrivateXMLFormatSlirp(buf, vm) < 0)
> +        return -1;
> +
>       return 0;
>   }
>   
> @@ -3258,6 +3324,46 @@ qemuDomainObjPrivateXMLParseJob(virDomainObjPtr vm,
>   }
>   
>   
> +static int
> +qemuDomainObjPrivateXMLParseSlirpFeatures(xmlXPathContextPtr ctxt,
> +                                          size_t h,
> +                                          qemuSlirpPtr slirp)

We tend to pass xmlNodePtr here among with ctxt and then use 
VIR_XPATH_NODE_AUTORESTORE(ctxt).

> +{
> +    VIR_AUTOFREE(char *) path = NULL;
> +    VIR_AUTOFREE(xmlNodePtr *) nodes = NULL;
> +    size_t i;
> +    int n;
> +
> +    if (virAsprintf(&path, "./slirp/helper[%ld]/feature", h + 1) < 0)
> +        return -1;
> +
> +    if ((n = virXPathNodeSet(path, 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,
> @@ -3396,6 +3502,37 @@ 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;
> +    }
> +    if (n > 0) {

I know you put this check here to be consistent with the rest of the 
code, but that code needs to alloc something in case of n > 0 and only 
after that it execs for ().

> +        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(ctxt, i, 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;
>   
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 7293c87d7c..84c39dfb54 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -521,7 +521,7 @@ typedef qemuDomainNetworkPrivate *qemuDomainNetworkPrivatePtr;
>   struct _qemuDomainNetworkPrivate {
>       virObject parent;
>   
> -    bool tmp_to_be_larger_than_parent;
> +    qemuSlirpPtr slirp;

This now requires include of qemu_slirp.h

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>

Michal

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