[Dnsmasq-discuss] [PATCH] fix for netlink ENOBUF problem

Ivan Kokshaysky ink at jurassic.park.msu.ru
Wed Jul 6 14:55:27 BST 2016


On Mon, Jul 04, 2016 at 01:58:43PM -0400, wkitty42 at gmail.com wrote:
> On 07/04/2016 11:29 AM, Ivan Kokshaysky wrote:
> > To fix that we need to purge the netlink buffer on ENOBUF error. With the
> > appended patch dnsmasq is running flawlessly for about a month.
> 
> why are the messages not removed from the buffer when they are processed? or are 
> they and there's simply too many messages coming in to handle?

Good questions, thanks.

It's certainly possible to drop these messages during normal processing -
if the message process ID is correct, but sequence number is wrong,
the message must be dropped (instead of putting it on async queue
like it happens now, and it's a real bug, BTW). In fact I tried this
approach first and it sort of worked, but then I went to "flush" because
it was much easier to debug and also had some minor advantages:
- less risk to hit ENOBUFS again on the next netlink request
  as the buffer is just flushed;
- no additional checks in a fast code path.

As for too many async messages coming in, I doubt that. In our config
all interfaces are static and never change their state. Of course, there are
lots of events like new neighbor appearance and so on, but as far as
I can see they are masked out and should not disturb dnsmasq.

> how large is the buffer? can it be made larger to handle the larger amount of 
> message traffic?

It's rather large, some 120 kB by default, IIRC. Even with thousands of
interfaces it's enough to keep dnsmasq happy most of the time. I'm not
a netlink specialist, but from what I read enlarging socket buffer is
generally not considered like a very good idea, as it won't eliminate
ENOBUFS, just delay it.

> what problem(s) will requesting devices run into when there is no response to 
> their query when the message is flushed?

Not a big deal, I think. After ENOBUFS our view on the system state
is not valid anymore. We don't know if the device in questions hasn't
requested again while we were out of buffer space. As netlink(7) says:

"However, reliable transmissions from kernel to user are impossible
 in any case. The kernel can't send a netlink message if the socket
 buffer is full: the message will be dropped and the kernel and the
 user-space process will no longer have the same view of kernel state.
 It is up to the application to detect when this happens (via the ENOBUFS
 error returned by recvmsg(2)) and resynchronize."

> would fixing/solving (one of?) the above be better than flushing?

Personally I like flushing more, because I think it fits in "resynchronize"
mentioned above. But I'd also be fine with a proper check for pid/seq in
the normal message processing path. It's up to authors to decide :)

Ivan.



More information about the Dnsmasq-discuss mailing list