Last step to get rid of dependency on @tap in net_tap_setup().
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
net/tap.c | 96 ++++++++++++++++++++++++++++++-------------------------
1 file changed, 53 insertions(+), 43 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index b4682d7400..b7175e4b10 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -83,11 +83,11 @@ typedef struct TAPState {
bool sndbuf_required;
int sndbuf;
+ int vhostfd;
+ uint32_t vhost_busyloop_timeout;
} TAPState;
-static bool net_tap_setup(TAPState *s, const NetdevTapOptions *tap,
- const char *vhostfdname,
- int fd, int vnet_hdr, Error **errp);
+static bool net_tap_setup(TAPState *s, int fd, int vnet_hdr, Error **errp);
static void launch_script(const char *setup_script, const char *ifname,
int fd, Error **errp);
@@ -336,6 +336,11 @@ static void tap_cleanup(NetClientState *nc)
tap_write_poll(s, false);
close(s->fd);
s->fd = -1;
+
+ if (s->vhostfd != -1) {
+ close(s->vhostfd);
+ s->vhostfd = -1;
+ }
}
static void tap_poll(NetClientState *nc, bool enable)
@@ -394,12 +399,14 @@ static NetClientInfo net_tap_info = {
};
static TAPState *net_tap_new(NetClientState *peer, const char *model,
- const char *name, const NetdevTapOptions *tap)
+ const char *name, const NetdevTapOptions *tap,
+ const char *vhostfdname, Error **errp)
{
NetClientState *nc = qemu_new_net_client(&net_tap_info, peer, model, name);
TAPState *s = DO_UPCAST(TAPState, nc, nc);
s->fd = -1;
+ s->vhostfd = -1;
if (!tap) {
return s;
@@ -409,7 +416,39 @@ static TAPState *net_tap_new(NetClientState *peer, const char *model,
s->sndbuf =
(tap->has_sndbuf && tap->sndbuf) ? MIN(tap->sndbuf, INT_MAX) : INT_MAX;
+ if (tap->has_vhost ? tap->vhost :
+ vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
+ if (vhostfdname) {
+ s->vhostfd = monitor_fd_param(monitor_cur(), vhostfdname, errp);
+ if (s->vhostfd == -1) {
+ goto failed;
+ }
+ if (!g_unix_set_fd_nonblocking(s->vhostfd, true, NULL)) {
+ error_setg_errno(errp, errno, "Can't use file descriptor %d",
+ s->fd);
+ goto failed;
+ }
+ } else {
+ s->vhostfd = open("/dev/vhost-net", O_RDWR);
+ if (s->vhostfd < 0) {
+ error_setg_errno(errp, errno,
+ "tap: open vhost char device failed");
+ goto failed;
+ }
+ if (!g_unix_set_fd_nonblocking(s->vhostfd, true, NULL)) {
+ error_setg_errno(errp, errno, "Failed to set FD nonblocking");
+ goto failed;
+ }
+ }
+
+ s->vhost_busyloop_timeout = tap->poll_us;
+ }
+
return s;
+
+failed:
+ qemu_del_net_client(&s->nc);
+ return NULL;
}
static bool net_tap_set_fd(TAPState *s, int fd, int vnet_hdr, Error **errp)
@@ -657,7 +696,7 @@ int net_init_bridge(const Netdev *netdev, const char *name,
return -1;
}
- s = net_tap_new(peer, "bridge", name, NULL);
+ s = net_tap_new(peer, "bridge", name, NULL, NULL, &error_abort);
net_tap_set_fd(s, fd, vnet_hdr, &error_abort);
qemu_set_info_str(&s->nc, "helper=%s,br=%s", helper, br);
@@ -700,7 +739,10 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
const char *downscript, const char *vhostfdname,
int vnet_hdr, int fd, Error **errp)
{
- TAPState *s = net_tap_new(peer, model, name, tap);
+ TAPState *s = net_tap_new(peer, model, name, tap, vhostfdname, errp);
+ if (!s) {
+ return;
+ }
if (tap->fd || tap->fds) {
qemu_set_info_str(&s->nc, "fd=%d", fd);
@@ -719,56 +761,24 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
}
}
- if (!net_tap_setup(s, tap, vhostfdname, fd, vnet_hdr, errp)) {
+ if (!net_tap_setup(s, fd, vnet_hdr, errp)) {
qemu_del_net_client(&s->nc);
}
}
-static bool net_tap_setup(TAPState *s, const NetdevTapOptions *tap,
- const char *vhostfdname,
- int fd, int vnet_hdr, Error **errp)
+static bool net_tap_setup(TAPState *s, int fd, int vnet_hdr, Error **errp)
{
- int vhostfd;
-
if (!net_tap_set_fd(s, fd, vnet_hdr, errp)) {
return false;
}
- if (tap->has_vhost ? tap->vhost :
- vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
+ if (s->vhostfd != -1) {
VhostNetOptions options;
options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
options.net_backend = &s->nc;
- if (tap->has_poll_us) {
- options.busyloop_timeout = tap->poll_us;
- } else {
- options.busyloop_timeout = 0;
- }
-
- if (vhostfdname) {
- vhostfd = monitor_fd_param(monitor_cur(), vhostfdname, errp);
- if (vhostfd == -1) {
- return false;
- }
- if (!g_unix_set_fd_nonblocking(vhostfd, true, NULL)) {
- error_setg_errno(errp, errno, "Can't use file descriptor %d",
- fd);
- return false;
- }
- } else {
- vhostfd = open("/dev/vhost-net", O_RDWR);
- if (vhostfd < 0) {
- error_setg_errno(errp, errno,
- "tap: open vhost char device failed");
- return false;
- }
- if (!g_unix_set_fd_nonblocking(vhostfd, true, NULL)) {
- error_setg_errno(errp, errno, "Failed to set FD nonblocking");
- return false;
- }
- }
- options.opaque = (void *)(uintptr_t)vhostfd;
+ options.busyloop_timeout = s->vhost_busyloop_timeout;
+ options.opaque = (void *)(uintptr_t)s->vhostfd;
options.nvqs = 2;
options.feature_bits = kernel_feature_bits;
options.get_acked_features = NULL;
--
2.48.1