Daemonize any program with daemontools and ucspi-tcp

Daemontools and ucspi-tcp are VERY commonly used with qmail, one of the most popular email MTA programs on the net today. Once you get the hang of it, you’ll see it’s very cool for daemonizing a script. This example will be a PHP script that does very little, just echo’s what you type back at you. Just enough to get the point across that you can deamonize your script with these two tools.

Below is blow by blow instructions for installation and setup of the echo.php daemon

unalias rm

# Get errno patches for daemontools and ucspi-tcp from netqmail:
cd /usr/local/src
wget http://www.qmail.org/netqmail-1.05.tar.gz
tar -xzvf netqmail-1.05.tar.gz

# Get and install ucspi-tcp
cd /usr/local/src
wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
tar -xzf ucspi-tcp-0.88.tar.gz
cd ucspi-tcp-0.88
patch -p1 < /usr/local/src/netqmail-1.05/other-patches/ucspi-tcp-0.88.errno.patch
make
make setup check

# get and install daemontools
mkdir /package
chmod 1755 /package
cd /package
wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
gunzip daemontools-0.76.tar
tar -xpf daemontools-0.76.tar
rm daemontools-0.76.tar
cd admin/daemontools-0.76
patch -p1 < /usr/local/src/netqmail-1.05/other-patches/daemontools-0.76.errno.patch
package/install

# make dir
cd /usr/local
mkdir echo

# create echo program (dummy, just an example)
cd /usr/local/echo
echo ‘#!/usr/bin/php -q’ > echo.php
chmod 755 echo.php
echo “<?php
\$fp = fopen(‘php://stdin’, ‘r’);
\$stderr = fopen(‘php://stderr’, ‘w’);
echo \”Welcome to echo. Say something.\\n\”;
while ( \$line = fgets(\$fp, 1024) )
{
echo \$line;
fputs(\$stderr, \$line);
}
fclose(\$fp);
fclose(\$stderr);
?>” >> echo.php
# note, writing to stderr puts the line in the log file.

# create supervise run file (max 100 MB of mem, set by softlimit)
cd /usr/local/echo
mkdir supervise
cd supervise/
echo ‘#!/bin/sh’ > run
echo “
PORT=1234
MAXCONNECT=10
LOCAL=\`hostname\`
UUID=\`id -u nobody\`
UGID=\`id -g nobody\`
exec /usr/local/bin/softlimit -m 104857600 \\
/usr/local/bin/tcpserver -v -H -R -l \”\$LOCAL\” -x /etc/tcp.echo.cdb -c \”\$MAXCONNECT\” \\
-u \”\$UUID\” -g \”\$UGID\” 0 \$PORT /usr/local/echo/echo.php 2>&1
” >> run
chmod 755 run

# create supervise log run file
cd /usr/local/echo/supervise
mkdir log
cd log
echo ‘#!/bin/sh’ > run
echo “exec /usr/local/bin/setuidgid nobody /usr/local/bin/multilog t n5 s1048576 /var/log/echo
” >> run
chmod 755 run

# create log dir
mkdir /var/log/echo
chown nobody:nobody /var/log/echo

# create the /etc/tcp.echo.cdb file:
# change the second line to s/allow/deny/, if you want to deny the world and only allow
# from your loopback address. Else add more specific rules to /etc/tcp.echo
echo “127.0.0.1:allow
:allow” > /etc/tcp.echo
tcprules /etc/tcp.echo.cdb /etc/tcp.echo.tmp < /etc/tcp.echo
chmod 644 /etc/tcp.echo.cdb

# link it up:
cd /service
ln -s /usr/local/echo/supervise echo

# check status:
svstat /service/echo
#take down:
svc -d /service/echo
sleep 5
# check status:
svstat /service/echo
#bring up:
svc -u /service/echo
# check log:
tail /var/log/echo/current

telnet localhost 1234

# type away, when you’re done CTRL+], the q to quit.

# check the log again:
tail /var/log/echo/current

#And, if you want to see real timestamps in your log file, use tai64nlocal:

cat /var/log/echo/current | tai64nlocal

End of example. What do you think? Did you get it to work on your server?

Dave.

Comments are closed.