Difference between revisions of "Initscripts/Writing rc.d scripts"

From ArchWiki
Jump to: navigation, search
(Tips: most daemons create their own pid file: exception, not the rule; grammar; random bullet nesting)
(22 intermediate revisions by 9 users not shown)
Line 1: Line 1:
[[Category:Boot process (English)]]
+
[[Category:Boot process]]
[[Category:HOWTOs (English)]]
+
[[Category:Package development]]
{{Article summary start}}
+
[[cs:Writing rc.d scripts]]
{{Article summary text|How to write rc.d (daemon) scripts.}}
+
[[es:Writing rc.d scripts]]
{{Article summary heading|Related}}
+
[[zh-CN:Writing rc.d scripts]]
{{Article summary wiki|Daemon}}
+
{{Related articles start}}
{{Article summary wiki|rc.conf}}
+
{{Related|Arch Boot Process}}
{{Article summary wiki|Arch_Boot_Process|Arch Boot Process}}
+
{{Related|Daemon}}
{{Article summary end}}
+
{{Related|rc.conf}}
 +
{{Related articles end}}
 +
{{Warning|Arch only supports [[systemd]]. Arch's old initscripts package is obsolete and is no longer supported. All Arch users need to move to systemd.}}
  
==Introduction==
+
[[Initscripts]] uses rc.d scripts to used to control the starting, stopping and restarting of [[Daemon|daemons]].
As part of Arch's 'BSD-style' init, rc.d scripts are used to control the starting,stopping and restarting of [[Daemon|daemons]]. This guide will help to create your own rc.d scripts.
 
  
==Basic scheme==
+
== Guideline ==
Most rc.d scripts follow the same structure but the details are typically specific to the daemon.
+
* Source {{ic|/etc/rc.conf}}, {{ic|/etc/rc.d/functions}}, and optionally {{ic|/etc/conf.d/DAEMON_NAME}}.
 +
* Arguments and other daemon options should be placed in {{ic|/etc/conf.d/DAEMON_NAME}}. This is done to separate configuration from logic and to keep a consistent style among daemon scripts.
 +
* Use functions in {{ic|/etc/rc.d/functions}} instead of duplicating their functionality.
 +
* Include at least start, stop and restart as arguments to the script.
  
===Daemon arguments===
+
== Available functions ==
Arguments to your daemon should be placed in {{Filename|/etc/conf.d/DAEMON_NAME}}
+
* There are some functions provided by {{ic|/etc/rc.d/functions}}:
 +
** {{Ic|stat_busy "''message''"}}: set status ''busy'' for printed message (e.g. <nowiki>Starting daemon  [BUSY]</nowiki>)
 +
** {{Ic|stat_done}}: set status ''done'' (e.g. <nowiki>Starting daemon  [DONE]</nowiki>)
 +
** {{Ic|stat_fail}}: set status ''failed'' (e.g. <nowiki>Starting daemon  [FAILED]</nowiki>)
 +
** {{Ic|get_pid ''program''}}: get PID of the program
 +
** {{Ic|ck_pidfile ''PID-file'' ''program''}}: check whether PID-file is still valid for the program (e.g. <nowiki>ck_pidfile /var/run/daemon.pid daemon || rm -f /var/run/daemon.pid</nowiki>)
 +
** {{Ic|<nowiki>[add|rm]_daemon</nowiki> ''program''}}: add/remove program to running daemons (stored in {{ic|/run/daemons/}})
  
===Prototype===
+
Full list of functions is much longer and most possibilities (like way to control whether or not non-root users can launch daemon) are still undocumented and can be learned only from {{ic|/etc/rc.d/functions}} source. See also {{Ic|man rc.d}}.
<pre>
+
 
 +
== Example ==
 +
The following is an example for ''crond''. Look in {{ic|/etc/rc.d}} for greater variety.
 +
 
 +
The configuration file:
 +
{{hc|/etc/conf.d/crond|2=<nowiki>ARGS="-S -l info"</nowiki>}}
 +
 
 +
The actual script:
 +
{{hc|/etc/rc.d/crond|2=<nowiki>
 
#!/bin/bash
 
#!/bin/bash
  
Line 25: Line 43:
 
. /etc/rc.d/functions
 
. /etc/rc.d/functions
  
[ -r /etc/conf.d/$DAEMON.conf ] && . /etc/conf.d/$DAEMON.conf
+
DAEMON=crond
 
+
ARGS=
DAEMON=DAEMON_NAME
 
PID=$(pidof -o %PPID $DAEMON)
 
  
case "$1" in
+
[ -r /etc/conf.d/$DAEMON ] && . /etc/conf.d/$DAEMON
  start)
 
    stat_busy "Starting $DAEMON daemon"
 
    [ -z "$PID" ] && $DAEMON &>/dev/null
 
    if [ $? = 0 ]; then
 
      add_daemon $DAEMON
 
      stat_done
 
    else
 
      stat_fail
 
      exit 1
 
    fi
 
    ;;
 
  stop)
 
    stat_busy "Stopping $DAEMON daemon"
 
    [ -n "$PID" ] && kill $PID &>/dev/null
 
    if [ $? = 0 ]; then
 
      rm_daemon $DAEMON
 
      stat_done
 
    else
 
      stat_fail
 
      exit 1
 
    fi
 
    ;;
 
  restart)
 
    $0 stop
 
    sleep 1
 
    $0 start
 
    ;;
 
  status)
 
    stat_busy "Checking $DAEMON status"
 
    ck_status $DAEMON
 
    ;;
 
  *)
 
    echo "usage: $0 {start|stop|restart|status}"
 
esac
 
</pre>
 
 
 
