tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Userland API for threaded programs to reload /etc/resolv.conf



In article <20131101090648.GB29468%mail.duskware.de@localhost>,
Martin Husemann  <martin%duskware.de@localhost> wrote:
>Hey folks,
>
>assume you have a multi threaded, long running application. The app
>does regular DNS queries using the high level APIs (getaddrinfo(3) and
>friends) and uses a pool of threads specifically for those lookups.
>
>Every now and then it wants to make sure that /etc/resolv.conf changes get
>noticed and used by the resolver.

This is not the job of the application. Our resolver handles this just fine.
It uses a kqueue to register for file update events to /etc/resolv.conf,
and updates itself internally when needed.

>On FreeBSD and Linux each thread has a local _res variable, so the app
>simply does:
>
>       res_ninit(&_res);
>
>Scream, tear, feather! This is mixing the ancient (_res) API with the new
>thread safe low level resolver API. But it is simple and works. Especially
>given that there are NO other calls to the low level API.

Yes, this is what we need; more magic.

>Now on NetBSD this gets tricky. We cause an assertion failure when _res is
>accessed from threaded programs.
>
>The way to fix this with existing means seems to be: make the timeout
>variable global and whenever one resolve threads hits the timeout, make
>it reset the global variable atomically and then simply do:
>
>       res_init();

This will not work in a threaded environment and is a step backwards.

>Now looking back at the whole picture, it seems that this all should
>not be necessary at all. IMHO the resolver library should deal with it
>internally, have a (application settable) timeout and after the timeout
>expired stat /etc/resolv.conf on next access - and internally deal.
>
>An alternative would be to have a full set of getaddrinfo_r(3),
>getnameinfo_r(3), gethostbyaddr_r(3), gethostbyname_r(3), which get
>passed a res_state*, so the resolver threads could just use a local
>res_state and do res_init() on that whenever they like.
>
>Did I overlook other options? Is there any precedence for the internal
>solution (automatic res_ninit on changes of /etc/resolv.conf) in other
>systems? Comments?

You don't neeed getaddrinfo_r and getnameinfo_r. The getaddrinfo and
getnameinfo functions are thread-safe since they create and destroy
their own res internally. Avoid using gethostbyname_r and gethostbyaddr_r
since those are non portable.

If you just use getaddrinfo() and getnameinfo() on NetBSD everything
will work just fine.

christos



Home | Main Index | Thread Index | Old Index