Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Oct 2015 10:13:02 -0600
From:      Warner Losh <imp@bsdimp.com>
To:        Eric van Gyzen <vangyzen@freebsd.org>
Cc:        "freebsd-arch@freebsd.org" <freebsd-arch@freebsd.org>
Subject:   Re: RFC: Automatically Reloading /etc/resolv.conf
Message-ID:  <CANCZdfp7k8wwU%2B0ChXD8rVK0kWq5F%2BORpjCH46Gg5qUq9Fw3xw@mail.gmail.com>
In-Reply-To: <5615886F.3060601@FreeBSD.org>
References:  <5615886F.3060601@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Oct 7, 2015 at 3:02 PM, Eric van Gyzen <vangyzen@freebsd.org> wrote:

> I would like to change the libc resolver to automatically reload
> /etc/resolv.conf when the latter changes.  I would like to hear opinions
> about the implementation.  Broadly, I see two approaches.
>
> == "stat" ==
>
> When loading the file, record the mod time.  Before each query, stat()
> the file to see if it has changed.
>
> Advantage:  It uses no extra persistently allocated objects.
>
> Disadvantage:  It incurs a stat() on every query.  I don't see this as a
> major disadvantage, since the resolver already does a lot of work on
> every query.  (For example, it creates and destroys a kqueue and a socket.)
>
> OpenBSD uses this approach.  It also uses clock_gettime(CLOCK_MONOTONIC)
> to rate-limit the stat() calls to one per several seconds.
>

Make sure you rate limit it. Calling stat at a high rate from multiple CPUs
exposes poor locking
scaleability and eats a lot of CPU. We had some setting wrong on NGINX at
work that lead to
large NGINX latency spikes because this contention was blocking the worker
threads. Correcting
the settings to cache the results of stat made this problem disappear.


> == "kqueue" ==
>
> When loading the file, open a kqueue and register for the appropriate
> events.  Before each query, check for kevents.
>
> Advantage:  The per-query overhead is fairly small.
>
> Disadvantage:  This would persistently allocate an open file and a
> kqueue for every thread that ever uses the resolver, for the life of the
> thread.  This seems fairly expensive.
>

Why does this follow? Can't you have a global one for the process?


> NetBSD uses this approach.  It mitigates most of the space-cost by using
> a shared pool of res_state objects, instead of one per thread [that uses
> the resolver].  On each query, a thread allocates/borrows a res_state
> from the pool, uses it, and returns it.  So, the number of objects is
> only the high water mark of the number of threads _concurrently_ issuing
> resolver queries.n
>

What's the locking scaleability here when resolv.conf changes?

There are probably several variations on each theme, of course.  I would
> appreciate your thoughts on these approaches and others I missed, as
> well as variations and details.
>
> FYI, I'm leaning toward the "stat" approach.
>

It sounds simpler to implement, but likely a higher overhead than the
kqueue approach. resolv.conf changes on an time scale measured in minutes
or hours for the mobile user, and on the scale of years for servers.
Polling on the scale of seconds (at least two orders of magnitude faster
than the rate of change) seems like a lot of extra work over the life of
resolv.conf.

Warner



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANCZdfp7k8wwU%2B0ChXD8rVK0kWq5F%2BORpjCH46Gg5qUq9Fw3xw>