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

From ArchWiki
Jump to: navigation, search
m
(23 intermediate revisions by 8 users not shown)
Line 1: Line 1:
[[Category:Boot process (English)]]
+
[[Category:Boot process]]
[[Category:HOWTOs (English)]]
+
[[Category:Package development]]
 
+
[[cs:Writing rc.d scripts]]
 +
[[es:Writing rc.d scripts]]
 +
[[zh-CN:Writing rc.d scripts]]
 
{{Article summary start}}
 
{{Article summary start}}
{{Article summary text|How to write rc.d (daemon) scripts.}}
+
{{Article summary text|Writing rc.d daemon scripts.}}
 
{{Article summary heading|Related}}
 
{{Article summary heading|Related}}
 +
{{Article summary wiki|Arch Boot Process}}
 
{{Article summary wiki|Daemon}}
 
{{Article summary wiki|Daemon}}
 
{{Article summary wiki|rc.conf}}
 
{{Article summary wiki|rc.conf}}
{{Article summary wiki|Arch_Boot_Process|Arch Boot Process}}
 
 
{{Article summary end}}
 
{{Article summary end}}
  
==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}}.
The {{Package Official|abs}} package contains a basic prototype located at {{Filename|/usr/share/pacman/rc-script.proto}}
+
  
<pre>
+
== Example ==
#!/bin/bash
+
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>}}
  
daemon_name=DAEMON_NAME
+
The actual script:
 +
{{hc|/etc/rc.d/crond|2=<nowiki>
 +
#!/bin/bash
  
 
. /etc/rc.conf
 
. /etc/rc.conf
 
. /etc/rc.d/functions
 
. /etc/rc.d/functions
. /etc/conf.d/$daemon_name.conf
 
  
get_pid() {
+
DAEMON=crond
pidof -o %PPID $daemon_name
+
ARGS=
}
+
  
case "$1" in
+
[ -r /etc/conf.d/$DAEMON ] && . /etc/conf.d/$DAEMON
  start)
+
    stat_busy "Starting $daemon_name daemon"
+
  
    PID=$(get_pid)
+
PID=$(get_pid $DAEMON)
    if [ -z "$PID" ]; then
+
      [ -f /var/run/$daemon_name.pid ] && rm -f /var/run/$daemon_name.pid
+
      # RUN
+
      $daemon_name
+
      #
+
      if [ $? -gt 0 ]; then
+
        stat_fail
+
        exit 1
+
      else
+
        echo $(get_pid) > /var/run/$daemon_name.pid
+
        add_daemon $daemon_name
+
        stat_done
+
      fi
+
    else
+
      stat_fail
+
      exit 1
+
    fi
+
    ;;
+
  
  stop)
 
    stat_busy "Stopping $daemon_name daemon"
 
    PID=$(get_pid)
 
    # KILL
 
    [ ! -z "$PID" ] && kill $PID &> /dev/null
 
    #
 
    if [ $? -gt 0 ]; then
 
      stat_fail
 
      exit 1
 
    else
 
      rm -f /var/run/$daemon_name.pid &> /dev/null
 
      rm_daemon $daemon_name
 
      stat_done
 
    fi
 
    ;;
 
 
  restart)
 
    $0 stop
 
    sleep 3
 
    $0 start
 
    ;;
 
 
  status)
 
    stat_busy "Checking $daemon_name status";
 
    ck_status $daemon_name
 
    ;;
 
 
  *)
 
    echo "usage: $0 {start|stop|restart|status}"
 
esac
 
 
exit 0
 
</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=
 
[ -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
    stat_fail
+
     add_daemon $DAEMON
  else
+
     add_daemon in.tftpd
+
 
     stat_done
 
     stat_done
 +
  else
 +
    stat_fail
 +
    exit 1
 
   fi
 
   fi
 
   ;;
 
   ;;
 
  stop)
 
  stop)
   stat_busy "Stopping TFTPD"
+
   stat_busy "Stopping $DAEMON"
   [ ! -z "$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 137: Line 82:
 
   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 script
 
**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
 
*Create /var/run/DAEMON_NAME.pid
 
*Include at least start,stop and restart.
 

Revision as of 06:00, 26 October 2012

Template:Article summary start Template:Article summary text Template:Article summary heading Template:Article summary wiki Template:Article summary wiki Template:Article summary wiki Template:Article summary end

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