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 <[email protected]> Reviewed-by: Maksim Davydov <[email protected]> --- net/tap.c | 90 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/net/tap.c b/net/tap.c index b01cd4d6c2..d08ef070e9 100644 --- a/net/tap.c +++ b/net/tap.c @@ -86,11 +86,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); @@ -361,6 +361,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) @@ -420,12 +425,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; @@ -435,7 +442,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) @@ -685,7 +721,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); @@ -726,7 +762,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); @@ -745,53 +784,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
