qemu-command: use -net socket, fd= with slirp-helper

If a slirp-helper is associated with a network interface (after
probing & preparing succesfully), pass the socket fd to QEMU and use
"-net socket,fd=".

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Marc-André Lureau 2019-08-08 18:55:11 +04:00 committed by Michal Privoznik
parent eef413e728
commit 03a2e2edad
3 changed files with 46 additions and 23 deletions

View File

@ -28,6 +28,7 @@
#include "qemu_alias.h" #include "qemu_alias.h"
#include "qemu_security.h" #include "qemu_security.h"
#include "qemu_dbus.h" #include "qemu_dbus.h"
#include "qemu_slirp.h"
#include "qemu_block.h" #include "qemu_block.h"
#include "cpu/cpu.h" #include "cpu/cpu.h"
#include "dirname.h" #include "dirname.h"
@ -3909,7 +3910,8 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
char **tapfd, char **tapfd,
size_t tapfdSize, size_t tapfdSize,
char **vhostfd, char **vhostfd,
size_t vhostfdSize) size_t vhostfdSize,
const char *slirpfd)
{ {
bool is_tap = false; bool is_tap = false;
VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER; VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER;
@ -3979,24 +3981,28 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
break; break;
case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_USER:
virBufferAddLit(&buf, "user,"); if (slirpfd) {
for (i = 0; i < net->guestIP.nips; i++) { virBufferAsprintf(&buf, "socket,fd=%s,", slirpfd);
const virNetDevIPAddr *ip = net->guestIP.ips[i]; } else {
VIR_AUTOFREE(char *) addr = NULL; virBufferAddLit(&buf, "user,");
const char *prefix = ""; for (i = 0; i < net->guestIP.nips; i++) {
const virNetDevIPAddr *ip = net->guestIP.ips[i];
VIR_AUTOFREE(char *) addr = NULL;
const char *prefix = "";
if (!(addr = virSocketAddrFormat(&ip->address))) if (!(addr = virSocketAddrFormat(&ip->address)))
goto cleanup; goto cleanup;
if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET))
prefix = "net="; prefix = "net=";
if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6)) if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6))
prefix = "ipv6-net="; prefix = "ipv6-net=";
virBufferAsprintf(&buf, "%s%s", prefix, addr); virBufferAsprintf(&buf, "%s%s", prefix, addr);
if (ip->prefix) if (ip->prefix)
virBufferAsprintf(&buf, "/%u", ip->prefix); virBufferAsprintf(&buf, "/%u", ip->prefix);
virBufferAddChar(&buf, ','); virBufferAddChar(&buf, ',');
}
} }
break; break;
@ -8312,10 +8318,10 @@ qemuInterfaceVhostuserConnect(virQEMUDriverPtr driver,
static int static int
qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virLogManagerPtr logManager, virLogManagerPtr logManager,
virSecurityManagerPtr secManager, virSecurityManagerPtr secManager,
virCommandPtr cmd, virCommandPtr cmd,
virDomainDefPtr def,
virDomainNetDefPtr net, virDomainNetDefPtr net,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,
unsigned int bootindex, unsigned int bootindex,
@ -8324,6 +8330,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
size_t *nnicindexes, size_t *nnicindexes,
int **nicindexes) int **nicindexes)
{ {
virDomainDefPtr def = vm->def;
int ret = -1; int ret = -1;
VIR_AUTOFREE(char *) nic = NULL; VIR_AUTOFREE(char *) nic = NULL;
VIR_AUTOFREE(char *) host = NULL; VIR_AUTOFREE(char *) host = NULL;
@ -8334,9 +8341,11 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
size_t vhostfdSize = 0; size_t vhostfdSize = 0;
char **tapfdName = NULL; char **tapfdName = NULL;
char **vhostfdName = NULL; char **vhostfdName = NULL;
VIR_AUTOFREE(char *) slirpfdName = NULL;
virDomainNetType actualType = virDomainNetGetActualType(net); virDomainNetType actualType = virDomainNetGetActualType(net);
virNetDevBandwidthPtr actualBandwidth; virNetDevBandwidthPtr actualBandwidth;
bool requireNicdev = false; bool requireNicdev = false;
qemuSlirpPtr slirp;
size_t i; size_t i;
@ -8562,6 +8571,16 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
slirp = QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp;
if (slirp && !standalone) {
int slirpfd = qemuSlirpGetFD(slirp);
virCommandPassFD(cmd, slirpfd,
VIR_COMMAND_PASS_FD_CLOSE_PARENT);
if (virAsprintf(&slirpfdName, "%d", slirpfd) < 0)
goto cleanup;
}
for (i = 0; i < tapfdSize; i++) { for (i = 0; i < tapfdSize; i++) {
if (qemuSecuritySetTapFDLabel(driver->securityManager, if (qemuSecuritySetTapFDLabel(driver->securityManager,
def, tapfd[i]) < 0) def, tapfd[i]) < 0)
@ -8586,7 +8605,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
if (!(host = qemuBuildHostNetStr(net, driver, if (!(host = qemuBuildHostNetStr(net, driver,
tapfdName, tapfdSize, tapfdName, tapfdSize,
vhostfdName, vhostfdSize))) vhostfdName, vhostfdSize,
slirpfdName)))
goto cleanup; goto cleanup;
virCommandAddArgList(cmd, "-netdev", host, NULL); virCommandAddArgList(cmd, "-netdev", host, NULL);
@ -8651,10 +8671,10 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
*/ */
static int static int
qemuBuildNetCommandLine(virQEMUDriverPtr driver, qemuBuildNetCommandLine(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virLogManagerPtr logManager, virLogManagerPtr logManager,
virSecurityManagerPtr secManager, virSecurityManagerPtr secManager,
virCommandPtr cmd, virCommandPtr cmd,
virDomainDefPtr def,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,
virNetDevVPortProfileOp vmop, virNetDevVPortProfileOp vmop,
bool standalone, bool standalone,
@ -8665,6 +8685,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
size_t i; size_t i;
int last_good_net = -1; int last_good_net = -1;
virErrorPtr originalError = NULL; virErrorPtr originalError = NULL;
virDomainDefPtr def = vm->def;
if (def->nnets) { if (def->nnets) {
unsigned int bootNet = 0; unsigned int bootNet = 0;
@ -8680,7 +8701,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
for (i = 0; i < def->nnets; i++) { for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i]; virDomainNetDefPtr net = def->nets[i];
if (qemuBuildInterfaceCommandLine(driver, logManager, secManager, cmd, def, net, if (qemuBuildInterfaceCommandLine(driver, vm, logManager, secManager, cmd, net,
qemuCaps, bootNet, vmop, qemuCaps, bootNet, vmop,
standalone, nnicindexes, standalone, nnicindexes,
nicindexes) < 0) nicindexes) < 0)
@ -10402,7 +10423,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
if (qemuBuildFilesystemCommandLine(cmd, def, qemuCaps) < 0) if (qemuBuildFilesystemCommandLine(cmd, def, qemuCaps) < 0)
return NULL; return NULL;
if (qemuBuildNetCommandLine(driver, logManager, secManager, cmd, def, if (qemuBuildNetCommandLine(driver, vm, logManager, secManager, cmd,
qemuCaps, vmop, standalone, qemuCaps, vmop, standalone,
nnicindexes, nicindexes, &bootHostdevNet) < 0) nnicindexes, nicindexes, &bootHostdevNet) < 0)
return NULL; return NULL;

View File

@ -90,7 +90,8 @@ char *qemuBuildHostNetStr(virDomainNetDefPtr net,
char **tapfd, char **tapfd,
size_t tapfdSize, size_t tapfdSize,
char **vhostfd, char **vhostfd,
size_t vhostfdSize); size_t vhostfdSize,
const char *slirpfd);
/* Current, best practice */ /* Current, best practice */
char *qemuBuildNicDevStr(virDomainDefPtr def, char *qemuBuildNicDevStr(virDomainDefPtr def,

View File

@ -1385,7 +1385,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
if (!(netstr = qemuBuildHostNetStr(net, driver, if (!(netstr = qemuBuildHostNetStr(net, driver,
tapfdName, tapfdSize, tapfdName, tapfdSize,
vhostfdName, vhostfdSize))) vhostfdName, vhostfdSize,
NULL)))
goto cleanup; goto cleanup;
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);