FreeBSD-init: Difference between revisions

From wikinotes
Line 56: Line 56:
| <code>/etc/rc.subr</code> || Library of rc-script functions
| <code>/etc/rc.subr</code> || Library of rc-script functions
|}
|}
== Skeleton File ==
<blockquote>
<source lang="bash">
#!/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
</source>
<source lang="bash">
# General Commands
name="myservice"                        # mandatory unique-name for script
rcvar="myservice_enable"                # name of variable in /etc/rc.conf used to enable service
</source>
<source lang="bash">
# 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}
</source>
<source lang="bash">
# Environment Variables
${name}_env="VAR=value VAR2=value" # you can set environment variables for the command this way
</source>
<source lang="bash">
# 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
</source>
<source lang="bash">
# Other Builtin Variables
# Command is not run if files do not exist
required_files="/etc/${name}.conf /usr/share/misc/${name}.rules"
</source>
<source lang="bash">
# 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."
}
</source>
<source lang="bash">
# run Command
run_rc_command "$1"                  # based on above conts, run command using /etc/rc.subr function
</source>
</blockquote><!-- skeleton file -->


== Debugging ==
== Debugging ==

Revision as of 18:38, 22 October 2022

The FreeBSD init system is called rc.

Documentation

official tutorial https://docs.freebsd.org/en/articles/rc-scripting/#rcng-dummy
man rc.subr https://www.freebsd.org/cgi/man.cgi?query=rc.subr
man rc https://www.freebsd.org/cgi/man.cgi?query=rc
man rcorder https://www.freebsd.org/cgi/man.cgi?query=rcorder

Locations

/etc/rc.d/* system rc scripts
/usr/local/etc/rc.d/* user rc scripts
/etc/rc.subr available rc script methods

Notes

freebsd rc usage
freebsd rc syntax
freebsd rc troubleshooting

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

Debugging

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>&1

Daemonize 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"