==Example==
 
{{Tip|{{Filename|/etc/rc.d/}} and {{Filename|/etc/conf.d/}} contain many examples}}
 
 
 
A proper example for tftpd:
 
 
 
{{File|name=/etc/conf.d/tftpd|content=<nowiki>TFTPD_ARGS="-l -s /var/tftpboot -c"</nowiki>}}
 
 
 
{{File|name=/etc/rc.d/tftpd|content=<nowiki>
 
#!/bin/bash
 
. /etc/rc.conf
 
. /etc/rc.d/functions
 
  
TFTPD_ARGS=
+
PID=$(get_pid $DAEMON)
[ -f /etc/conf.d/tftpd ] && . /etc/conf.d/tftpd
 
PID=`pidof -o %PPID /usr/sbin/in.tftpd`
 
  
 
case "$1" in
 
case "$1" in
 
  start)
 
  start)
   stat_busy "Starting TFTPD"
+
   stat_busy "Starting $DAEMON"
   [ -z "$PID" ] && /usr/sbin/in.tftpd ${TFTPD_ARGS}
+
   [ -z "$PID" ] && $DAEMON $ARGS &>/dev/null
   if [ $? -gt 0 ]; then
+
   if [ $? = 0 ]; then
 +
    add_daemon $DAEMON
 +
    stat_done
 +
  else
 
     stat_fail
 
     stat_fail
  else
+
     exit 1
     add_daemon in.tftpd
 
    stat_done
 
 
   fi
 
   fi
 
   ;;
 
   ;;
 
  stop)
 
  stop)
   stat_busy "Stopping TFTPD"
+
   stat_busy "Stopping $DAEMON"
   [ -n "$PID" ] && kill $PID &> /dev/null
+
   [ -n "$PID" ] && kill $PID &>/dev/null
   if [ $? -gt 0 ]; then
+
   if [ $? = 0 ]; then
 +
    rm_daemon $DAEMON
 +
    stat_done
 +
  else
 
     stat_fail
 
     stat_fail
  else
+
     exit 1
     rm_daemon in.tftpd
 
    stat_done
 
 
   fi
 
   fi
 
   ;;
 
   ;;
 
  restart)
 
  restart)
 
   $0 stop
 
   $0 stop
 +
  sleep 1
 
   $0 start
 
   $0 start
 
   ;;
 
   ;;
Line 111: Line 81:
 
   echo "usage: $0 {start|stop|restart}"   
 
   echo "usage: $0 {start|stop|restart}"   
 
esac
 
esac
exit 0
 
 
</nowiki>}}
 
</nowiki>}}
 
==Tips==
 
*Follow the same structure as other rc.d scripts
 
*Source {{Filename|/etc/rc.conf}}, {{Filename|/etc/rc.d/functions}}, and optionally {{Filename|/etc/conf.d/DAEMON_NAME}}
 
*Use functions in /etc/rc.d/functions
 
*Include at least start, stop and restart
 

Revision as of 13:35, 31 December 2013

zh-CN:Writing rc.d scripts

Warning: Arch only supports systemd. Arch's old initscripts package is obsolete and is no longer supported. All Arch users need to move to systemd.

Initscripts uses rc.d scripts to used to control the starting, stopping and restarting of daemons.

Guideline

  • Source /etc/rc.conf, /etc/rc.d/functions, and optionally /etc/conf.d/DAEMON_NAME.
  • Arguments and other daemon options should be placed in /etc/conf.d/DAEMON_NAME. This is done to separate configuration from logic and to keep a consistent style among daemon scripts.
  • Use functions in /etc/rc.d/functions instead of duplicating their functionality.
  • Include at least start, stop and restart as arguments to the script.

Available functions

  • There are some functions provided by /etc/rc.d/functions:
    • stat_busy "message": set status busy for printed message (e.g. Starting daemon [BUSY])
    • stat_done: set status done (e.g. Starting daemon [DONE])
    • stat_fail: set status failed (e.g. Starting daemon [FAILED])
    • get_pid program: get PID of the program
    • ck_pidfile PID-file program: check whether PID-file is still valid for the program (e.g. ck_pidfile /var/run/daemon.pid daemon || rm -f /var/run/daemon.pid)
    • [add|rm]_daemon program: add/remove program to running daemons (stored in /run/daemons/)

Full list of functions is much longer and most possibilities (like way to control whether or not non-root users can launch daemon) are still undocumented and can be learned only from /etc/rc.d/functions source. See also man rc.d.

Example

The following is an example for crond. Look in /etc/rc.d for greater variety.

The configuration file:

/etc/conf.d/crond
ARGS="-S -l info"

The actual script:

/etc/rc.d/crond
#!/bin/bash

. /etc/rc.conf
. /etc/rc.d/functions

DAEMON=crond
ARGS=

[ -r /etc/conf.d/$DAEMON ] && . /etc/conf.d/$DAEMON

PID=$(get_pid $DAEMON)

case "$1" in
 start)
   stat_busy "Starting $DAEMON"
   [ -z "$PID" ] && $DAEMON $ARGS &>/dev/null
   if [ $? = 0 ]; then
     add_daemon $DAEMON
     stat_done
   else
     stat_fail
     exit 1
   fi
   ;;
 stop)
   stat_busy "Stopping $DAEMON"
   [ -n "$PID" ] && kill $PID &>/dev/null
   if [ $? = 0 ]; then
     rm_daemon $DAEMON
     stat_done
   else
     stat_fail
     exit 1
   fi
   ;;
 restart)
   $0 stop
   sleep 1
   $0 start
   ;;
 *)
   echo "usage: $0 {start|stop|restart}"  
esac