From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
Save & restore the slirp helper PID associated with a network
interface & the probed features.
Signed-off-by: Marc-André Lureau <marcandre.lureau(a)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