The service description files for Dinit each describe a
service. The name of the file corresponds to the name of the service it
describes.
Service description files specify the various attributes of a
service. A service description file is named after the service it
represents, and is a plain-text file with simple key-value format. The
description files are located in a service description directory; by
default, the system dinit process searches /etc/dinit.d,
/usr/local/lib/dinit.d and /lib/dinit.d, while a user process
searches $HOME/.config/dinit.d. See dinit(8) for more details
of how and when service descriptions are loaded.
All services have a type and a set of dependencies.
These are discussed in the following subsections. The type, dependencies,
and other attributes are specified via property settings, the format of
which are documented in the SERVICE PROPERTIES subsection, which also
lists the available properties.
There are five basic types of service:
- Process services. This kind of service runs as a single process;
starting the service simply requires starting the process; stopping the
service is accomplished by stopping the process (via sending it a
signal).
- Bgprocess services ("background process" services). This
kind of service is similar to a regular process service, but the process
daemonizes or otherwise forks from the original process which starts it,
and the process ID is written to a file. Dinit can read the process ID
from the file and, if it is running as the system init process, can
supervise it.
- Scripted services are services which are started and stopped by a
command (which need not actually be a script, despite the name). They can
not be supervised.
- Internal services do not run as an external process at all. They
can be started and stopped without any external action. They are useful
for grouping other services (via service dependencies).
- Triggered services are similar to internal processes, but an external
trigger is required before they will start (i.e. their startup will pause
until the trigger occurs). The dinitctl trigger command can be used
to trigger such a service; see dinitctl(8).
Independent of their type, the state of services can be linked to
other services via dependency relationships, which are discussed in the next
section.
A service dependency relationship, broadly speaking, specifies
that for one service to run, another must also be running. The first service
is the dependent service and the latter is the dependency
service (we will henceforth generally refer to the the dependency
relationship as the relationship and use dependency to refer
to the service). A dependency relationship is specified via the properties
of the dependent. There are different relationship types, as follows:
- A need (or "hard") relationship specifies that the
dependent must wait for the dependency to be started before it starts, and
that the dependency must remain started while the dependent is started.
Starting the dependent will start the dependency, and stopping the
dependency will stop the dependent. This type of relationship is specified
using a depends-on property.
- A milestone relationship specifies that the dependency must start
successfully before the dependent starts. Starting the dependent will
therefore start the dependency. Once started, the relationship is
satisfied; if the dependency then stops, it has no effect on the
dependent. However, if the dependency fails to start or has its startup
cancelled, the dependent will not start (and will return to the stopped
state). This type of relationship is specified using a depends-ms
property.
- A waits-for relationship specifies that the dependency must start
successfully, or fail to start, before the dependent starts. Starting the
dependent will attempt to first start the dependency, but failure will not
prevent the dependent from starting. If the dependency starts, stopping it
will have no effect on the dependent. This type of relationship is
specified using a waits-for property.
Note that process-based services always wait for their dependency
relationships to be satisfied (by the dependency starting, or failing to
start in case of a waits-for relationship) before their process is launched.
Conversely, a termination signal will not in general be sent to a service
process until the service has no active dependents.
Since in general dependencies should remain started so long as
their dependent does, an attachment forms between the two once both are
started. This attachment is released when the dependent stops, and the
dependency will then stop, unless it has other attachments or it has been
explicitly started independently. Attachments between a dependent and
dependency are re-created if a dependency starts (or starts again) while the
dependent is still started.
This section described the various service properties that can be
specified in a service description file. The properties specify the type of
the service, dependencies of the service, and other service
configuration.
Each line of the file can specify a single property value,
expressed as `property-name = value'. Comments begin with a
hash mark (#) and extend to the end of the line (they must be separated from
setting values by at least one whitespace character). Values are interpreted
literally, except that:
- White space (comprised of spaces, tabs, etc) is collapsed to a single
space, except leading or trailing white space around the property value,
which is stripped.
- For settings which specify a command with arguments, the value is
interpreted as a series of tokens separated by white space, rather than a
single string of characters.
- Double quotes (") can be used around all or part of a property value,
to prevent whitespace collapse and prevent interpretation of other special
characters (such as "#") inside the quotes. The quote characters
are not considered part of the property value. White space appearing
inside quotes does not act as a delimiter for tokens.
- A backslash (\) can be used to escape the next character, causing it to
lose any special meaning and become part of the property value. A double
backslash (\\) is collapsed to a single backslash within the parameter
value. White space preceded by a backslash will not separate tokens.
Setting a property generally overrides any previous setting (from
prior lines). However some properties are set additively; these include
dependency relationships and options properties.
The following properties can be specified:
- type = {process |
bgprocess | scripted | internal | triggered}
- Specifies the service type; see the SERVICE TYPES section.
- command =
command-string
- Specifies the command, including command-line arguments, for starting the
process. Applies only to process, bgprocess and
scripted services. The value is subject to variable substitution
(see VARIABLE SUBSTITUTION).
- stop-command =
command-string
- Specifies the command to stop the service (optional). Applicable to
process, bgprocess and scripted services. If
specified for process or bgprocess services, the "stop
command" will be executed in order to stop the service, instead of
signalling the service process. The value is subject to variable
substitution (see VARIABLE SUBSTITUTION).
- working-dir =
directory
- Specifies the working directory for this service. For a scripted service,
this affects both the start command and the stop command. The value is
subject to variable substitution (see VARIABLE SUBSTITUTION).
- run-as =
user-id
- Specifies which user to run the process(es) for this service as. Specify
as a username or numeric ID. If specified by name, the group for the
process will also be set to the primary group of the specified user, and
supplementary groups will be initialised (unless support for them is
disabled) according to the system's group database. If specified by
number, the group for the process will remain the same as that of the
running dinit process, and all supplementary groups will be dropped
(unless support has been disabled).
- env-file =
file
- Specifies a file containing value assignments for environment variables,
in the same format recognised by the dinit command's
--env-file option (see dinit(8)). The file is read when the
service is loaded, therefore values from it can be used in variable
substitutions (see VARIABLE SUBSTITUTION). Variable substitution is
not performed on the env-file property value itself.
- restart = {yes |
true | no | false}
- Indicates whether the service should automatically restart if it stops,
including due to unexpected process termination or a dependency stopping.
Note that if a service stops due to user request, automatic restart is
inhibited. The default is to automatically restart.
- smooth-recovery =
{yes | true | no | false}
- Applies only to process and bgprocess services. When set
true/yes, an automatic process restart can be performed without first
stopping any dependent services. This setting is meaningless if the
restart setting is set to false.
- restart-delay
= XXX.YYYY
- Specifies the minimum time (in seconds) between automatic restarts.
Enforcing a sensible minimum prevents Dinit from consuming a large number
of process cycles in case a process continuously fails immediately after
it is started. The default is 0.2 (200 milliseconds).
- restart-limit-interval
= XXX.YYYY
- Sets the interval (in seconds) over which restarts are limited. If a
process automatically restarts more than a certain number of times
(specified by the restart-limit-count setting) in this time
interval, it will not be restarted again. The default value is 10
seconds.
- restart-limit-count
= NNN
- Specifies the maximum number of times that a service can automatically
restart over the interval specified by restart-limit-interval.
Specify a value of 0 to disable the restart limit. The default value is
3.
- start-timeout =
XXX.YYY
- Specifies the time in seconds allowed for the service to start. If the
service takes longer than this, its process group is sent a SIGINT signal
and enters the "stopping" state (this may be subject to a stop
timeout, as specified via stop-timeout, after which the process
group will be terminated via SIGKILL). The timeout period begins only when
all dependencies have been satisfied. The default value is 60. A value of
0 allows unlimited start time.
- stop-timeout =
XXX.YYY
- Specifies the time in seconds allowed for the service to stop. If the
service takes longer than this, its process group is sent a SIGKILL signal
which should cause it to terminate immediately. The timeout period begins
only when all dependent services have already stopped. The default value
is 10. A value of 0 allows unlimited stop time.
- pid-file =
path-to-file
- For bgprocess type services only; specifies the path of the file
where daemon will write its process ID before detaching. Dinit will read
the contents of this file when starting the service, once the initial
process exits, and will supervise the process with the discovered process
ID. Dinit may also send signals to the process ID to stop the service; if
dinit runs as a privileged user the path should therefore not be
writable by unprivileged users.
The value is subject to variable substitution (see VARIABLE
SUBSTITUTION).
- depends-on =
service-name
- This service depends on the named service. Starting this service will
start the named service; the command to start this service will not be
executed until the named service has started. If the named service is
stopped then this service will also be stopped.
- depends-ms =
service-name
- This service has a "milestone" dependency on the named service.
Starting this service will start the named service; this service will not
start until the named service has started, and will fail to start if the
named service does not start. Once the named (dependent) service reaches
the started state, however, the dependency may stop without affecting the
dependent service.
- waits-for =
service-name
- When this service is started, wait for the named service to finish
starting (or to fail starting) before commencing the start procedure for
this service. Starting this service will automatically start the named
service. If the named service fails to start, this service will start as
usual (subject to other dependencies being met).
- waits-for.d =
directory-path
- For each file name in directory-path which does not begin with a
dot, add a waits-for dependency to the service with the same name.
Note that contents of files in the specified directory are not
significant; expected usage is to have symbolic links to the associated
service description files, but this is not required. Failure to read the
directory contents, or to find any of the services named within, is not
considered fatal.
The directory path, if not absolute, is relative to the
directory containing the service description file.
- after =
service-name
- When starting this service, if the named service is also starting, wait
for the named service to finish starting before bringing this service up.
This is similar to a waits-for dependency except no dependency
relationship is implied; if the named service is not starting, starting
this service will not cause it to start (nor wait for it in that case). It
does not by itself cause the named service to be loaded (if loaded later,
the "after" relationship will be enforced from that point).
- before =
service-name
- When starting the named service, if this service is also starting, wait
for this service to finish starting before bringing the named service up.
This is largely equivalent to specifying an after relationship to
this service from the named service. However, it does not by itself cause
the named service to be loaded (if loaded later, the "before"
relationship will be enforced from that point).
- chain-to =
service-name
- When this service terminates (i.e. starts successfully, and then stops of
its own accord), the named service should be started. Note that the named
service is not loaded until that time; naming an invalid service will not
cause this service to fail to load.
This can be used for a service that supplies an interactive
"recovery mode" for another service; once the user exits the
recovery shell, the primary service (as named via this setting) will
then start. It also supports multi-stage system startup where later
service description files reside on a separate filesystem that is
mounted during the first stage; such service descriptions will not be
found at initial start, and so cannot be started directly, but can be
chained via this directive.
The chain is not executed if the initial service was
explicitly stopped, stopped due to a dependency stopping (for any
reason), if it will restart (including due to a dependent restarting),
or if its process terminates abnormally or with an exit status
indicating an error. However, if the always-chain option is set
the chain is started regardless of the reason and the status of this
service termination.
- socket-listen =
socket-path
- Pre-open a socket for the service and pass it to the service using the
systemd activation protocol. This by itself does not give so called
"socket activation", but does allow any process trying to
connect to the specified socket to do so immediately after the service is
started (even before the service process is properly prepared to accept
connections).
The path value is subject to variable substitution (see
VARIABLE SUBSTITUTION).
- socket-permissions
= octal-permissions-mask
- Gives the permissions for the socket specified using socket-listen.
Normally this will be 600 (user access only), 660 (user and group access),
or 666 (all users). The default is 666.
- socket-uid =
{numeric-user-id | username}
- Specifies the user (name or numeric ID) that should own the activation
socket. If socket-uid is specified as a name without also
specifying socket-gid, then the socket group is the primary group
of the specified user (as found in the system user database, normally
/etc/passwd). If the socket-uid setting is not provided, the
socket will be owned by the user id of the dinit process.
- socket-gid =
{numeric-group-id | group-name}
- Specifies the group of the activation socket. See discussion of
socket-uid.
- term-signal =
{none | signal-name}
- Specifies the signal to send to the process when requesting it to
terminate (applies to `process' and `bgprocess' services only). Signal
names are specified as the POSIX signal name without the SIG-
prefix. At least HUP, TERM, and KILL are supported
(use dinitctl signal --list for the full list of supported
signals). The default is TERM (the SIGTERM signal). See also the
discussion of stop-timeout.
- ready-notification =
{pipefd:fd-number |
pipevar:env-var-name}
- Specifies the mechanism, if any, by which a process service will notify
that it is ready (successfully started). If not specified, a process
service is considered started as soon as it has begun execution. The two
options are:
- pipefd:fd-number — the service will write a message
to the specified file descriptor, which dinit sets up as the write
end of a pipe before execution. This mechanism is compatible with the S6
supervision suite.
- pipevar:env-var-name — the service will write a
message to file descriptor identified using the contents of the specified
environment variable, which will be set by dinit before execution
to a file descriptor (chosen arbitrarily) attached to the write end of a
pipe.
- log-type = {file | buffer
| pipe | none}
- Specifies how the output of this service is logged. This setting is valid
only for process-based services (including scripted services).
- file: output will be written to a file; see the logfile
setting.
- buffer: output will be buffered in memory, up to a limit specified
via the log-buffer-size setting. The buffer contents can be
examined via the dinitctl(8) catlog subcommand.
- pipe: output will be written to a pipe, and may be consumed by
another service (see the consumer-of setting); note that, if output
is not consumed promptly, the pipe buffer may become full which may cause
the service process to stall.
- none: output is discarded.
- The default log type is none, unless the logfile setting is
specified in which case the default log type is file. For
pipe (and buffer, which uses a pipe internally) note that
the pipe created may outlive the service process and be re-used if the
service is stopped and restarted.
- logfile =
log-file-path
- Specifies the log file for the service. Output from the service process
(standard output and standard error streams) will be appended to this
file, which will be created if it does not already exist. The file
ownership and permissions are adjusted according to the
logfile-uid, logfile-gid and logfile-permissions
settings. This setting has no effect if the service is set to run on the
console (via the runs-on-console, starts-on-console, or
shares-console options). The value is subject to variable
substitution (see VARIABLE SUBSTITUTION). Note that if the
directory in which the logfile resides does not exist (or is not otherwise
accessible to dinit) when the service is started, the service will
not start successfully. If this settings is specified and log-type
is not specified or is currently none, then the log type will be
changed to file.
- logfile-permissions
= octal-permissions-mask
- Gives the permissions for the log file specified using logfile.
Normally this will be 600 (user access only), 640 (also readable by the
group), or 644 (readable by all users). If the log file already exists
when the service starts, its permissions will be changed in accordance
with the value of this setting. The default is value 600 (accessible to
only the owning user).
- logfile-uid =
{numeric-user-id | username}
- Specifies the user (name or numeric ID) that should own the log file. If
logfile-uid is specified as a name without also specifying
logfile-gid, then the log file group is the primary group of the
specified user (as found in the system user database, normally
/etc/passwd). If the log file already exists when the service
starts, its ownership will be changed in accordance with the value of this
setting. The default value is the user id of the dinit
process.
- logfile-gid =
{numeric-group-id | group-name}
- Specifies the group of the log file. See discussion of
logfile-uid.
- log-buffer-size =
size-in-bytes
- If the log type (see log-type) is set to buffer, this
setting controls the maximum size of the buffer used to store process
output. If the buffer becomes full, further output from the service
process will be discarded.
- consumer-of =
service-name
- Specifies that this service consumes (as its standard input) the output of
another service. For example, this allows this service to act as a logging
agent for another service. The named service must be a process-based
service with log-type set to pipe. This setting is only
valid for process and bgprocess services.
- options =
option...
- Specifies various options for this service. See the OPTIONS
section. This directive can be specified multiple times to set additional
options.
- load-options =
load_option...
- Specifies options for interpreting other settings when loading this
service description. Currently there are two available options. One is
export-passwd-vars, which specifies that the environment variables
`USER', `LOGNAME' (same as `USER'), `HOME',
`SHELL', `UID', and `GID' should be exported into the
service's load environment (that is, overriding any global environment
including the global environment file, but being overridable by the
service's environment file). The other is export-service-name,
which will set the environment variable `DINIT_SERVICE' containing
the name of the current service.
- inittab-id =
id-string
- When this service is started, if this setting (or the inittab-line
setting) has a specified value, an entry will be created in the system
"utmp" database which tracks processes and logged-in users.
Typically this database is used by the "who" command to list
logged-in users. The entry will be cleared when the service terminates.
The inittab-id setting specifies the "inittab
id" to be written in the entry for the process. The value is
normally quite meaningless. However, it should be distinct (or unset)
for separate processes. It is typically limited to a very short
length.
The "utmp" database is mostly a historical artifact.
Access to it on some systems is prone to denial-of-service by
unprivileged users. It is therefore recommended that this setting not be
used. However, "who" and similar utilities may not work
correctly without this setting (or inittab-line) enabled
appropriately.
This setting has no effect if Dinit was not built with support
for writing to the "utmp" database. It applies only to
process services.
- inittab-line
= tty-name-string
- This specifies the tty line that will be written to the "utmp"
database when this service is started. Normally, for a terminal login
service, it would match the terminal device name on which the login
process runs, without the "/dev/" prefix.
See the description of the inittab-id setting for
details.
- rlimit-nofile =
resource-limits
- Specifies the number of file descriptors that a process may have open
simultaneously. See the RESOURCE LIMITS section.
- rlimit-core =
resource-limits
- Specifies the maximum size of the core dump file that will be generated
for the process if it crashes (in a way that would result in a core dump).
See the RESOURCE LIMITS section.
- rlimit-data =
resource-limits
- Specifies the maximum size of the data segment for the process, including
statically allocated data and heap allocations. Precise meaning may vary
between operating systems. See the RESOURCE LIMITS section.
- rlimit-addrspace
= resource-limits
- Specifies the maximum size of the address space of the process. See the
RESOURCE LIMITS section. Note that some operating systems (notably,
OpenBSD) do not support this limit; the setting will be ignored on such
systems.
- run-in-cgroup =
cgroup-path
- Run the service process(es) in the specified cgroup (see
cgroups(7)). The cgroup is specified as a path; if it has a leading
slash, the remainder of the path is interpreted as relative to
/sys/fs/cgroup, and otherwise the entire path is interpreted
relative to the cgroup in which dinit is running (as determined at
startup or specified by options). The latter can only be used if there is
only a single cgroup hierarchy (either the cgroups v2 hierarchy with no
cgroups v1 hierarchies, or a single cgroups v1 hierarchy).
Note that due to the "no internal processes" rule in
cgroups v2, a relative path must typically begin with ".." if
cgroups v2 are used.
The named cgroup must already exist prior to the service
starting; it will not be created by dinit.
This setting is only available if dinit was built with
cgroups support.
These options are specified via the options parameter.
- runs-on-console
- Specifies that this service uses the console; its input and output should
be directed to the console (or precisely, to the device to which
dinit's standard output stream is connected). A service running on
the console prevents other services from running on the console (they will
queue for the console).
Proper operation of this option (and related options) assumes
that dinit is itself attached correctly to the console device (or
a terminal, in which case that terminal will be used as the
"console").
The interrupt key (normally control-C) may be active
for process / scripted services that run on the console, depending on
terminal configuration and operating-system specifics. The interrupt
signal (SIGINT), however, is masked by default (but see
unmask-intr).
- starts-on-console
- Specifies that this service uses the console during service startup. This
is identical to runs-on-console except that the console will be
released (available for running other services) once the service has
started. It is applicable only for bgprocess and scripted
services.
As for the runs-on-console option, the interrupt
key will be enabled while the service has the console.
- shares-console
- Specifies that this service should be given access to the console (input
and output will be connected to the console), but that it should not
exclusively hold the console. A service given access to the console in
this way will not delay the startup of services which require exclusive
access to the console (see starts-on-console,
runs-on-console) nor will it be itself delayed if such services are
already running.
This is mutually exclusive with both starts-on-console
and runs-on-console; setting this option unsets both those
options, and setting either of those options unsets this option.
- unmask-intr
- For services that run or start on the console, specifies that the terminal
interrupt signal (SIGINT, normally invoked by control-C) should be
unmasked. Handling of an interrupt is determined by the service process,
but typically will cause it to terminate. This option may therefore be
used to allow a service to be terminated by the user via a keypress
combination. In combination with skippable, it may allow service
startup to be skipped.
A service with this option will typically also have the
start-interruptible option set.
Note that whether an interrupt can be generated, and the key
combination required to do so, depends on the operating system's
handling of the console device and, if it is a terminal, how the
terminal is configured; see stty(1).
Note also that a process may choose to mask or unmask the
interrupt signal of its own accord, once it has started. Shells, in
particular, may unmask the signal; it might not be possible to reliably
run a shell script on the console without allowing a user to interrupt
it.
- starts-rwfs
- This service mounts the root filesystem read/write (or at least mounts the
normal writable filesystems for the system). This prompts Dinit to attempt
to create its control socket, if it has not already managed to do so, and
similarly log boot time to the system wtmp(5) database (if
supported) if not yet done. This option may be specified on multiple
services, which may be useful if the wtmp database becomes writable
at a different stage than the control socket location becomes writable,
for example. If the control socket has already been created, this option
currently causes Dinit to check that the socket "file" still
exists and re-create it if not. It is not recommended to rely on this
behaviour.
- starts-log
- This service starts the system log daemon. Dinit will begin logging via
the /dev/log socket.
- pass-cs-fd
- Pass an open Dinit control socket to the process when launching it (the
DINIT_CS_FD environment variable will be set to the file descriptor
of the socket). This allows the service to issue commands to Dinit even if
the regular control socket is not available yet.
Using this option has security implications! The service which
receives the control socket must close it before launching any untrusted
processes. You should not use this option unless the service is designed
to receive a Dinit control socket.
- start-interruptible
- Indicates that this service can have its startup interrupted (cancelled),
by sending it the SIGINT signal. If service state changes such that this
service will stop, but it is currently starting, and this option is set,
then Dinit will attempt to interrupt it rather than waiting for its
startup to complete. This is meaningful only for bgprocess and
scripted services.
- skippable
- For scripted services, indicates that if the service startup process
terminates via an interrupt signal (SIGINT), then the service should be
considered started. Note that if the interrupt was issued by Dinit to
cancel startup, the service will instead be considered stopped.
This can be combined with options such as
starts-on-console to allow skipping certain non-essential
services (such as filesystem checks) using the interrupt key
(typically control-C).
- signal-process-only
- Signal the service process only, rather than its entire process group,
whenever sending it a signal for any reason.
- always-chain
- Alters behaviour of the chain-to property, forcing the chained
service to always start on termination of this service (instead of only
when this service terminates with an exit status indicating success).
- kill-all-on-stop
- Before stopping this service, send a TERM signal and then (after a short
pause) a KILL signal to all other processes in the system, forcibly
terminating them. This option is intended to allow system shutdown scripts
to run without any possible interference from "leftover" or
orphaned processes (for example, unmounting file systems usually requires
that the file systems are no longer in use).
This option must be used with care since the signal broadcast
does not discriminate and potentially kills other services (or their
shutdown scripts); a strict dependency ordering is suggested, i.e. every
other service should either be a (possibly transitive) dependency or
dependent of the service with this option set.
This option can be used for scripted and internal services
only.
There are several settings for specifying process resource limits:
rlimit-nofile, rlimit-core, rlimit-data and
rlimit-addrspace. See the descriptions of each above. These settings
place a limit on resource usage directly by the process. Note that resource
limits are inherited by subprocesses, but that usage of a resource and
subprocess are counted separately (in other words, a process can effectively
bypass its resource limits by spawning a subprocess and allocating further
resources within it).
Resources have both a hard and soft limit. The soft
limit is the effective limit, but note that a process can raise its soft
limit up to the hard limit for any given resource. Therefore the soft limit
acts more as a sanity-check; a process can exceed the soft limit only by
deliberately raising it first.
Resource limits are specified in the following format:
soft-limit:hard-limit
Either the soft limit or the hard limit can be omitted (in which
case it will be unchanged). A limit can be specified as a dash, `-',
in which case the limit will be removed. If only one value is specified with
no colon separator, it affects both the soft and hard limit.
Some service properties specify a path to a file or directory, or
a command line. For these properties, the specified value may contain one or
more environment variable names, each preceded by a single `$'
character, as in `$NAME'. In each case the value of the named
environment variable will be substituted. The name must begin with a
non-punctuation, non-space, non-digit character, and ends before the first
control character, space, or punctuation character other than `_'. To
avoid substitution, a single `$' can be escaped with a second, as in
`$$'.
Variable substitution also supports a limited subset of shell
syntax. You can use curly braces to enclose the variable, as in
`${NAME}'. Limited parameter expansion is also supported,
specifically the forms `${NAME:-word}' (substitute `word' if
variable is unset or empty), `${NAME-word}' (substitute `word'
if variable is unset), `${NAME:+word}' (substitute `word' if
variable is set and non-empty), and `${NAME+word}' (substitute
`word' if variable is set). Unlike in shell expansion, the
substituted word does not itself undergo expansion and cannot contain
closing brace characters or whitespace, even if quoted.
Note command-line variable substitution occurs after splitting the
line into separate arguments and so a single environment variable cannot be
used to add multiple arguments to a command line. If a designated variable
is not defined, it is replaced with an empty (zero-length) string, possibly
producing a zero-length argument.
Variable substitution occurs when the service is loaded.
Therefore, it is typically not useful for dynamically changing service
parameters (including command line) based on a variable that is inserted
into dinit's environment once it is running (for example via
dinitctl setenv).
The effective environment for variable substitution in setting
values matches the environment supplied to the process for a service when it
is launched. The priority of environment variables, from highest to lowest,
for both is:
- variables from the service env-file
- variables set by the export-passwd-vars and
export-service-name load options
- the process environment of dinit (which is established on launch by
the process environment of the parent, amended by loading the environment
file (if any) as specified in dinit(8), and further amended via
dinitctl setenv commands or equivalent).
Note that since variable substitution is performed on service
load, the values seen by a service process may differ from those used for
substitution, if they have been changed in the meantime.
Here is an example service description for the mysql
database server. It has a dependency on the rcboot service (not
shown) which is expected to have set up the system to a level suitable for
basic operation.
# mysqld service
type = process
command = /usr/bin/mysqld --user=mysql
logfile = /var/log/mysqld.log
smooth-recovery = true
restart = false
depends-on = rcboot # Basic system services must be ready
Here is an examples for a filesystem check "service",
run by a script (/etc/dinit.d/rootfscheck.sh). The script may need to
reboot the system, but the control socket may not have been created, so it
uses the pass-cs-fd option to allow the reboot command to
issue control commands to Dinit. It runs on the console, so that output is
visible and the process can be interrupted using control-C, in which case
the check is skipped but dependent services continue to start.
# rootfscheck service
type = scripted
command = /etc/dinit.d/rootfscheck.sh
restart = false
options = starts-on-console pass-cs-fd
options = start-interruptible skippable
depends-on = early-filesystems # /proc and /dev
depends-on = device-node-daemon
More examples are provided with the Dinit distribution.