Use an rc.d script to determine if a service is running and start, restart or stop it as required

Author: hubertf contact BSD flavour

Reviewer: name contact BSD flavour

Reviewer: name contact BSD flavour


Concept

In addition to directly sending signals to processes, realize that BSD systems provide scripts which can be used to check the status of services and to stop, start and restart them as required. Be aware of the locations of these scripts on each of the BSD systems. Note: this objective does not apply to OpenBSD.

Introduction

In NetBSD, FreeBSD, and DragonFly, the traditional system startup script /etc/rc has been split into tiny scripts that start and stop individual services (similar to what SysVR4 systems have done for some time). Each script runs at system boot, and determines via variables set in the file /etc/rc.conf whether its service should be started or not. This is covered in section Configure a service to start at boot time. A similar operation is performed at system shutdown to turn off running services.

Note: OpenBSD does not use this rc.d script system. On OpenBSD, checking services and starting, stopping, and restarting services is done manually (except at boot time or shutdown). (FOOTNOTE: See section Configure a service to start at boot time for information and examples for configuring services on OpenBSD to start at boot time.)

The advantage this approach has to the system administrator that he doesn't need to know any details about how to start or stop a system - running the corresponding rc.d script with an argument of either 'start' or 'stop' is sufficient. As an extension over the System V behaviour, an argument of 'status' displays the service's status, and 'restart' stops and then starts the service again.

A list of scripts (and thus services) that can be run can be found in the /etc/rc.d directory (hence the scripts are often called "rc.d scripts").

Examples

Here is a list of rc.d scripts from a NetBSD 4.0 system:

""netbsd% ls /etc/rc.d ""DAEMON downinterfaces lpd postfix sshd ""LOGIN fixsb mixerctl powerd staticroute ""NETWORKING fsck mopd ppp swap1 ""SERVERS ftpd motd pwcheck swap2 ""accounting hostapd mountall quota sysctl ""altqd identd mountcritlocal racoon sysdb ""amd ifwatchd mountcritremote raidframe syslogd ""apache inetd mountd raidframeparity timed ""apmd ipfilter moused rarpd tpctl ""bootconf.sh ipfs mrouted rbootd ttys ""bootparams ipmon named root veriexec ""btconfig ipnat ndbootd route6d virecover ""btcontrol ipsec network routed wdogctl ""bthcid irdaattach newsyslog rpcbind wscons ""ccd iscsi_target nfsd rtadvd wsmoused ""cgd isdnd nfslocking rtclocaltime xdm ""cleartmp kdc ntpd rtsold xfs ""cron ldconfig ntpdate rwho ypbind ""dhclient lkm1 pf savecore yppasswdd ""dhcpd lkm2 pf_boot screenblank ypserv ""dhcrelay lkm3 pflogd sdpd ""dmesg local poffd securelevel

TODO: I think these lists are too long for this book. Maybe just highlight some similar ones and mentin a few unique ones.

Here is the same listing on FreeBSD 6.2:

""freebsd% ls /etc/rc.d DAEMON devfs kadmind nfsd rpcbind LOGIN dhclient kerberos nfslocking rtadvd NETWORKING dmesg keyserv nfsserver rwho SERVERS dumpon kldxref nisdomain savecore abi early.sh kpasswdd nsswitch sdpd accounting encswap ldconfig ntpd securelevel addswap fsck local ntpdate sendmail adjkerntz ftpd localpkg othermta serial amd gbde lpd pccard sppp apm geli mdconfig pcvt sshd apmd geli2 mdconfig2 pf swap1 archdep hcsecd mixer pflog syscons atm1 hostapd motd pfsync sysctl atm2 hostname mountcritlocal power_profile syslogd atm3 ike mountcritremote powerd timed auditd inetd mountd ppp tmp auto_linklocal initrandom mountlate pppoed ugidfw bgfsck ip6addrctl moused pwcheck usbd bluetooth ip6fw mroute6d quota var bootparams ipfilter mrouted ramdisk virecover bridge ipfs msgs ramdisk-own watchdogd bsnmpd ipfw named random wpa_supplicant bthidd ipmon natd rarpd ypbind ccd ipnat netif resolv yppasswdd cleanvar ipsec netoptions root ypserv cleartmp ipxrouted network_ipv6 route6d ypset cron isdnd newsyslog routed ypupdated devd jail nfsclient routing ypxfrd

To determine the status of a service, run the rc.d script with 'status':

TODO: maybe for examples use services or rc.d scripts that are common to these three BSDs.

""netbsd# sh /etc/rc.d/ipfilter status ""ipf: IP Filter: v4.1.13 (396) ""Kernel: IP Filter: v4.1.13
""Running: yes ""Log Flags: 0 = none set ""Default: pass all, Logging: available ""Active list: 0 ""Feature mask: 0x10e

Note that the 'status' command is not available for all scripts:

""netbsd# sh /etc/rc.d/postfix status ""/etc/rc.d/postfix: unknown directive 'status'. ""Usage: /etc/rc.d/postfix [fast|force|one](start stop restart rcvar reload)

To stop a service, run its rc.d script with the 'stop' argument:

FOOTNOTE (TODO: or mention) The "pgrep" usage in the examples is not needed but just shows an example if running or not. (TODO: maybe remove the pgrep from examples?)

""# pgrep -lf postfix ""166 /usr/libexec/postfix/master ""# sh /etc/rc.d/postfix stop ""postfix/postfix-script: stopping the Postfix mail system ""# pgrep -lf postfix ""#

To start it (again), use the same script with the 'start' argument:

""# sh /etc/rc.d/postfix start ""postfix/postfix-script: starting the Postfix mail system ""# pgrep -lf postfix ""12101 /usr/libexec/postfix/master ""#

Now let's do this again in one command:

""# pgrep -lf postfix ""12101 /usr/libexec/postfix/master ""# sh /etc/rc.d/postfix restart ""postfix/postfix-script: stopping the Postfix mail system ""postfix/postfix-script: starting the Postfix mail system ""# pgrep -lf postfix ""472 /usr/libexec/postfix/master ""#

Practice Exercises

  • Determine if your system has rc.d scripts by looking into /etc/rc.d
  • Determine what scripts your system has
  • Check if the cron daemon runs
  • Assuming the cron daemon does run, stop it using the corresponding rc.d script
  • Restart the cron daemon, and verify with a tool of your choice.

More information

rc(8), rc.conf(5), rc.subr(8)