Scripts as Reliable Daemons
Overview
Here is a step-by-step tutorial on one way that I've found to deploy simple scripts as reliable daemons using the Daemontools package and Multilog facilities provided by D. J. Bernstein.
If you are familiar with QMail, you are probably familiar with one of the many brilliant applications created by the
DJB; Daemontools. In a QMail install, it keeps the various parts running and resident in memory no matter what happens, even after you explicitly kill them.
Also, Daemontools is packaged with a very nice logging package, called Multilog. The combination of Daemontools and Multilog makes a great base to deploy scripts/applications that need to react to events, either internal or external. It keeps you out of the business of creating true daemons, handles log rolling, log time-stamping and allows you manage your scripts or applications that you write as services that are started and stopped. Once your system is setup with these tools, all you have to do is write the logic to perform the task you want. Daemontools and Multilog handle the rest of the stuff.
It doesn't really matter what language you write your "daemon" in, as long as it will execute and hopefully sleep for a few seconds between runs.
Example: /etc/passwd Monitor
As an example, I'll show how to write a "daemon" with daemontools that will monitor your /etc/passwd file for changes and email you when it is changed. Here is what you need:
- 1) http://cr.yp.to/daemontools/daemontools-0.76.tar.gz - The Daemontools package, this includes Multilog
- 2) Exactly follow the instructions here to install it: http://cr.yp.to/daemontools/install.html
- 3) On certain types of systems, you will need to reboot in order for the installation to take effect. This is because Daemontools actually becomes part of run-level of you machine.
The installation process will create a directory called /service. This directory is where you define what scripts/applications you want to run as daemons. Next, create the directory structure to house the necessary shell scripts that Daemontool is looking for to manage your application.
# mkdir /usr/local/bin/daemons/supervise/
# mkdir /usr/local/bin/daemons/supervise/passwdmon/
# mkdir /usr/local/bin/daemons/supervise/passwdmon/supervise/
# mkdir /usr/local/bin/daemons/supervise/passwdmon/log/
Now, create the script that you want to run (/usr/local/bin/passwdmon.php) and make it executable. In PHP, I've simply used a while(1) construct to keep it in memory and sleep() function to stop it from running 24/7 and consuming too much CPU.
#!/usr/bin/bash
<?
$passwdfile = "/etc/passwd";
while (1)
{
$thismodtime = filemtime($passwdfile);
if ($lastmodtime != $thismodtime)
{
echo "Your /etc/passwd file has changed";
mail("user@domain.com","/etc/passwd changed","/etc/passwd file changed on machine x");
}
$lastmodtime = $thismodtime;
sleep(10);
}
?>
Now, you will need to create a run script for daemontools. Daemontools looks for a file named 'run' in the supervise/passwdmon/ directory that you created.
#!/bin/sh
exec /usr/local/bin/passwdmon.php
Make both the script you wrote and the 'run' script executable:
# chmod 755 /usr/local/bin/passwdmon.php
# chmod 755 /usr/local/bin/daemons/supervise/passwdmon/run
Now, create a symbolic link to your supervise directory from /service
# ln -s /usr/local/bin/daemons/supervise/passwdmon/ /service/passwdmon
Now, your daemon should be running! To stop and start it, run:
# svc -d /services/passwdmon
# svc -u /services/passwdmon
You should now see your process in the process list, along with supervise, which is keeping it running.
# ps -ax|grep passwdmon
599 ?? S 0:00.03 /usr/bin/php /usr/local/bin/passwdmon.php
610 ?? S 7:02.39 supervise passwdmon
Adding Multilog Logging
Now your script is outputting text and you want to be able to see the logs for you process. You simply need to create a 'run' script to enable Multilog to capture that and manage a log file. Place the following in
/usr/local/bin/daemons/supervise/passwdmon/log/run:
#!/bin/sh
exec /usr/local/bin/setuidgid root /usr/local/bin/multilog t /var/log/passwdmon
Your logs will be kept in /var/log/passwdmon.
That's it! Now your script can't be killed until you do a 'svc -d /services/passwdmon' to stop it. If it dies on its own, it will restart automatically. Also, it will automatically startup when your machine starts up.
# ps -ax|grep passwdmon
13547 ?? S 0:00.03 /usr/bin/php /usr/local/bin/passwdmon.php
13561 p5 R+ 0:00.00 grep passwdmon
101 ?? R 5018:26.07 supervise passwdmon
104 ?? S 0:00.02 /usr/local/bin/multilog s1000000 n100 t /var/log/passwdmon
# kill -9 13547
# ps -ax|grep passwdmon
13567 ?? S 0:00.03 /usr/bin/php /usr/local/bin/passwdmon.php
13576 p5 R+ 0:00.00 grep passwdmon
101 ?? R 5018:33.80 supervise passwdmon
104 ?? S 0:00.02 /usr/local/bin/multilog s1000000 n100 t /var/log/passwdmon
#
01/27/2008 11:52pm
This article hasn't been commented yet.
Write a comment
* = required field