home   articles   archive   forum   masthead  
Published at 6.06.05
Author: Lars-Anders Schmuhl
Translator: Sebastian Kueppers
Languages: de
Printer printer-version
Support Us!
  Warning: This article needs a proof reader.

Daemon

What is a "daemon"? - How do I adjure a "daemon"? - How do I get rid of one? - These questions will be answered here, not mystically but with help from an easy wrapper-script.

What is a Daemon?

As for the UNIX-world a daemon is - opposite to the real world - a helpful, nearly invisible ghost providing useful services to the user.
"Invisible" means, that they are processes which need no interaction with the user and therefore need no graphical user interface. Once started they wait for specific events to come into force. This might be a database server waiting for connections requesting some data for example.

UNIX-systems have many daemons providing lots of useful services without being noticed by the user. Most likely those are important system functions that have to have root-rights.
Take the secure shell daemon (sshd) to handle ssh connections or the at-daemon which starts tasks on schedule. Those "traditional" UNIX services are started and stopped when changing runlevels (e.g. when booting or shutting down) using the init-scripts usually. But there are occasions where such behaviour is not wanted. On the one hand not every user has root-rights and the knowledge needed to modify init scripts. On the other hand there are services which are not included in common linux distributions (rightly). Two practical examples which do not need root-privileges shall be given here:

  • File-sharing systems
  • Dedicated game server
But before that the daemon "skeleton" (the "wrapper-script" concealing the daemon itself) which can be customized easily shall be introduced.

The skeleton

This is the source of the skeleton:

skeleton.sh
       1	#!/bin/sh
       2	#-------------------------------------------------------- 
       3	#
       4	# generic daemon wrapper script
       5	#
       6	# OPTIONS: (start|stop|restart|status)
       7	#
       8	#-------------------------------------------------------- 
       9	
      10	# --- edit here ---
      11	
      12	DAEMON_DESC="my fancy daemon"
      13	DAEMON_BIN="/path/to/my_daemon"
      14	DAEMON_PROC="daemon_ps_name"
      15	DAEMON_LOGFILE="/path/to/my/logfile/${DAEMON_PROC}.log"
      16	DAEMON_OPTIONS=" -foo -bar "
      17	
      18	# --- don't edit below ---
      19	
      20	#-------------------------------------------------------- 
      21	#
      22	# get_pid()
      23	#
      24	#-------------------------------------------------------- 
      25	
      26	get_pid()
      27	{
      28		PID=`ps aux | grep -v grep | grep ${DAEMON_PROC} | awk '{print $2}'`
      29	}
      30	
      31	#-------------------------------------------------------- 
      32	#
      33	# start_daemon()
      34	#
      35	#-------------------------------------------------------- 
      36	
      37	start_daemon()
      38	{
      39		echo -n "Starting ${DAEMON_DESC}"
      40		${DAEMON_BIN} ${DAEMON_OPTIONS} 2> ${DAEMON_LOGFILE}&
      41		echo " ... done." 
      42	}
      43	
      44	#-------------------------------------------------------- 
      45	#
      46	# stop_daemon()
      47	#
      48	#-------------------------------------------------------- 
      49	
      50	stop_daemon()
      51	{
      52		echo -n "Stopping ${DAEMON_DESC}" 
      53		kill -s SIGKILL $PID
      54		echo " ... done." 
      55	}
      56	
      57	#-------------------------------------------------------- 
      58	#
      59	# main
      60	#
      61	#-------------------------------------------------------- 
      62	
      63	case "$1" in 
      64		start) 
      65			get_pid
      66			if [ -z "$PID" ] ; then
      67				start_daemon
      68			else
      69				echo "${DAEMON_DESC} is running."
      70				exit 1
      71			fi
      72			;; 
      73	
      74		stop) 
      75			get_pid
      76			if [ -z "$PID" ] ; then
      77				echo "${DAEMON_DESC} is not running."
      78				exit 1
      79			else
      80				stop_daemon
      81			fi
      82			;;
      83	
      84		restart)
      85			get_pid
      86			if [ ! -z "$PID" ] ; then
      87				stop_daemon
      88			fi
      89			start_daemon
      90			;; 
      91	
      92		status) 
      93			get_pid
      94			if [ -z "$PID" ] ; then
      95				echo "${DAEMON_DESC} is not running."
      96			else
      97				echo "${DAEMON_DESC} is running. PID is $PID"
      98			fi
      99			;; 
     100	
     101		*) 
     102			echo "Usage: $0 {start|stop|status|restart}" 
     103			exit 1 
     104			;; 
     105	esac 
     106	
     107	exit 0 
     108	
     109	# --- EOF ---
  


Explanation:

lines 10-18: are for customizing the daemom
lines 26-29: this function gets the process ID of the running daemon
lines 37-42: function for starting the daemon
lines 50-55: function for stopping the daemon
lines 63-107: main function, evaluate parameters

This script accepts one of those four parametres:

start: starts the daemon
stop: stops the the daemon if running
status: informs about if the daemon is running
restart: stops the daemon (if running) and starts it again

The advantage using a generic script is that using them is rather similar and easy because you don't have to remember and recall every single special detail.

Examples

By editing lines 10-18 of the skeleton script you can create your own daemon easily.

File-sharing (overnet)

First example: User "horst-kevin" wants to take part in file-sharing using the overnet-core (the edonkey-core can be used as well). To do so he created a directory ed2k in his home directory where the executable can be found and the logfile shall be written to. Changes to be made in the skeleton are simply these:

Changes for overnet core
  DAEMON_DESC="overnet core 0.51.2"
  DAEMON_BIN="/home/horst-kevin/ed2k/overnet0.51.2"
  DAEMON_PROC="overnet0.51.2"
  DAEMON_LOGFILE="/home/horst-kevin/ed2k/${DAEMON_PROC}.log"
  DAEMON_OPTIONS=" - ! -g -l "
  


If no logfile shall be written choose /dev/null. You don't need root rights here. For starting enter

  >> ./overnetd.sh start
  
The overnet core has the (rather wide spread) site effect to fork threads that show up with the same name in the process lsit. But no problem, enter
  >> ./overnetd.sh stop
  
and all of them get killed (and the mystery is over).

Dedicated game server (Unreal Tournament)

Second example: User "horst-kevin" likes to play UT with other people. Now he wants to use his old spare computer whose equipment is quite old but still good enough for an UT dedicated game server for exactly that. He commits the following changes to the skeleton:

Changes for UT dedicated server
  DAEMON_DESC="UT dedicated server version 436"
  DAEMON_BIN="/usr/local/games/ut/ucc"
  DAEMON_PROC="ucc-bin"
  DAEMON_LOGFILE="/home/horst-kevin/${DAEMON_PROC}.log"
  DAEMON_OPTIONS=" server \"DM-Turbine?game=Botpack.DeathMatchPlus\" -port=7777 ini=ucc.ini log=ucc.log"
  


The server can be started and stopped easily using the console or remote via telnet or ssh as described above.

Conclusion

UNIX-daemons should have lost their fearful image. The reader should now be able to create and control own daemons. Creating a Quake 3 dedicated server for exaple is as easy as seen in the UT-example above


Links:



Talkback Area




Enter Own Comment