Skip to content

Commit

Permalink
tools: ynl: use MSG_DONTWAIT for getting notifications
Browse files Browse the repository at this point in the history
To stick to libmnl wrappers in the past we had to use poll()
to check if there are any outstanding notifications on the socket.
This is no longer necessary, we can use MSG_DONTWAIT.

Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Link: https://lore.kernel.org/r/20240227223032.1835527-16-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Feb 28, 2024
1 parent 73395b4 commit 7c4a38b
Showing 1 changed file with 14 additions and 15 deletions.
29 changes: 14 additions & 15 deletions tools/net/ynl/lib/ynl.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,16 +458,20 @@ static int ynl_cb_null(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg)
return YNL_PARSE_CB_ERROR;
}

static int ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb)
static int
__ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb, int flags)
{
struct ynl_sock *ys = yarg->ys;
const struct nlmsghdr *nlh;
ssize_t len, rem;
int ret;

len = recv(ys->socket, ys->rx_buf, YNL_SOCKET_BUFFER_SIZE, 0);
if (len < 0)
len = recv(ys->socket, ys->rx_buf, YNL_SOCKET_BUFFER_SIZE, flags);
if (len < 0) {
if (flags & MSG_DONTWAIT && errno == EAGAIN)
return YNL_PARSE_CB_STOP;
return len;
}

ret = YNL_PARSE_CB_STOP;
for (rem = len; rem > 0; NLMSG_NEXT(nlh, rem)) {
Expand Down Expand Up @@ -509,6 +513,11 @@ static int ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb)
return ret;
}

static int ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb)
{
return __ynl_sock_read_msgs(yarg, cb, 0);
}

static int ynl_recv_ack(struct ynl_sock *ys, int ret)
{
struct ynl_parse_arg yarg = { .ys = ys, };
Expand Down Expand Up @@ -797,18 +806,8 @@ int ynl_ntf_check(struct ynl_sock *ys)
int err;

do {
/* libmnl doesn't let us pass flags to the recv to make
* it non-blocking so we need to poll() or peek() :|
*/
struct pollfd pfd = { };

pfd.fd = ys->socket;
pfd.events = POLLIN;
err = poll(&pfd, 1, 1);
if (err < 1)
return err;

err = ynl_sock_read_msgs(&yarg, ynl_ntf_trampoline);
err = __ynl_sock_read_msgs(&yarg, ynl_ntf_trampoline,
MSG_DONTWAIT);
if (err < 0)
return err;
} while (err > 0);
Expand Down

0 comments on commit 7c4a38b

Please sign in to comment.