[Pianod] /etc/resolv.conf issue

Peter Li chinasaurli at gmail.com
Fri Sep 6 01:33:49 PDT 2013


So I finally tracked down a long-standing issue I've had on my Arch 
Linux ARM RasPi.  Gets back to the bad old days of getaddrinfo()! Not 
sure if this is related to problems other people had, but on my system 
the issue appears to be:
     1) pianod starts at boot before the network stack
     2) As a result, the first call to getaddrinfo() calls res_init() to 
load DNS servers from /etc/resolv.conf but they haven't been written 
into there yet by DHCP.  Bad DNS info gets stored in the process's 
global _res (I think, or maybe it's _res_state or _res_status or 
somesuch name)
     3) pianod is well behaved and keeps trying to reconnect at 60 
second intervals, but it never manages to shake the bad DNS info loaded 
into the process's globals, so getaddrinfo() continues to return 
EAI_NONAME ad infinitum

Patching waitress.c to manually re-call res_init() after a getaddrinfo() 
failure seems to fix things, i.e. pianod can successfully connect on its 
first 60 second retry after boot.  While Mac OS doesn't seem to have the 
problem in the first place (probably because it's easier to make sure 
that pianod doesn't start before the network stack) I believe this patch 
should be safe in terms of not messing up pianod on Mac OS.  The only 
thing I'm not sure about is whether we need to link libwaitress against 
libresolv; it doesn't seem necessary on my Linux, but probably should be 
in the Makefile to be safe.  Perette maybe you can try it, or else I'll 
try on a Mac this weekend.

This does make me wonder why this didn't come up with WSGW, where I 
recall there being a similar issue...

I'll look into submitting patch upstream; apparently pianobar is on GitHub?
P

    Index: libwaitress/waitress.c
    ===================================================================
    --- libwaitress/waitress.c    (revision 149)
    +++ libwaitress/waitress.c    (working copy)
    @@ -40,6 +40,7 @@
      #include <errno.h>
      #include <assert.h>
      #include <stdint.h>
    +#include <resolv.h>

      #include <gnutls/x509.h>

    @@ -779,17 +780,27 @@
          hints.ai_socktype = SOCK_STREAM;

          /* Use proxy? */
    +  int gaierror;
          if (WaitressProxyEnabled (waith)) {
    -        if (getaddrinfo (waith->proxy.host,
    -                WaitressDefaultPort (&waith->proxy), &hints, &res)
    != 0) {
    -            return WAITRESS_RET_GETADDR_ERR;
    -        }
    +        gaierror = getaddrinfo (waith->proxy.host,
    +                WaitressDefaultPort (&waith->proxy), &hints, &res);
          } else {
    -        if (getaddrinfo (waith->url.host,
    -                WaitressDefaultPort (&waith->url), &hints, &res) !=
    0) {
    -            return WAITRESS_RET_GETADDR_ERR;
    -        }
    +        gaierror = getaddrinfo (waith->url.host,
    +                WaitressDefaultPort (&waith->url), &hints, &res);
          }
    +  if (gaierror != 0) {
    +    /* If process started at boot, before network stack, it can get
    into a
    +     * persistent state of getaddrinfo fail with EAI_NONAME. I
    believe this
    +     * is because /etc/resolv.conf was not initialized when the
    first DNS
    +     * attempt was made and the process gets stuck with bad DNS
    server info.
    +     *
    +     * res_init() normally runs on the first DNS query and then is
    cached by
    +     * the process in global _res.  Rerunning res_init() manually
    seems to fix
    +     * the issue.
    +     */
    +    res_init();
    +    return WAITRESS_RET_GETADDR_ERR;
    +  }

          if ((waith->request.sockfd = socket (res->ai_family,
    res->ai_socktype,
                  res->ai_protocol)) == -1) {


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.deviousfish.com/pipermail/pianod-deviousfish.com/attachments/20130906/f12e2129/attachment-0002.htm>


More information about the Pianod mailing list