I'm running pianod, a Pandora client/server, on a Raspberry Pi with Arch Linux ARM. I have pianod set up to run as a service at boot. It starts up before the network stack, so getaddrinfo() fails. This should be okay; pianod is setup to retry network login every 60 seconds.

(Aside: I tried obvious things to get systemd to wait for the network stack before starting pianod, but it wasn't working. On the systemd list, I was advised that really I should just try to make my process behave well if network isn't available, a perspective I can appreciate. There are other hacks to make my process sleep during boot, etc.. I'd be interested if there is such a hack that's actually standard for some reason, but would prefer a clean solution.)

Despite pianod retrying network every 60 seconds after initial fail on boot, getaddrinfo() persists in returning EAI_NONAME. If I restart the process manually everything works.

The issue seems to be that on the first call to getaddrinfo() on boot, res_init() is called and tries to load /etc/resolv.conf. Since DHCP hasn't initialized that file with proper DNS information yet (?), this loads bad DNS (localhost I think) information into the process's global _res variable. The process is then stuck with EAI_NONAME.

Adding a manual re-call to res_init() to reload DNS info after failed getaddrinfo() calls makes the thing work, i.e. getaddrinfo() succeeds on the first login retry 60 s after boot.

BUT... I'm pretty surprised that this is an issue. I have another service that does essentially the same thing and doesn't seem to need the manual res_init(). The other process does a bit more fork(), but I don't see where it would escape from the bad _res global. In general I'm surprised Linux is setup to have this issue.

So I felt like I should ask around what I might be missing here. Does my interpretation sound correct? If so, why is this not handled better upstream? If not, what more should I look into? Are there better standard ways to handle this?

UPDATE: as requested, here's the current service unit description. I have tried adding After=network.target as well as Requires. From what the systemd folks said, these aren't reliable from one distro to the next...

Description=Pandora Client Daemon

ExecStart=/usr/sbin/pianod $INITSCRIPT $USERFILE $PORT $LOGGING -nroot

  • Can you post your pianod service file? – jasonwryan Sep 6 '13 at 19:48
  • 1
    Can't you stick the thing trying to be resolved into your /etc/hosts file? (making sure your /etc/nsswitch.conf: has hosts: files dns) – Drav Sloan Sep 6 '13 at 20:34
  • Yes, /etc/hosts should work as long as the Pandora server doesn't change... – Chinasaur Sep 7 '13 at 3:56

The Unix interfaces and internal design date back from a time when a network configuration was a very static thing. There were no laptops and no dynamic IP addresses assigned by DHCP. Therefore the system wasn't designed to send an event to applications when the network configuration changes. Applications read the DNS configuration in /etc/resolv.conf once when they start, and that's it.

The modern way to cope with changing network configurations is to run a local DNS proxy. It admittedly took a long time, but more and more distributions are starting to make this a default configuration (I think Ubuntu starting doing it with 12.04). Have only listed as a name server in /etc/resolv.conf, and let your DNS proxy cope with the configuration changes.

Dnsmasq is a popular choice for a lightweight DNS proxy and server. Choose it unless you have a good reason to pick another. It's what Ubuntu uses. It's also what my home router with a MIPS processor and 16MB RAM runs, so your Pi is strongly overpowered to run it.

As usual Arch Linux doesn't ship with a working configuration out of the box but the wiki has clear and detailed instructions.

  • Thanks; this seems to be the right answer from the user perspective. From the application perspective (pianod is open source), I would still like to know if there is a better solution than re-calling res_init() after GAI failures. I suppose I could look in _res manually to check if it looks like something silly is there and only then call res_init()...? – Chinasaur Sep 8 '13 at 4:38
  • Except poking into _res is probably brittle, and as you point out, localhost is not an inherently silly thing to find there... – Chinasaur Sep 8 '13 at 4:43
  • @Chinasaur You could call res_init again after a failure, but it isn't the normal thing to do. I don't even know if calling it multiple times is supported. From an application perspective, this is up to the system administrator. – Gilles 'SO- stop being evil' Sep 8 '13 at 11:15
  • The docs imply that you can do it, but they do say it's unusual. I mean, it would seem weirder to me to require a DNS proxy as a dependency for pianod, so I don't see too many options... – Chinasaur Sep 10 '13 at 2:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.