FreeBSD-init
Documentation
official tutorial https://docs.freebsd.org/en/articles/rc-scripting/#rcng-dummy
Locations
/etc/rc.d/*
system rc scripts /usr/local/etc/rc.d/*
user rc scripts
Managing Services
All daemons are enabled, and primarily configured in the
/etc/rc.conf
. rcvars (variables which can be overridden in rc.conf) are listed in the program's rcscript/usr/local/etc/rc.d
.# /etc/rc.conf: sshd_enable="YES" sshguard_enable="YES" sshguard_whitelist="/etc/sshguard.whitelist"Services can be managed from the commandline very simply:
service sshguard start # start service service sshguard stop # stop service service sshguard restart # restart service
Force Starting Broken InitScripts
Sometimes, you don't have time to troubleshoot why a particular command is not working. You can get around this in two ways:
rc.local method
# /etc/rc.local /usr/local/etc/rc.d/${MY_SERVICE} start # bypass rc.d init and runcrontab method
su crontab -u
# crontab @reboot /usr/local/etc/rc.d/<my_service> start
https://forums.freebsd.org/threads/31249/
Init Scripting
NOTE:
Checkout the following initscripts (in my saltstack repostiory) for simple examples:
- taskwarrior's taskd
- minecraft
https://www.freebsd.org/doc/en/articles/rc-scripting/rcng-dummy.html
Official Documentation /etc/rc.subr
Library of rc-script functions Skeleton File
#!/bin/sh # PROVIDE: myservice # allows other services to require 'myservice' # REQUIRE: DAEMON # before this service starts, DAEMON must be provided # KEYWORD: shutdown # this service must be killed before the system shuts down . /etc/rc.subr # source rc.subr, generic rc-script functions# General Commands name="myservice" # mandatory unique-name for script rcvar="myservice_enable" # name of variable in /etc/rc.conf used to enable service# Read User-Configuration in /etc/rc.conf # Set Variables that can be used in rc.conf load_rc_config $name # load variables from /etc/rc.conf : ${myservice_enable:=NO} # rc.conf variables, and their defaults : ${myservice_config=/etc/myservice.conf} : ${myservice_user=will}# Environment Variables ${name}_env="VAR=value VAR2=value" # you can set environment variables for the command this way# Builtin Variables thave affect CLI command to be run ${name}_user=myuser # user to run command as (using su) pidfile=/var/run/myservice/myservice.pid # pidfile path command=/usr/local/bin/myservice # path to binary command_args="-d -p ${pidfile}" # arguments to use against $command command_interpreter=/usr/local/bin/python2.7 # use different interpreter than /bin/sh# Other Builtin Variables # Command is not run if files do not exist required_files="/etc/${name}.conf /usr/share/misc/${name}.rules"# Start/Stop/Restart/... Functions start_cmd="${name}_start" # override default /etc/rc.subr start function with the function ${name}_start stop_cmd=":" # use default /etc/rc.subr stop_cmd function start_precmd="echo start" # runs before 'start' start_postcmd="echo end" # runs after successful 'start' dummy_start() # define your own functions { echo "Nothing started." }# run Command run_rc_command "$1" # based on above conts, run command using /etc/rc.subr functionDebugging
You can create 'debug mode' for a particular init script by adding the following lines to it's init script (just below the shebang), then rebooting and checking
/tmp/output.txt
.set -xv exec 1>/tmp/output.txt 2>&1Daemonize Non-Daemon Programs
FreeBSD provides the program daemon which manages forking processes along with their pidfile. Simply use this as your command instead. Note that you will need to manage your status/stop manually if running the program this way.
pidfile=/var/run/program_name.pid is_running(){ if [ -f $pidfile ]; then pgrep `cat $pidfile` return $0 fi return 1 } program_status(){ if is_running; then echo "${name} is running" else echo "${name} is not running" fi } program_stop() { if is_running; then echo "stopping ${name}" kill -15 `cat pidfile` else echo "${name} is not running" fi } status_cmd=program_status stop_cmd=program_stop command="/usr/sbin/daemon" command_args="-u $command_user -f -p $pidfile $program_name -x -y -z"