Wednesday, January 16, 2008

Daemonizing a non-daemon application without nohup

Sometimes *nix man need to daemonize a non-daemon application and make a full init.d start/restart script. And we will.
First of all, nohup will not be used for these purposes, ‘cause it creates a process with a PID we can’t get to know without some extra efforts.
The idea is in a special init.d script.
  1. We start init.d script (#/etc/init.d/myscipt start).
  2. Init script executes itself in a background mode with a special parameter "start_internal" . The new created process have a new PID.
  3. The process executes the application to be daemonized using exec. Exec replaces the shell and no new process is created, so we do know the PID of our application and have no problems to kill the daemonized application.
Here is a simple implementation:

#!/bin/sh

. /etc/rc.d/init.d/functions

# Location of a non-daemon application to be daemonized
BIN="/usr/local/bin/hello_world"
# The username to run the process with
RELUSER="aolehnovich"
# Our PID file
PIDFILE="/var/run/hello_world.pid"
# Log file location
LOGFILE="/var/log/hello_world.log"

start()
{
rm -f $LOGFILE
# Execute ourself in a background mode
su -l $RELUSER -p -c "${0} start_internal &"
echo -n "Starting Application: "
success "Starting Application: "
echo
}

start_internal()
{
# Remember PID
echo "$$" > $PIDFILE
# Exec the non-daemon application
exec "$BIN" > $LOGFILE
}

stop()
{
if [ -f ${PIDFILE} ]; then
kill `cat $PIDFILE`
rm -f $PIDFILE
echo -n "Stopping Application: "
success "Stopping Application: "
echo
fi
}

case "$1" in
start)
start
;;
start_internal)
start_internal
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage $0 {start|stop|restart}"
exit 1
esac
exit 0


Thanks to Viktor Kovalevich. This article uses his knowledge, too ;)

No comments: