Until very recently, I never realized how much work went into creating a proper daemon program for a linux system. I had always assumed that sysinitv and the distro’s init function library (eg. daemon() in redhat/cent) handled all of the details. I wrote a simple python “daemon” to handle some task I was working on, and was surprised to find that the “daemon” was about as un-daemonlike as it could be. A ‘service start ‘ immediately started displaying the stdout/stderr of the program, and the service binary never returned until a ctrl-C was entered. Whoops.
So as it turns out, there’s a bit of stuff you have to do in the program itself to properly daemonize. Specifically, you need to double-fork so that the daemon process becomes a session and process group leader, then close both parent processes so that the daemon can never have a terminal attached. There’s a few other details as well, which thankfully are pretty well documented. Also, it’s awesome that python has native bindings for every required bit of functionality in the os module. Really makes things easier.
For a while, I just ran my daemon using upstart rather than sysinitv, which seemed to magically handle all of the details with zero daemonization efforts in the code itself (plus, the respawn feature is really nice). However, it was a rather cool experience digging into the gritty details of how daemon processes actually work.