Desi Programmer @ Work

Daemonzing linux processes

If you use Linux on servers and connect remotely via SSH, many times you'd want run a process which will keep doing its work quietly in the background while you work on something else. Sometimes you'd like to process your job in the background in such a way that even if you close your session or logout, it keeps doing it work until it finishes; for instance a resizing script to create thumbnails of all images on your machine. In some cases you'd also want to control your running process such that it keeps running in background but you may stop or restart it conveniently at any time.

This blog post covers these scenarios and looks at different methods of running processes in background.

On the Linux shell, you can launch any task in background by appending "&" while launching it. The task keeps running in the background while you get back control and issue further shell related commands. However the background running process's standard output will still be shown on your shell. More importantly, if you logout while the task is running in the background, the process will exit as well. In many cases this is not desirable.

To truly run a process in the background, you need a "daemon". In computer science, a daemon is a program which runs in the background and doesn't have direct interaction with the user, neither the user has direct control over it. This means some other programs are required to control its working. Normally daemons are system processes which provide some service. For instance sshd is a daemon which provides ssh access to the users. daemons work by detaching them from standard output stream and working in background.

It is possible to daemonize a normal process. There is a command called "nohup" which tells the system not to forward the HangUp signal in case of disconnection. It also automatically redirects standard stream output to a file. Combined with "&", you can run a program in background which does not exit upon disconnection. For instance:

$ nohup ./analyzelogmessages.py *.log &

However once you launch this process, you cannot stop it except by help of other programs. For instance you can figure out the process ID with ps command and use the kill command. Also, in some cases you'd want your daemon to automatically start in case your server restarts.

To have a convenient control over your daemon, there are some tools and services available in Linux. A program called startstopdaemon is used to start and stop daemon programs. It provides various options such as running daemon as another user, jail root into different directory, change the priority, stopping already running daemon, force kill daemon etc.

$ startstopdaemon --background --start --quiet --exec sms_server -- /etc/sms_server.conf # Starts the SMS Server $ startstopdaemon --stop --quiet --exec sms_server -- /etc/sms_server.conf # Stops the SMS Server

This works well except that the system doesn't know you have a daemon and it won't start it automatically. One can put it in a init.d script. An init.d script, depending upon the linux distribution, usually resides in /etc/init.d/ and is used in much like the same manner as that of services on Windows. Creating script is simple; just create a script file and set its execute bit. On Ubuntu there is a skeleton file which acts as a template for reference.

Here is an example init.d script I wrote:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#! /bin/sh
### BEGIN INIT INFO
# Provides:          streamerd
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Streaming Service
# Description:       This is a streaming server

# Author: Sharjeel Ahmed Qureshi

PATH=/usr/sbin:/usr/bin:/sbin:/bin:/home/sharjeel/streamingserver
DESC="Streaming Server"
NAME=streamerd
DAEMON=/home/sharjeel/streamingserver/$NAME
DAEMON_OPTS="-d /tmp/ -p 8080 -f flv "
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/streamerd
NOHUP=/usr/bin/nohup
USER=sharjeel
GROUP=sharjeel

case "$1" in
 start)
 echo -n "Starting $DESC: "
 start-stop-daemon --start -c $USER -g $GROUP \
 --background --exec $DAEMON -- $DAEMON_OPTS
 echo "$NAME."
 ;;
 stop)
 echo -n "Stopping $DESC: "
 start-stop-daemon --stop -c $USER -g $GROUP \
 --exec $DAEMON -- $DAEMON_OPTS
 echo "$NAME."
 ;;
 restart|force-reload)
 echo -n "Restarting $DESC: "
 start-stop-daemon --stop --quiet --pidfile \
 /var/run/$NAME.pid -c $USER -g $GROUP --exec $DAEMON -- $DAEMON_OPTS
 sleep 1
 start-stop-daemon --start --quiet --pidfile \
 /var/run/$NAME.pid -c $USER -g $GROUP --exec $DAEMON -- $DAEMON_OPTS
 echo "$NAME."
 ;;
 reload)
 echo -n "Reloading $DESC configuration: "
 start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid \
 --chuid iwitness --exec $DAEMON
 echo "$NAME."
 ;;
 *)
 N=/etc/init.d/$NAME
 echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
 exit 1
 ;;
esac

Put your init.d file in your /etc/init.d and make it executable:

# chmod +x

You have to register your script with the system so that it starts it automatically when system boots. Use the update-rc.d script which registers your script with init of the system:

# update-rc.d defaults

The "defaults" parameter installs it with default runlevels of your system.

For more information, see: [][]