Continue the track to avoid dependency on @tap in net_tap_setup(),
no move the vhost fd initialization to net_tap_new(). So in
net_tap_setup() we simply check, do we have and vhostfd at this
point or not.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
net/tap.c | 90 ++++++++++++++++++++++++++++++-------------------------
1 file changed, 50 insertions(+), 40 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 877564405a..dbd1eb3a17 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);
@@ -351,6 +351,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)
@@ -409,12 +414,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;
@@ -424,7 +431,36 @@ 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 (!qemu_set_blocking(s->vhostfd, false, errp)) {
+ 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 (!qemu_set_blocking(s->vhostfd, false, errp)) {
+ goto failed;
+ }
+ }
+
+ s->vhost_busyloop_timeout = tap->has_poll_us ? tap->poll_us : 0;
+ }
+
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)
@@ -671,7 +707,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);
@@ -712,7 +748,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);
@@ -731,53 +770,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 (!qemu_set_blocking(vhostfd, false, errp)) {
- 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 (!qemu_set_blocking(vhostfd, false, errp)) {
- 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