From 6d5a9b9ed0951f80f7b7c8b57fa7a29ff52bccb4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 8 Aug 2019 18:55:06 +0400 Subject: [PATCH] qemu-domain: save and restore slirp state MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Save & restore the slirp helper PID associated with a network interface & the probed features. Signed-off-by: Marc-André Lureau Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- src/qemu/qemu_domain.c | 132 +++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 3 +- 2 files changed, 134 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 5b3835abf9..ec80905c89 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" @@ -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, "\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, "\n", + net->info.alias, slirp->pid); + + virBufferAdjustIndent(buf, 2); + for (j = 0; j < QEMU_SLIRP_FEATURE_LAST; j++) { + if (qemuSlirpHasFeature(slirp, j)) { + virBufferAsprintf(buf, "\n", + qemuSlirpFeatureTypeToString(j)); + } + } + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\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; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index bb73c7a375..d297cb3a96 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -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; }; -- 2.47.2