unit - resource that system operates.

Systemd operates unit files which can be multiple types .service, .socket, .device etc. To start process we need only .service file.

Unit files mostly stored in /etc/systemd/system. There may be other directories with units but this one has maximum priority.

For example system units are in /lib/systemd/system. To override system unit, copy file from /lib/systemd/system to /etc/systemd/system and edit.

To override only specific directives, for unit named unit_name.service create unit_name.service.d directory in the /etc/systemd/system and place .conf file there with overridden or extended attributes.

Runtime units placed in /run/systemd/system, this directory can be used to change units for session but changes will be lost after reboot.

Sections

  • section names are case-sensetive, e.g. [Unit]

custom user sections start with X-

  • In case of overriding files inside of unit.type.d dir you can eliminate default value by assigning nothing:
Directive1=

values

For booleans you can use:

  • true 1, yes, on, true
  • false 0, no, off, false

Directives in [Unit] section

  • Requires= units on which this unit depends. They started in parallel with the current unit by default. If start of them impossible (not found or failed) current unit will also fail
  • Wants= like Requires= but less strict - will simply ignore failed units.
  • BindsTo= like Requires= but causes current unit stop if binded unit was terminated
  • Before= units which will wait for this
  • After= units which should be started before this
  • Conflicts= units that can't run when this run
  • Condition...= conditions on which unit will be run, if not met it will be skipped
  • Assert...= as a condition but will cause failure instead of skipping

Directives in [Install] section

[Install] section used to define behavior when service enabled or disabled.

WantedBy= - similar to Wants= in [Unit] section but related to called instead of caller: If current unit has WantedBy=multi-user.target, the directory multi-user.target.wants will be created in /etc/systemd/system (if not already available) and symlink to current unit will be created in that dir when unit is enabled.

  • This way it works.
  • RequiredBy= similar to previous but will cause a fail if conditions not met. CreaAlias=te directory which ends with .requires
  • Alias= allows the unit to be enabled under another name as well
  • Also= Supporting units that should always be available when this unit is active
  • DefaultInstance= For template units (covered later) which can produce unit instances with unpredictable names, this can be used as a fallback value for the name if an appropriate name is not provided.

Directives in [Service] section

Section available only for .servicees. Should provide Type= which tells systemd how to:

1. Call service process

2. Find out its state

Types:

  • simple (default if Type= not set but ExecStart= is set)
  • forking - tels that main process can fork child and exit immediately. PIDFile= is used to set the path of the file with PID number of the main child that should be monitored.
  • oneshot - process will short lived and systemd should wait. Default when both Type= and ExecStart= not set. To leave service in active state set even after process finished use RemainAfterExit=
  • also there are other types.

starting process in service

  • ExecStart= full path and args to command. To ignore non-zero exit codes use - ad first character in command
  • ExecStartPre= same as previous but will be run before command
  • ExecStartPost= will be run after main process started
  • ExecReload= command that should used for reload if needed
  • ExecStop= custom stop command. If not set process will be killed
  • ExecStopPost= command to run after stop. Values: always, on-success, on-failure, on-abnormal, on-abort, or on-watchdog.
  • Restart= circumstances under which systemd will attempt to restart
  • RestartSec= specifies wait timeout before restart using previous setting
  • TimeoutSec= - how many systemd will wait for starting/stopping. If was not started will be marking failed, if not stopped will be forcefully killed. Separate timeout can be set as well: TimeoutStartSec= and TimeoutStopSec=

Template units

Example of such unit: [email protected]

Instantiation of unit: [email protected]

An instance file is usually created as a symbolic link to the template file, with the link name including the instance identifier.

In the template it's possible to use variables:

  • %i - instance name, e.g. instance1
  • %I - same as above but with reversed escaping

Also

  • systemctl show unitFile - shows info about unit file
  • systemctl start service.service - start service
  • systemctl enable service.service - enable service (boot on start-up)
  • systemctl start [email protected] - enable service instance (e.g. here openvpn tun1 instance)