Skip to content

Commit

Permalink
sd-netlink: don't give up on netlink on ENOBUFS
Browse files Browse the repository at this point in the history
If our netlink input buffer overruns the kernel will send us ENOBUFS on
the next recvmsg(). Don't consider this a complete failure resulting in
closing of the netlink socket. Instead, simply continue (after debug
logging).

Of course, ideally we'd have a better strategy for this, and would have
a way to resync if this happens (as well as a scheme for cancelling all
ongoing asynchronous transactions), but for now let's at least not choke
fatally, and simply accept that we lost some messages and continue.

Note that if we lose messages when synchronously waiting for an
operation to complete, we'll still propagate the ENOBUFS up, to make the
individual transaction fail.

See: systemd#5398

(This bug does not properly fix the issue, hence we should leave the bug
open.)
  • Loading branch information
poettering committed Feb 21, 2017
1 parent 94c4c62 commit 71994cf
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/libsystemd/sd-netlink/netlink-socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
else if (errno == EAGAIN)
log_debug("rtnl: no data in socket");

return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
}

if (sender.nl.nl_pid != 0) {
Expand All @@ -292,7 +292,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
/* drop the message */
r = recvmsg(fd, &msg, 0);
if (r < 0)
return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
}

return 0;
Expand Down
4 changes: 4 additions & 0 deletions src/libsystemd/sd-netlink/sd-netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
if (rtnl->rqueue_size <= 0) {
/* Try to read a new message */
r = socket_read_message(rtnl);
if (r == -ENOBUFS) { /* FIXME: ignore buffer overruns for now */
log_debug_errno(r, "Got ENOBUFS from netlink socket, ignoring.");
return 1;
}
if (r <= 0)
return r;
}
Expand Down

0 comments on commit 71994cf

Please sign in to comment.