LCFG systemd documentation
Also see
SystemdCookbook for various examples of how to use Systemd with LCFG.
Introduction
Systemd has units (kind of equivalent to sysv init scripts) :-
- service - manage daemons - start/stop/reload/restart
- socket - lazy start - each socket has matching service which is started on first connection to socket (like xinetd)
- target - does nothing - used to group other units to provide a 'sync' point during boot
- device, mount, automount, slice ... - not covered here
Each unit Y can have dependencies :-
- Y wants X - Y will 'pull-in' X, but won't fail if X fails to start for any reason
- Y requires X - as for 'wants X', but Y will fail if X fails to start
- Y after X / Y before X
All units started together unless order defined :-
- order is orthagonal to dependencies
Service units
- service units have one of the following 'type' :-
- simple - specified command runs in foreground
- forking - forks a child and exits
- oneshot - one shot task and exits
- notify - linked against systemd's sd_notify()
- service unit options
- ExecStart - command (with argument) to be executed to start service
- ExecReload - command to reload service
- ExecStop - command to stop service
- ExecStartPre - command to call before executing command specified by ExecStart
- ExecStartPost - command to call after executing command specified by ExecStart
- ExecStopPost - command to call after executing command specifed by ExecStop
- EnvironmentFile - a file containing environment variables to be set before running above commands
Systemd directory structure
-
/usr/lib/systemd/system
- a directory of available units. Each unit can have a directory {unit}.wants and a directory {unit}.requires : these directories have links to other units that are wanted or required by the unit. These files are shipped by RPM and are considered read-only.
-
/etc/systemd/system
- this directory is writeable and is overlaid on top of
/usr/lib/systemd/system
. It is used to override unit files in /usr/lib/systemd/system
. It is also used to create local unit files (eg for LCFG). As with /usr/lib/systemd/system
, each unit can have a {unit}.wants and {unit}.requires directory : if a unit has one of these directories in both the /usr and /etc trees, the union of both directories is used.
Note that a system with an empty
/etc/systemd/system
directory should boot correctly.
Macros
-
REGISTER_COMPONENT_WITH_SYSTEMD(COMP,REQUIRES,AFTER,WANTEDBYTAG)
- creates a one-shot service unit to start component LCFG component
COMP
. REQUIRES
- units that this component requires to run (optional). AFTER
- units that should be started before this component (optional). WANTEDBYTAG
- the tag of the unit that this component is wanted by (required). WANTEDBYTAG
should be set to 'lcfgmultiuser' if it has the capability to ask for a reboot, or is required by components that may ask for a reboot. It should be set to 'multiusertarget' if it should not be started until after any boot-time reboots have been completed (eg getty, gdm, apacheconf etc).
-
LCFG_SYSTEMD_UNIT(TAG,RN)
- define a unit whose real name is
RN
. This macro doesn't create a unit file. It is used, with systemd.required_units_{TAG} and systemd.wanted_units_{TAG}, to populate {service}.wants and {service}.requires subdirectories of /etc/systemd/system.
-
LCFG_SYSTEMD_UNIT_WANTEDBY(TAG,RN,WANTEDBYTAG)
- as
LCFG_SYSTEMD_UNIT
but also adds this unit to systemd.wanted_units resource of unit WANTEDBYTAG.
-
LCFG_SYSTEMD_UNIT_LINK(TAG,RN,LINK)
- define a unit whose real name is
RN
. This macro creates a link RN
, in /etc/systemd/system, to the unit file LINK
in /usr/lib/systemd/system.
-
LCFG_SYSTEMD_UNIT_LINK_WANTEDBY(TAG,RN,LINK,WANTEDBYTAG)
- as
LCFG_SYSTEMD_UNIT_LINK
but also adds this unit to systemd.wanted_units resource of unit WANTEDBYTAG
-
LCFG_SYSTEMD_WAIT(TAG,DELAYEDUNIT,DEPENDENCYUNIT)
- delays the start of unit
DELAYEDUNIT
until after unit DEPENDENCYUNIT
has started. Useful for delaying the start of built-in units (those defined in /usr).
LCFG targets
- multi-user.target (as end 'default' target)
- lcfg-multi-user-stable.target
- lcfg-multi-user.target
- lcfg-auth.service (after network.target)
- lcfg-client.service (after network.target)
- lcfg-updaterpms.service (after network.target)
- lcfg-rebootcheck.service (after lcfg-multi-user.target)
- lcfg-clearbootctx.service (after lcfg-multi-user-stable.target)
- lcfg-cron.service (after lcfg-multi-user-stable.target)
- lcfg-apacheconf.service (after lcfg-multi-user-stable.target)
- lcfg-openssh.service (after lcfg-multi-user-stable.target)
- getty.service (after lcfg-multi-user-stable.target)
See this blog post
Fun with systemd targets
for some explanation of the above targets.
This
SVG file shows the dependencies between targets and LCFG services, pruned at basic.target. You can use inkscape to display this file.
There is an additional
internet-online
target that can be used to delay the start of a unit until a fully-routed network connection is available.
Systemd notes of interest
Debugging
Systemd will open a root shell on VT9 as early as it can if you set
systemd.debug-shell=1
on the kernel command line.
Overriding dependencies
It does not appear possible to override dependencies defined through a unit's .wants or .requires directories.
A unit can declare a 'want' or 'require' either through directives in its unit file or through links created in a .wants or .requires directory.
You can easily override dependencies specified in a unit's unit file, by creating a file of the same name in /etc with the offending directives removed. This file is simply used instead of the file in /lib. For example, unit sshd.service might specify that it 'Wants' kerberos.service by means of a Wants directive in its unit file /lib/systemd/sshd.service. One can override this by creating an /etc/systemd/sshd.service with the offending Wants directive removed.
One might expect that creating unit's .wants or .requires directories in /etc would override the equivalent directories in /lib, but that is not the case. For example, ntpd.service may specify that it 'Requires' network.target by means of a symlink, in /lib/systemd/ntpd.service.requires, to the network.target unit file. One might expect that you could remove this dependency by creating a directory /etc/systemd/ntpd.service.requires without the offending symlink. Unfortunately this isn't what happens - instead, systemd uses the union of /etc/systemd/ntpd.service.requires and /lib/systemd/ntpd.service.requires.
Target dependencies
If you have a target B.target which wants/requires S.service and you want S.service to start after A.target - it isn't sufficient to state B.target 'requires' and 'after' A.target. If you just do that, S.service will start based on its own requires/afters - usually much earlier than after A.target. You also need to state that S.service 'requires' and 'after' A.target.
How shutdown works
There is a
good article
which describes how shutdown works with systemd.
Schema
See
lcfg-systemd(8)
Known issues
- The 'systemctl' command shows units to be disabled even though they are not. This is due to the fact that the systemd component currently creates null files in /etc/systemd/ rather than links to units in /usr/lib/systemd. This will be fixed prior to the upgrade to SL7.3
-- Main.ascobie - 2014-08-19