From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> Save & restore the slirp helper PID associated with a network interface & the probed features. Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> --- 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list