Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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...

[Unit]
Description=Pandora Client Daemon
After=syslog.target

[Service]
EnvironmentFile=/etc/pianod.env
ExecStart=/usr/sbin/pianod $INITSCRIPT $USERFILE $PORT $LOGGING -nroot
Restart=on-abort

[Install]
WantedBy=multi-user.target
share|improve this question
    
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
add comment

1 Answer

up vote 2 down vote accepted

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 127.0.0.1 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.

share|improve this answer
    
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 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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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