NAME¶
openrc-run
—
a means of hooking shell commands into a
service
SYNOPSIS¶
openrc-run |
[ -D ,
--nodeps ]
[-d ,
--debug ]
[-s ,
--ifstarted ]
[-S ,
--ifstopped ]
[-Z ,
--dry-run ]
[command ... ] |
DESCRIPTION¶
openrc-run
is basically an interpreter for
shell scripts which provides an easy interface to the often complex system
commands and daemons. When a service runs a command it first loads its
multiplexed configuration file, then its master configuration file, then
/etc/rc.conf and finally the script itself.
At this point
openrc-run
then runs the
command given.
Commands are defined as shell functions within the script. Here is a list of
some functions that all scripts have by default:
- describe
- Describes what the service does and each command the service defines.
- start
- First we ensure that any services we depend on are started. If any needed
services fail to start then we exit with a suitable error, otherwise call
the supplied start function if it exists.
- stop
- First we ensure that any services that depend on us are stopped. If any
services that need us fail to stop then we exit with a suitable error,
otherwise call the supplied stop function if it exists.
- restart
- Stops and starts the service, including dependencies. This cannot be
overridden. See the description of the RC_CMD variable below for the
method to make your service behave differently when restart is being
executed.
- status
- Shows the status of the service. The return code matches the status, with
the exception of "started" returning 0 to match standard command
behaviour.
- zap
- Resets the service state to stopped and removes all saved data about the
service.
The following options affect how the service is run:
-d
,
--debug
- Set xtrace on in the shell to assist in debugging.
-D
,
--nodeps
- Ignore all dependency information the service supplies.
-s
,
--ifstarted
- Only run the command if the service has been started.
-S
,
--ifstopped
- Only run the command if the service has been stopped.
-q
,
--quiet
- Turns off all informational output the service generates. Output from any
non OpenRC commands is not affected.
-v
,
--verbose
- Turns on any extra informational output the service generates.
-Z
,
--dry-run
- Shows which services would be stopped and/or started without actually
stopping or starting them.
The following variables affect the service script:
- extra_commands
- Space separated list of extra commands the service defines. These should
not depend on the service being stopped or started.
- extra_started_commands
- Space separated list of extra commands the service defines. These only
work if the service has already been started.
- extra_stopped_commands
- Space separated list of extra commands the service defines. These only
work if the service has already been stopped.
- description
- String describing the service.
- description_$command
- String describing the extra command.
- start_stop_daemon_args
- List of arguments passed to start-stop-daemon when starting the
daemon.
- command
- Daemon to start or stop via
start-stop-daemon
if no start or stop
function is defined by the service.
- command_args
- List of arguments to pass to the daemon when starting.
- command_background
- Set this to "true", "yes" or "1"
(case-insensitive) to force the daemon into the background. This implies
the "--make-pidfile" and "--pidfile" option of
start-stop-daemon(8) so the pidfile variable
must be set.
- pidfile
- Pidfile to use for the above defined command.
- name
- Display name used for the above defined command.
- retry
- Retry schedule to use when stopping the daemon. It can either be a timeout
in seconds or multiple signal/timeout pairs (like SIGTERM/5).
- required_dirs
- A list of directories which must exist for the service to start.
- required_files
- A list of files which must exist for the service to start.
DEPENDENCIES¶
You should define a
depend
function for the
service so that
openrc-run
will start and
stop it in the right order in relation to other services. As it's a function
it can be very flexible, see the example below. Here is a list of the
functions you can use in a
depend
function.
You simply pass the names of the services to it to add to that dependency
type, or prefix it with ! to remove it.
need
- The service will refuse to start until needed services have started and it
will refuse to stop until any services that need it have stopped.
use
- The service will attempt to start any services we use that have been added
to the runlevel.
after
- The service will start after these services and stop before these
services.
before
- The service will start before these services and stop after these
services.
provide
- We provide this virtual service. For example, named provides dns. Virtual
services take precedence over real services, so it is highly recommended
that you do not have a real service that has the same name as a virtual
service.
config
- We should recalculate our dependencies if the listed files have
changed.
keyword
- Tags a service with a keyword. These are the keywords we currently
understand:
-shutdown
- Don't stop this service when shutting the system down. This is
normally quite safe as remaining daemons will be sent a SIGTERM just
before final shutdown. Network related services such as the network
and dhcpcd init scripts normally have this keyword.
-stop
- Don't stop this service when changing runlevels, even if not present.
This includes shutting the system down.
-timeout
- Other services should wait indefinitely for this service to start. Use
this keyword if your service may take longer than 60 seconds to
start.
-jail
- When in a jail, exclude this service from any dependencies. The
service can still be run directly. Set via
rc_sys
in
/etc/rc.conf
-lxc
- Same as -jail, but for Linux Resource Containers (LXC).
-openvz
- Same as -jail, but for OpenVZ systems.
-prefix
- Same as -jail, but for Prefix systems.
-uml
- Same as -jail, but for UML systems.
-vserver
- Same as -jail, but for VServer systems.
-xen0
- Same as -jail, but for Xen DOM0 systems.
-xenu
- Same as -jail, but for Xen DOMU systems.
To see how to influence dependencies in configuration files, see the
FILES section below.
BUILTINS¶
openrc-run
defines some builtin functions
that you can use inside your service scripts:
einfo
[string
]
- Output a green asterisk followed by the string.
ewarn
[string
]
- Output a yellow asterisk followed by the string.
eerror
[string
]
- Output a red asterisk followed by the string to stderr.
ebegin
[string
]
- Same as einfo, but append 3 dots to the end.
eend
retval
[string
]
- If retval does not equal 0 then output
the string using
eerror
and !! in
square brackets at the end of the line. Otherwise output ok in square
brackets at the end of the line. The value of
retval is returned.
ewend
retval
[string
]
- Same as
eend
, but use
ewarn
instead of
eerror
.
You can prefix the above commands with the letter
v
, which means they only output when the
environment variable
EINFO_VERBOSE is true.
ewaitfile
timeout
file1 file2
...
- Wait for timeout seconds until all files
exist. Returns 0 if all files exist, otherwise non zero. If
timeout is less than 1 then we wait
indefinitely.
is_newer_than
file1 file2
...
- If file1 is newer than
file2 return 0, otherwise 1. If
file2 is a directory, then check all its
contents too.
is_older_than
file1 file2
...
- If file1 is newer than
file2 return 0, otherwise 1. If
file2 is a directory, then check all its
contents too.
service_set_value
name
value
- Saves the name
value for later retrieval. Saved values
are lost when the service stops.
service_get_value
name
- Returns the saved value called name.
service_started
[service
]
- If the service is started, return 0 otherwise 1.
service_starting
[service
]
- If the service is starting, return 0 otherwise 1.
service_inactive
[service
]
- If the service is inactive, return 0 otherwise 1.
service_stopping
[service
]
- If the service is stopping, return 0 otherwise 1.
service_stopped
[service
]
- If the service is stopped, return 0 otherwise 1.
service_coldplugged
[service
]
- If the service is coldplugged, return 0 otherwise 1.
service_wasinactive
[service
]
- If the service was inactive, return 0 otherwise 1.
service_started_daemon
[service
]
daemon
[index
]
- If the service has started the daemon using
start-stop-daemon
, return 0 otherwise
1. If an index is specified, it has to be the nth daemon started by the
service.
mark_service_started
[service
]
- Mark the service as started.
mark_service_starting
[service
]
- Mark the service as starting.
mark_service_inactive
[service
]
- Mark the service as inactive.
mark_service_stopping
[service
]
- Mark the service as stopping.
mark_service_stopped
[service
]
- Mark the service as stopped.
mark_service_coldplugged
[service
]
- Mark the service as coldplugged.
mark_service_wasinactive
[service
]
- Mark the service as inactive.
checkpath
[-D
,
--directory-truncate
]
[-d
,
--directory
]
[-F
,
--file-truncate
]
[-f
,
--file
]
[-p
,
--pipe
]
[-m
,
--mode
mode
]
[-o
,
--owner
owner
]
[-W
,
--writable
]
[-q
,
--quiet
]
path ...
- If -d, -f or -p is specified, checkpath checks to see if the path exists,
is the right type and has the correct owner and access modes. If any of
these tests fail, the path is created and set up as specified. If more
than one of -d, -f or -p are specified, the last one will be used.
The argument to -m is a three or four digit octal number. If this option is
not provided, the value defaults to 0644 for files and 0775 for
directories.
The argument to -o is a representation of the user and/or group which should
own the path. The user and group can be represented numerically or with
names, and are separated by a colon.
The truncate options (-D and -F) cause the directory or file to be cleared
of all contents.
If -W is specified, checkpath checks to see if the first path given on the
command line is writable. This is different from how the test command in
the shell works, because it also checks to make sure the file system is
not read only.
Also, the -d, -f or -p options should not be specified along with this
option.
The -q option suppresses all informational output. If it is specified twice,
all error messages are suppressed as well.
yesno
value
- If value matches YES, TRUE, ON or 1
regardless of case then we return 0, otherwise 1.
ENVIRONMENT¶
openrc-run
sets the following environment
variables for use in the service scripts:
- RC_SVCNAME
- Name of the service.
- RC_SERVICE
- Full path to the service.
- RC_RUNLEVEL
- Current runlevel that OpenRC is in. Note that, in OpenRC, the reboot
runlevel is mapped to the shutdown runlevel. This was done because most
services do not need to know if a system is shutting down or rebooting. If
you are writing a service that does need to know this, see the RC_REBOOT
variable.
- RC_REBOOT
- This variable contains YES if the system is rebooting. If your service
needs to know the system is rebooting, you should test this variable.
- RC_BOOTLEVEL
- Boot runlevel chosen. Default is boot.
- RC_DEFAULTLEVEL
- Default runlevel chosen. Default is default.
- RC_SYS
- A special variable to describe the system more. Possible values are
OPENVZ, XENU, XEN0, UML and VSERVER.
- RC_PREFIX
- In a Gentoo Prefix installation, this variable contains the prefix offset.
Otherwise it is undefined.
- RC_UNAME
- The result of `uname -s`.
- RC_CMD
- This contains the name of the command the service script is executing,
such as start, stop, restart etc. One example of using this is to make a
service script behave differently when restart is being executed.
- RC_GOINGDOWN
- This variable contains YES if the system is going into single user mode or
shutting down.
- RC_LIBEXECDIR
- The value of libexecdir which OpenRC was configured with during build
time.
- RC_NO_UMOUNTS
- This variable is used by plugins to contain a list of directories which
should not be unmounted.
FILES¶
Configuration files, relative to the location of the service. If a file ending
with .${RC_RUNLEVEL} exists then we use that instead.
- ../conf.d/${RC_SVCNAME%%.*}
- multiplexed configuration file. Example: if ${RC_SVCNAME} is net.eth1 then
look for ../conf.d/net.
- ../conf.d/${RC_SVCNAME}
- service configuration file.
- /etc/rc.conf
- host configuration file.
With the exception of
/etc/rc.conf, the
configuration files can also influence the dependencies of the service through
variables. Simply prefix the name of the dependency with rc_. Examples:
# Whilst most services don't bind to a specific interface, our
# openvpn configuration requires a specific interface, namely bge0.
rc_need="net.bge0"
# To put it in /etc/rc.conf you would do it like this
rc_openvpn_need="net.bge0"
# Services should not depend on the tap1 interface for network,
# but we need to add net.tap1 to the default runlevel to start it.
rc_provide="!net"
# To put it in /etc/conf.d/net you would do it like this
rc_provide_tap1="!net"
# To put in in /etc/rc.conf you would do it like this
rc_net_tap1_provide="!net"
# It's also possible to negate keywords. This is mainly useful for prefix
# users testing OpenRC.
rc_keyword="!-prefix"
EXAMPLES¶
An example service script for foo.
#!/sbin/openrc-run
command=/usr/bin/foo
command_args="${foo_args} --bar"
pidfile=/var/run/foo.pid
name="FooBar Daemon"
description="FooBar is a daemon that eats and drinks"
extra_commands="show"
extra_started_commands="drink eat"
description_drink="Opens mouth and reflexively swallows"
description_eat="Chews food in mouth"
description_show="Shows what's in the tummy"
_need_dbus()
{
grep -q dbus /etc/foo/plugins
}
depend()
{
# We write a pidfile and to /var/cache, so we need localmount.
need localmount
# We can optionally use the network, but it's not essential.
use net
# We should be after bootmisc so that /var/run is cleaned before
# we put our pidfile there.
after bootmisc
# Foo may use a dbus plugin.
# However, if we add the dbus plugin whilst foo is running and
# stop dbus, we don't need to stop foo as foo didn't use dbus.
config /etc/foo/plugins
local _need=
if service_started; then
_need=`service_get_value need`
else
if _need_dbus; then
_need="${_need} dbus"
fi
fi
need ${_need}
}
# This function does any pre-start setup. If it fails, the service will
# not be started.
# If you need this function to behave differently for a restart command,
# you should check the value of RC_CMD for "restart".
# This also applies to start_post, stop_pre and stop_post.
start_pre()
{
if [ "$RC_CMD" = restart ]; then
# This block will only execute for a restart command. Use a
# structure like this if you need special processing for a
# restart which you do not need for a normal start.
# The function can also fail from here, which will mean that a
# restart can fail.
# This logic can also be used in start_post, stop_pre and
# stop_post.
fi
# Ensure that our dirs are correct
checkpath --directory --owner foo:foo --mode 0775 \
/var/run/foo /var/cache/foo
}
start_post()
{
# Save our need
if _need_dbus; then
service_set_value need dbus
fi
}
stop_post() {
# Clean any spills
rm -rf /var/cache/foo/*
}
drink()
{
ebegin "Starting to drink"
${command} --drink beer
eend $? "Failed to drink any beer :("
}
eat()
{
local result=0 retval= ate= food=
ebegin "Starting to eat"
if yesno "${foo_diet}"; then
eend 1 "We are on a diet!"
return 1
fi
for food in /usr/share/food/*; do
veinfo "Eating `basename ${food}`"
${command} --eat ${food}
retval=$?
: $(( result += retval ))
[ ${retval} = 0 ] && ate="${ate} `basename ${food}`"
done
if eend ${result} "Failed to eat all the food"; then
service_set_value ate "${ate}"
fi
}
show()
{
einfo "Foo has eaten: `service_get_value ate`"
}
BUGS¶
Because of the way we load our configuration files and the need to handle more
than one service directory, you can only use symlinks in service directories
to other services in the same directory. You cannot symlink to a service in a
different directory even if it is another service directory.
is_older_than should return 0 on success. Instead we return 1 to be compliant
with Gentoo baselayout. Users are encouraged to use the is_newer_than function
which returns correctly.
SEE ALSO¶
einfo(3),
openrc(8),
rc-status(8),
rc-update(8),
rc_plugin_hook(3),
sh(1p),
start-stop-daemon(8),
uname(1)
AUTHORS¶
Roy Marples <roy@marples.name>