Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 181343

Summary: pdns_recursor rec_control function is broken when chroot is enabled
Product: Gentoo Linux Reporter: Jefferson Noxon <jeff-gentoo>
Component: New packagesAssignee: Sven Wegener <swegener>
Status: RESOLVED FIXED    
Severity: normal    
Priority: High    
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard:
Package list:
Runtime testing required: ---

Description Jefferson Noxon 2007-06-08 19:58:15 UTC
pdns_recursor uses unix domain sockets to communicate with the command-line utility rec_control.  When the chroot= configuration parameter is set (the default setting is /var/empty), the rec_control program no longer works.

The reason for the breakage is that a new unix domain socket is created for each rec_control request.  The powerdns recursor looks for these files in LOCALSTATEDIR (defined in config.h) unless --socket-dir is specified on the command line or socket-dir is changed in /etc/powerdns/recursor.conf.  When pdns_recursor is chrooted, it cannot access these files and therefore cannot respond to rec_control commands.

An unfortunate side-effect of the socket-dir option is that it also changes where pdns_recusor puts its PID file.  Therefore if the sysadmin changes it, the init.d script breaks and can no longer stop the daemon.

I advocate changing the default LOCALSTATEDIR in config.h to /var/run/powerdns .

This allows the following workaround to the chroot problem:

mkdir -p /var/empty/var/run
mv /var/run/powerdns /var/empty/var/run
ln -s /var/empty/var/run/powerdns /var/run

At this point, rec_control will create its sockets within the chroot-accessable portion of the filesystem.  pdns_recursor will be able to respond to rec_control commands.

Reproducible: Always

Steps to Reproduce:
1. Set "chroot=/var/empty" in /etc/powerdns/recursor.conf (this is the ebuild default!)
2. /etc/init.d/precursor start
3. rec_control ping

Actual Results:  
rec_control hangs

Expected Results:  
rec_control gives "pong" response

SuSE's solution is to use /var/run/pdns ... but conffiles on SuSE are also stored in /etc/pdns.  I suggest, since gentoo uses /etc/powerdns, that /var/run/powerdns is used for consistency.

It is also necessary to change the initscript to use the pid file in /var/run/powerdns.

Aside from the PID file problem associated with changing the socket-dir entry in the config file (as noted above), it is also worth mentioning that rec_control does not parse the config file, so if LOCALSTATEDIR is not changed in the code and the socket directory is changed in the config file, it's always necessary to pass --socket-dir= to rec_control... Which is somewhat cumbersome.

Is /var/empty really a good name for the chroot dir?  It's not very descriptive.
Comment 1 Sven Wegener gentoo-dev 2007-06-08 21:50:29 UTC
I know that rec_control is broken.

The main problem is that the recursor uses datagram sockets. When using stream sockets the recursor could pass the answer back the same way the request came in. I initially wrote the init script stop action with "rec_control quit" until I noticed that the chroot support breaks it. IMHO a chroot'ed daemon shouldn't need to open back a connection to the outside of the chroot.

In an ideal world the recursor would only need an empty directory for chroot, hence the current uhm "historic" default is /var/empty.
Comment 2 Sven Wegener gentoo-dev 2007-06-08 22:30:58 UTC
I updated the package. The chroot directory is now /var/lib/powerdns, statedir is /var/run/powerdns, being a symlink to /var/lib/powerdns/var/run/powerdns. Init script now uses rec_control quit to stop the recursor and also has a ping command. 

Thanks!
Comment 3 Sven Wegener gentoo-dev 2007-06-11 19:17:12 UTC
I updated it once more. Our bootmisc init script will remove the symlink in /var/run during boot. I now made the state and chroot directory /var/lib/powerdns and /var/lib/powerdns/var/lib/powerdns a symlink to ../..

Not really clean, but that's the way it is. :(