[libvirt] [PATCH v2 15/23] qemu-domain: save and restore slirp state
Michal Privoznik
mprivozn at redhat.com
Fri Sep 6 11:36:34 UTC 2019
On 8/8/19 4:55 PM, marcandre.lureau at redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau at redhat.com>
>
> Save & restore the slirp helper PID associated with a network
> interface & the probed features.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau at 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 at redhat.com>
Michal
More information about the libvir-list
mailing list