Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re^5: A few questions regarding Proc::Daemon

by afoken (Chancellor)
on Nov 09, 2013 at 22:33 UTC ( #1061872=note: print w/replies, xml ) Need Help??

in reply to Re^4: A few questions regarding Proc::Daemon
in thread A few questions regarding Proc::Daemon

Ohhh, stupid me! Sorry, I thought you were saying to replace upstart, init, systemd, etc with daemontools.

Yes, this is possible and can be useful, but it is rarely used.

I just figured that the daemon would need to understand stop, status, etc in order to shutdown gracefully, give a status, and so on.


I guess I was wrong in this assumption?

No. The daemon has to receive some kind of message that tells it to shutdown, re-read the configuration, deliver some status, and so on. UNIX systems typically use signals for that purpose:

  • SIGTERM is used for a graceful shutdown. If you don't need a graceful shutdown (because you run a very simple-minded daemon), just don't set up a signal handler for SIGTERM, so your process will simply die when it receives SIGTERM.
  • SIGKILL is used for a hard shutdown. Your process will die, and you can't do anything against that.
  • SIGHUP was originally used to inform a process that the connection to the user's terminal was ended (modem hang up). This is obviously useless for deamons, so they use that signal to re-read the configuration or re-initialise. Set up a signal handler for this signal, or at least make your process ignore the HUP signal, or any SIGHUP sent to your daemon will terminate it.
  • SIGINT was originally used to abort a process (via Ctrl-C). Like SIGHUP, this is useless for daemons, but you need to setup a signal handler or ignore the INT signal, or any SIGINT will terminate your daemon.
  • SIGUSR1 and SIGUSR2 are free to use, but like SIGINT and SIGHUP, they will terminate your daemon unless you set up a signal handler or explicitly ignore those signals. SIGUSR1 and SIGUSR2 are often used for things like toggling debug mode or write a status file.

Tools like daemontools send those signals to your daemon process. On a system with a classic init, your daemon (or its startup script) needs to write a PID file so that you know the PID of your daemon: kill -HUP `cat /var/run/`. Daemontools and the other tools know the PID because the daemon runs as a child process of the monitor process (supervise in case of daemontools), and you ask the monitor process to send a signal to your daemon process (svc -h /service/my-daemon). The advantage over PID files is that there is no race condition and no problem with an unclean shutdown.

Daemontools were written by djb, who has some very strange opinions about errno. gcc on Linux will simply not compile his code, because djb insists on declaring errno as extern int. This is plain wrong, so you need to change that to #include <errno.h>. (See the djb way - errno patches) There are patches available for this, and a second patch that adds the signals QUIT, USR1 and USR2 to daemontools, see the djb way - daemontools - installation.

runit works nearly the same, except that the program names are a little bit different (svscanboot is runit, svscan is runsvdir, supervise is runsv, svc is sv, multilog is svlogd). And of course: no trouble with errno.

The point here is that your daemon contains code to handle the signals, but no code to send those signals. This is the job of daemontools, runit, or the start script.

Configuration in the djb way is done by passing environment variables to your daemon. The envdir program reads them from a directory of files, one file per variable. Or, the run script simply sets them. Of course, you can still read your own configuration file and ignore the environment variables.

Dropping privileges is also done outside the daemon, using the setuidgid program.

Running a TCP service on a privileged port (0-1023) without root privileges is possible, using ucspi-tcp. These programs (mainly tcpserver) open a socket as root, and pass the socket though setuidgid to the daemon running without root privileges - simply as STDIN and STDOUT, just like inetd does.

SSL requires no changes to the daemon, just replace tcpserver with sslserver from ucspi-ssl.

Of course, you can do all of this in your daemon code. But daemontools and friends are there to avoid all of that extra work.


Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1061872]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2023-12-08 15:28 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (36 votes). Check out past polls.