From nobody Tue Feb 10 13:01:35 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1565276312; cv=none; d=zoho.com; s=zohoarc; b=njighjhaNtMTVsU/QdtN79GEZchDkSVm2zxVaSKoAe42Rp0+91Q1VphUcXKHc5IBOcY9eX5YHoEepHWCIWYC9ZH4YSqCxkUx0sUoIlknvWAQ9hUDglq6J96CtfIX8T9xQCwtN3oS7Xh+rMcchLIV6EJAHJ9QK9Kwa50Zmmz3nBc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1565276312; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=ychn8+PJTShCRRGqZfE+N08Y6LHpRVxcsuJG/ruW7Mk=; b=hOGMOKMY0VA/EtT39Y2/3L2SgHX7kcq/Dym9OWkr3JrJ96CJOE+13oR6CD55UVFupA0raR0NBpB+fLsyIhhkRUVrpxIbEeaICst6y9qymnrwz4lto/wOE7kNREq3vzOOq833DoqKzRkBKoYUrBVaZ0urIwyZdXFZDNEww04OLDs= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1565276312397733.1710167191889; Thu, 8 Aug 2019 07:58:32 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1B9106908B; Thu, 8 Aug 2019 14:58:31 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DAF205B6A5; Thu, 8 Aug 2019 14:58:30 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9490183552; Thu, 8 Aug 2019 14:58:30 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x78EvqLo023365 for ; Thu, 8 Aug 2019 10:57:52 -0400 Received: by smtp.corp.redhat.com (Postfix) id E45F91F4; Thu, 8 Aug 2019 14:57:52 +0000 (UTC) Received: from localhost (ovpn-112-57.ams2.redhat.com [10.36.112.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC0AB5DAA0; Thu, 8 Aug 2019 14:57:44 +0000 (UTC) From: marcandre.lureau@redhat.com To: libvir-list@redhat.com Date: Thu, 8 Aug 2019 18:55:05 +0400 Message-Id: <20190808145514.20789-15-marcandre.lureau@redhat.com> In-Reply-To: <20190808145514.20789-1-marcandre.lureau@redhat.com> References: <20190808145514.20789-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Subject: [libvirt] [PATCH v2 14/23] qemu: add slirp helper unit X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 08 Aug 2019 14:58:31 +0000 (UTC) From: Marc-Andr=C3=A9 Lureau The unit provides the functions associated with a slirp-helper: - probing / checking capabilities - opening the socketpair - starting / stoping the helper - registering for dbus-vmstate migration Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Michal Privoznik --- src/qemu/Makefile.inc.am | 2 + src/qemu/qemu_domain.h | 4 + src/qemu/qemu_slirp.c | 448 +++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_slirp.h | 81 +++++++ 4 files changed, 535 insertions(+) create mode 100644 src/qemu/qemu_slirp.c create mode 100644 src/qemu/qemu_slirp.h diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am index 94dd0e56ff..505b418fa5 100644 --- a/src/qemu/Makefile.inc.am +++ b/src/qemu/Makefile.inc.am @@ -58,6 +58,8 @@ QEMU_DRIVER_SOURCES =3D \ qemu/qemu_security.h \ qemu/qemu_qapi.c \ qemu/qemu_qapi.h \ + qemu/qemu_slirp.c \ + qemu/qemu_slirp.h \ qemu/qemu_tpm.c \ qemu/qemu_tpm.h \ $(NULL) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 560b01d80a..7293c87d7c 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -509,6 +509,10 @@ struct _qemuDomainGraphicsPrivate { }; =20 =20 +typedef struct _qemuSlirp qemuSlirp; +typedef struct _qemuSlirp *qemuSlirpPtr; + + #define QEMU_DOMAIN_NETWORK_PRIVATE(dev) \ ((qemuDomainNetworkPrivatePtr) (dev)->privateData) =20 diff --git a/src/qemu/qemu_slirp.c b/src/qemu/qemu_slirp.c new file mode 100644 index 0000000000..36370b6be0 --- /dev/null +++ b/src/qemu/qemu_slirp.c @@ -0,0 +1,448 @@ +/* + * qemu_slirp.c: QEMU Slirp support + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "qemu_dbus.h" +#include "qemu_extdevice.h" +#include "qemu_security.h" +#include "qemu_slirp.h" +#include "viralloc.h" +#include "virenum.h" +#include "virerror.h" +#include "virjson.h" +#include "virlog.h" +#include "virpidfile.h" +#include "virstring.h" +#include "virtime.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +VIR_LOG_INIT("qemu.slirp"); + +VIR_ENUM_IMPL(qemuSlirpFeature, + QEMU_SLIRP_FEATURE_LAST, + "", + "ipv4", + "ipv6", + "tftp", + "dbus-address", + "dbus-p2p", + "migrate", + "restrict", + "exit-with-parent", +); + + +void +qemuSlirpFree(qemuSlirpPtr slirp) +{ + VIR_FORCE_CLOSE(slirp->fd[0]); + VIR_FORCE_CLOSE(slirp->fd[1]); + virBitmapFree(slirp->features); + VIR_FREE(slirp); +} + + +void +qemuSlirpSetFeature(qemuSlirpPtr slirp, + qemuSlirpFeature feature) +{ + ignore_value(virBitmapSetBit(slirp->features, feature)); +} + + +bool +qemuSlirpHasFeature(const qemuSlirpPtr slirp, + qemuSlirpFeature feature) +{ + return virBitmapIsBitSet(slirp->features, feature); +} + + +qemuSlirpPtr +qemuSlirpNew(void) +{ + qemuSlirpPtr slirp =3D NULL; + + if (VIR_ALLOC(slirp) < 0) + return NULL; + + slirp->pid =3D (pid_t)-1; + slirp->fd[0] =3D slirp->fd[1] =3D -1; + slirp->features =3D virBitmapNew(QEMU_SLIRP_FEATURE_LAST); + + return slirp; +} + + +qemuSlirpPtr +qemuSlirpNewForHelper(const char *helper) +{ + VIR_AUTOPTR(qemuSlirp) slirp =3D NULL; + VIR_AUTOPTR(virCommand) cmd =3D NULL; + VIR_AUTOFREE(char *) output =3D NULL; + VIR_AUTOPTR(virJSONValue) doc =3D NULL; + virJSONValuePtr featuresJSON; + size_t i, nfeatures; + + if (!helper) + return NULL; + + slirp =3D qemuSlirpNew(); + if (!slirp) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to allocate slirp for '%s'"), helper); + return NULL; + } + + cmd =3D virCommandNewArgList(helper, "--print-capabilities", NULL); + virCommandSetOutputBuffer(cmd, &output); + if (virCommandRun(cmd, NULL) < 0) + return NULL; + + if (!(doc =3D virJSONValueFromString(output)) || + !(featuresJSON =3D virJSONValueObjectGetArray(doc, "features"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unable to parse json capabilities '%s'"), + helper); + return NULL; + } + + nfeatures =3D virJSONValueArraySize(featuresJSON); + for (i =3D 0; i < nfeatures; i++) { + virJSONValuePtr item =3D virJSONValueArrayGet(featuresJSON, i); + const char *tmpStr =3D virJSONValueGetString(item); + int tmp; + + if ((tmp =3D qemuSlirpFeatureTypeFromString(tmpStr)) <=3D 0) { + VIR_WARN("unknown slirp feature %s", tmpStr); + continue; + } + + qemuSlirpSetFeature(slirp, tmp); + } + + VIR_RETURN_PTR(slirp); +} + + +static char * +qemuSlirpCreatePidFilename(const char *stateDir, + const char *shortName, + const char *alias) +{ + VIR_AUTOFREE(char *) name =3D NULL; + + if (virAsprintf(&name, "%s-%s-slirp", shortName, alias) < 0) + return NULL; + + return virPidFileBuildPath(stateDir, name); +} + + +static int +qemuSlirpGetPid(const char *binPath, + const char *stateDir, + const char *shortName, + const char *alias, + pid_t *pid) +{ + VIR_AUTOFREE(char *) pidfile =3D qemuSlirpCreatePidFilename(stateDir, = shortName, alias); + if (!pidfile) + return -ENOMEM; + + return virPidFileReadPathIfAlive(pidfile, pid, binPath); +} + + +int +qemuSlirpOpen(qemuSlirpPtr slirp, + virQEMUDriverPtr driver, + virDomainDefPtr def) +{ + int rc, pair[2] =3D { -1, -1 }; + + if (qemuSecuritySetSocketLabel(driver->securityManager, def) < 0) + goto error; + + rc =3D socketpair(AF_UNIX, SOCK_DGRAM, 0, pair); + + if (qemuSecurityClearSocketLabel(driver->securityManager, def) < 0) + goto error; + + if (rc < 0) { + virReportSystemError(errno, "%s", _("failed to create socketpair")= ); + goto error; + } + + slirp->fd[0] =3D pair[0]; + slirp->fd[1] =3D pair[1]; + + return 0; + +error: + VIR_FORCE_CLOSE(pair[0]); + VIR_FORCE_CLOSE(pair[1]); + return -1; +} + + +int +qemuSlirpGetFD(qemuSlirpPtr slirp) +{ + int fd =3D slirp->fd[0]; + slirp->fd[0] =3D -1; + return fd; +} + + +static char * +qemuSlirpGetDBusVMStateId(virDomainNetDefPtr net) +{ + char macstr[VIR_MAC_STRING_BUFLEN] =3D ""; + char *id =3D NULL; + + /* can't use alias, because it's not stable across restarts */ + if (virAsprintf(&id, "slirp-%s", virMacAddrFormat(&net->mac, macstr)) = < 0) + return NULL; + + return id; +} + + +static char * +qemuSlirpGetDBusAddress(const char *stateDir, + const char *shortName, + const char *alias) +{ + char *name =3D NULL; + + if (virAsprintf(&name, "unix:path=3D%s/%s-%s-slirp", stateDir, shortNa= me, alias) < 0) + return NULL; + + return name; +} + + +void +qemuSlirpStop(qemuSlirpPtr slirp, + virDomainObjPtr vm, + virQEMUDriverPtr driver, + virDomainNetDefPtr net, + bool hot) +{ + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + VIR_AUTOFREE(char *) pidfile =3D NULL; + VIR_AUTOFREE(char *) shortName =3D virDomainDefGetShortName(vm->def); + VIR_AUTOFREE(char *) id =3D qemuSlirpGetDBusVMStateId(net); + virErrorPtr orig_err; + int rc; + pid_t pid; + + if (!(pidfile =3D qemuSlirpCreatePidFilename( + cfg->stateDir, shortName, net->info.alias))) { + VIR_WARN("Unable to construct slirp pidfile path"); + return; + } + + qemuDBusVMStateRemove(driver, vm, id, hot); + + rc =3D qemuSlirpGetPid(cfg->slirpHelperName, + cfg->stateDir, shortName, net->info.alias, &pid); + if (rc =3D=3D 0 && pid !=3D (pid_t)-1) { + char ebuf[1024]; + + VIR_DEBUG("Killing slirp process %lld", (long long)pid); + if (virProcessKill(pid, SIGKILL) < 0 && errno !=3D ESRCH) + VIR_ERROR(_("Failed to kill process %lld: %s"), + (long long)pid, + virStrerror(errno, ebuf, sizeof(ebuf))); + } + + virErrorPreserveLast(&orig_err); + if (virPidFileForceCleanupPath(pidfile) < 0) { + VIR_WARN("Unable to kill slirp process"); + } else { + if (unlink(pidfile) < 0 && + errno !=3D ENOENT) { + virReportSystemError(errno, + _("Unable to remove stale pidfile %s"), + pidfile); + } + } + virErrorRestore(&orig_err); + slirp->pid =3D 0; +} + + +int +qemuSlirpStart(qemuSlirpPtr slirp, + virDomainObjPtr vm, + virQEMUDriverPtr driver, + virDomainNetDefPtr net, + bool hotplug, + qemuProcessIncomingDefPtr incoming) +{ + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + VIR_AUTOPTR(virCommand) cmd =3D NULL; + VIR_AUTOFREE(char *) cmdstr =3D NULL; + VIR_AUTOFREE(char *) addr =3D NULL; + VIR_AUTOFREE(char *) pidfile =3D NULL; + VIR_AUTOFREE(char *) dbus_addr =3D NULL; + VIR_AUTOFREE(char *) id =3D NULL; + VIR_AUTOFREE(char *) shortName =3D virDomainDefGetShortName(vm->def); + size_t i; + virTimeBackOffVar timebackoff; + const unsigned long long timeout =3D 500 * 1000; /* ms */ + const char *dbus_path =3D NULL; + pid_t pid; + int cmdret =3D 0, exitstatus =3D 0; + + if (incoming && + !qemuSlirpHasFeature(slirp, QEMU_SLIRP_FEATURE_MIGRATE)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("The slirp-helper doesn't support migration")); + } + + if (!(pidfile =3D qemuSlirpCreatePidFilename( + cfg->stateDir, shortName, net->info.alias))) + return -1; + + if (!(cmd =3D virCommandNew(cfg->slirpHelperName))) + return -1; + + virCommandClearCaps(cmd); + virCommandSetPidFile(cmd, pidfile); + virCommandDaemonize(cmd); + + virCommandAddArgFormat(cmd, "--fd=3D%d", slirp->fd[1]); + virCommandPassFD(cmd, slirp->fd[1], + VIR_COMMAND_PASS_FD_CLOSE_PARENT); + slirp->fd[1] =3D -1; + + for (i =3D 0; i < net->guestIP.nips; i++) { + const virNetDevIPAddr *ip =3D net->guestIP.ips[i]; + const char *opt =3D ""; + + if (!(addr =3D virSocketAddrFormat(&ip->address))) + return -1; + + if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) + opt =3D "--net"; + if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6)) + opt =3D "--prefix-ipv6"; + + virCommandAddArgFormat(cmd, "%s=3D%s", opt, addr); + VIR_FREE(addr); + + if (ip->prefix) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) { + virSocketAddr netmask; + VIR_AUTOFREE(char *) netmaskStr =3D NULL; + + if (virSocketAddrPrefixToNetmask(ip->prefix, &netmask, AF_= INET) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to translate prefix %d to net= mask"), + ip->prefix); + return -1; + } + if (!(netmaskStr =3D virSocketAddrFormat(&netmask))) + return -1; + virCommandAddArgFormat(cmd, "--mask=3D%s", netmaskStr); + } + if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6)) + virCommandAddArgFormat(cmd, "--prefix-length-ipv6=3D%u", i= p->prefix); + } + } + + if (qemuSlirpHasFeature(slirp, + QEMU_SLIRP_FEATURE_DBUS_P2P)) { + id =3D qemuSlirpGetDBusVMStateId(net); + dbus_addr =3D qemuSlirpGetDBusAddress(cfg->stateDir, + shortName, net->info.alias); + if (!id || !dbus_addr) { + return -1; + } + + dbus_path =3D dbus_addr + strlen("unix:path=3D"); + + if (unlink(dbus_path) < 0 && errno !=3D ENOENT) { + virReportSystemError(errno, _("Unable to unlink %s"), dbus_pat= h); + return -1; + } + + virCommandAddArgFormat(cmd, "--dbus-id=3D%s", id); + + virCommandAddArgFormat(cmd, "--dbus-p2p=3D%s", dbus_addr); + + if (incoming && + qemuSlirpHasFeature(slirp, QEMU_SLIRP_FEATURE_MIGRATE)) + virCommandAddArg(cmd, "--dbus-incoming"); + } + + if (qemuSlirpHasFeature(slirp, + QEMU_SLIRP_FEATURE_EXIT_WITH_PARENT)) { + virCommandAddArg(cmd, "--exit-with-parent"); + } + + if (qemuExtDeviceLogCommand(driver, vm, cmd, "slirp") < 0) + return -1; + + if (qemuSecurityCommandRun(driver, vm, cmd, + &exitstatus, &cmdret) < 0) + return -1; + + if (cmdret < 0 || exitstatus !=3D 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not start 'slirp'. exitstatus: %d"), exits= tatus); + return -1; + } + + /* check that the helper has written its pid into the file */ + if (virTimeBackOffStart(&timebackoff, 1, timeout) < 0) + return -1; + while (virTimeBackOffWait(&timebackoff)) { + int rc =3D qemuSlirpGetPid(cfg->slirpHelperName, + cfg->stateDir, shortName, net->info.alias= , &pid); + if (rc < 0) + continue; + if (rc =3D=3D 0 && pid =3D=3D (pid_t)-1) + return -1; + break; + } + + if (dbus_path) { + while (virTimeBackOffWait(&timebackoff)) { + if (!virFileExists(dbus_path)) + continue; + break; + } + } + + if (qemuSlirpHasFeature(slirp, QEMU_SLIRP_FEATURE_MIGRATE)) { + if (qemuDBusVMStateAdd(driver, vm, id, dbus_addr, hotplug) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to register slirp migration")); + return -1; + } + } + + slirp->pid =3D pid; + return 0; +} diff --git a/src/qemu/qemu_slirp.h b/src/qemu/qemu_slirp.h new file mode 100644 index 0000000000..f44edce543 --- /dev/null +++ b/src/qemu/qemu_slirp.h @@ -0,0 +1,81 @@ +/* + * qemu_slirp.h: QEMU Slirp support + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "qemu_conf.h" +#include "qemu_domain.h" +#include "qemu_process.h" +#include "vircommand.h" + +typedef enum { + QEMU_SLIRP_FEATURE_NONE =3D 0, + QEMU_SLIRP_FEATURE_IPV4, + QEMU_SLIRP_FEATURE_IPV6, + QEMU_SLIRP_FEATURE_TFTP, + QEMU_SLIRP_FEATURE_DBUS_ADDRESS, + QEMU_SLIRP_FEATURE_DBUS_P2P, + QEMU_SLIRP_FEATURE_MIGRATE, + QEMU_SLIRP_FEATURE_RESTRICT, + QEMU_SLIRP_FEATURE_EXIT_WITH_PARENT, + + QEMU_SLIRP_FEATURE_LAST, +} qemuSlirpFeature; + +VIR_ENUM_DECL(qemuSlirpFeature); + + +struct _qemuSlirp { + int fd[2]; + virBitmapPtr features; + pid_t pid; +}; + + +qemuSlirpPtr qemuSlirpNew(void); + +qemuSlirpPtr qemuSlirpNewForHelper(const char *helper); + +void qemuSlirpFree(qemuSlirpPtr slirp); + +void qemuSlirpSetFeature(qemuSlirpPtr slirp, + qemuSlirpFeature feature); + +bool qemuSlirpHasFeature(const qemuSlirpPtr slirp, + qemuSlirpFeature feature); + +int qemuSlirpOpen(qemuSlirpPtr slirp, + virQEMUDriverPtr driver, + virDomainDefPtr def); + +int qemuSlirpStart(qemuSlirpPtr slirp, + virDomainObjPtr vm, + virQEMUDriverPtr driver, + virDomainNetDefPtr net, + bool hot, + qemuProcessIncomingDefPtr incoming); + +void qemuSlirpStop(qemuSlirpPtr slirp, + virDomainObjPtr vm, + virQEMUDriverPtr driver, + virDomainNetDefPtr net, + bool hot); + +int qemuSlirpGetFD(qemuSlirpPtr slirp); + +VIR_DEFINE_AUTOPTR_FUNC(qemuSlirp, qemuSlirpFree); --=20 2.23.0.rc1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list