Quick tutorial on how to create a FreeBSD system startup script
The init system of FreeBSD is quite different to the Linux. There is no concept of symbolic link of the init script to each run level and no run level. All you have is one big long list of init scripts and very simple way to administer these scripts. If you want some further readings, check out the original paper on rc.d system.
Here is a short tutorial, hopefully someone will find it useful. If you need to know more in depth, check out the FreeBSD document
Step 1. rc.d script template.
Here is a template example of an init script. It’s very short. All you need is to put your startup operations inside the if checkyesno … statement.
#!/bin/sh # PROVIDE: myscript . /etc/rc.subr name="myscript" rcvar=`set_rcvar` start_cmd="myscript_start" stop_cmd=":" load_rc_config $name myscript_start() { if checkyesno ${rcvar}; then ........ fi } run_rc_command "$1"
Like all Unix system startup scripts, they all heavily shared a single file with common subroutines. In FreeBSD, this is governed by rc.subr.
Step 2. Mandatory keyword, ‘# PROVIDE:’
First of all, you must declare a unique name (inside the comment) for your startup script. So that other startup scripts execution sequence can be arranged with ‘# AFTER:’ and ‘# BEFORE:’ on other scripts name.
Step 3. Enable the startup script
Edit /etc/rc.conf and add the line:
myscript_enable="YES"
Things to check before reboot
There are several things that you can check before rebooting the machine to the script.
rc_debug
Turn on the debug on. Add the following line into /etc/rc.conf
rc_debug="YES"
rcvar
You can run the script with the parameter, ‘rcvar’, which will evaluate whether the script will be started in the reboot.
rcorder
Finally, you can use rcorder to show the script is executed in the right dependency. Since there is no BEFORE: or AFTER: keywords declared in this example, therefore the script is ordered in low priority. See the man page
rcorder /etc/rc.d/*
Here is a screenshot of part of the result.
There are stubs rc scripts with uppercase filename, such as FILESYSTEMS, NETWORKING for other scripts to run before or after certain stage.
rc.subr explained
If you don’t want to know what exactly rc.d code does, then ignore this section.
rcvar=`set_rcvar`
This tells the rc.d system that the variable name of {$name}_enable, “myscript_enable”, is used as the main configuration variable to indicate whether the service is on/off. See man page of rc.subr.
load_rc_config $name
This loads the /etc/rc.conf file. Additionally, it looks for the ‘myscript’ specific configuration file in /etc/rc.conf.d/ if you need more advance control over the script. So at this stage, $myscript_enable=”YES” (in Step 3) is loaded into memory.
run_rc_command $1
This command contains several steps.
- When the system startup, the rc.d system will run the script as ‘/etc/rc.d/myscript start’.
- Then ‘run_rc_command start’ command is resolved with the ‘start’ argument as ${1}_cmd which becomes the string “start_cmd”, then further evaluating the variable name (using eval \$${start_cmd}) gives “myscript_start” (declared in Step 1, line 9).
- The function myscript_start is then executed.
checkyesno ${rcvar}
This evaluates the value of “myscript_enable” (declared in /etc/rc.conf) variable and check whether it is defined “YES”. If so, returns 1. Hence runs the startup operations.
At the time of writing this blog, I am using FreeBSD 8.0.
I work for iTrinegy. Here are my other blogs on FreeBSD
Trackbacks & Pingbacks
- How to install mariadb on FreeBSD | Learning On Demand
- Running a UNIX script on startup, and Cron jobs | I'm a Human Inbox Programming Journal
Thanks for this guide. I need to make a unicorn startup script before nginx, I think here there’s everything I need.
Excellent post, Joe! Thank you for the in-depth explanation.
Thank you, this really helped my to better understand FreeBSD startup scripts!