An init system is the system used to start and stop a system, and to manage the services it offers. It can handle other functions, as well (e.g., management of logins, devices, and network connections). In the past, the System V init system was prevalent. Now, GNU/Linux systems usually use systemd.
Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.
systemd
The systemd daemon is located at /lib/systemd/systemd
. /sbin/init
points to this daemon.
In the systemd init system, a service is a program that runs as a background process.
Explicit Versus Implicit Dependencies
System V init used explicit dependencies to describe the relationship between services, while systemd uses implicit dependencies. For example, in systemd, a service requiring the system log service does not wait to send messages to the system log until the system log service is running because the system log service needs to be running, but because it wants to send messages to the system log itself.
The service that wants to send messages to the system log must access the communication channel that the system log service provides. It is sufficient if systemd itself creates this communication channel and passes it to the system log service once it becomes available. The service that wants to send messages to the system log service will wait until its messages are capable of being received before sending them.
systemd has the capability to create all communication channels first, and then simultaneously start all services, without regard to any dependencies. The dependencies will sort themselves out without an explicit configuration, i.e., implicit dependencies.
Also, this approach works with systems that are already running. If a service is accessed that is not currently running, systemd can start it on-demand. The same approach can also work for file systems, i.e., if a service wants to open a file on a file system that is currently unavailable, the service is suspended until the file system can be accessed.
Units and Targets
System V init used init scripts as a representation of parts of the system to be managed (e.g., services, communication channels, devices). The systemd equivalent is units.
System V init used runlevels to collect related services and define a system state. The systemd equivalent is targets.
systemd Properties
systemd has unique properties:
- It supports on-demand service activation, not just for hardware dependence, but also via network connections, Desktop Bus (D-Bus) requests, and the availability of specific paths within a file system.
- It supports fine-grained control of services it launches (e.g., concerning the process environment, resource limits). This includes security enhancements (e.g., providing a limited view of the file system for certain services, or providing services with a private
/tmp
directory or networking environment). - It uses the Linux kernel's cgroups mechanism to ensure that stopping a service stops all related processes.
- It can be configured to handle services' logging output (the service only needs to be able to write to the standard output).
- It makes configuration maintenance easier by cleanly separating GNU/Linux distribution default and local customizations.
- It contains a number of tools built in C that handle system initialization and the tasks that System V init scripts would do. Often, this speeds up the boot process and improves cross-distribution standardization.
systemd is designed to be backwards compatible with System V init. For example, if no native configuration file is available for a service, systemd supports the init scripts of System V init. Also, it takes the file systems to be mounted on startup from the /etc/fstab
file.
Jobs and Transactions
systemd calls system state change requests jobs and puts them into a queue. systemd calls status change requests transactions.
If a unit is being started or stopped, it (and any units depending on it) is put into a temporary transaction. Then, systemd checks that the transaction is consistent (specifically, that no circular dependencies exist). If this is the case, systemd tries to repair the transaction by removing non-essential jobs (including those that lead to running services being stopped) in order to break the cycle.
Next, systemd checks if the jobs within the transaction conflict with other jobs that are already in the queue. If that is the case, the transaction is refused. Only if the transaction is consistent and the minimization of its impact on the system is complete, will the transaction proceed and its associated jobs be entered into the queue.
Unit Files
systemd uses a unified file format for its unit files. Only the details of the possible configuration settings differ. The basic file format is always the same.
systemd unit files are declarative, i.e., they describe what the desired configuration looks like, unlike System V init's init scripts, which contain executable code that tries to implement the desired configuration. Unit files may contain shell commands (e.g., to describe how a service should be started/stopped), but these are fairly self-explanatory.
Unit files are stored in three locations:
/lib/systemd/system
or/usr/lib/systemd/system
The default unit files for distribution packages. These unit files have the lowest priority./run/systemd/system
The dynamically generated runtime unit files./etc/systemd/system
The local configuration system administrator units. These unit files have the highest priority.
Unit File Structure
You can view the outline for the basic syntax of a unit file by running man 5 systemd.unit
.
Here is a sample unit file:
## This file is part of systemd.
#
## systemd is free software; you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as
## published by the Free Software Foundation; either version 2.1
## of the License, or (at your option) any later version.
[Unit]
Description=Console Getty
Documentation=man:agetty(8)
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
Before=getty.target
[Service]
ExecStart=-/sbin/agetty --noclear --keep-baud console
115200,38400,9600 $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=cons
TTYPath=/dev/console
TTYReset=yes
TTYVHangup=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes
[Install]
WantedBy=getty.target
A systemd unit file is generally subdivided into sections that start with a title in square brackets ([]
), e.g., [Service]
. All unit files include [Unit]
and [Install]
sections (some until files may not directly have an [Install]
section, but are tied to a unit file that does). The [Unit]
section contains general information about the unit, and the [Install]
section provides details for its installation. Also, there are sections that are specific to the purpose of the unit.
These are some of the important directives that are used in the [Unit]
section of a unit file:
Description=
- A human readable name for the unit. This is used by systemd as the label for the unit, so the string should identify the unit, rather than describe it. This name will be used in status messages, so it should be capitalized and should not be a full sentence or phrase with a continuous verb.
ConditionPathExists=
- Before starting a unit, verify that the specified condition is true. Checks whether there is a file (or directory) under the given absolute pathname. If not, the starting of the unit will be (mostly silently) skipped. However, all ordering dependencies of it are still respected. If there is a
!
in front of the pathname, then a file (or directory) with that name must not exist. There are many other condition tests. Runman 5 systemd.unit
for more information. Documentation=
- A space-separated list of URIs containing documentation for the unit or its configuration. The allowed protocol schemes include
http:
,https:
,file:
,info:
, andman:
(the latter three refer to locally-installed documentation). An empty value resets the list and all prior assignments will have no effect. OnFailure=
- A space-separated list of other units that will be activated if this unit transitions into the
failed
state. A service unit usingRestart=
enters the failed state only after the start limits are reached. SourcePath=
- The pathname of a configuration file from which this unit file has been generated. This is useful for tools that create unit files for systemd from external configuration files.
Blank lines and comment lines are ignored. Comment lines can start with a #
or ;
. Over-long lines can be broken up with a \
at the end of the line, which will be replaced by a space character when the file is read. File contents are case-sensitive.
Lines that are not section headers, empty lines, or comment lines contain options according to a ex_name=ex_value
pattern. Various options may occur several times and systemd's handling of that depends on the option. Often, multiple options form a list. If you specify an empty value, all earlier settings will be ignored.
Options that are not listed in the documentation will be flagged with a warning by systemd and otherwise ignored. If a section or option name starts with X-
, it is completely ignored (options in a X-
section do not need their own X-
prefix).
Yes/no settings in unit files can be given in a variety of ways. 1
, true
, yes
, and on
stand for yes. 0
, false
, no
, and off
stand for no.
Times can be specified in various ways, too. Simple integers will be interpreted as seconds. If you append a unit, then that unit applies. Allowed units include us
, ms
, s
, min
, h
, d
, and w
in increasing sequence from microseconds to weeks (run man 7 systemd.time
for more information). You can concatenate several time specifications (e.g., 10min 30s
) and these times will be added.
Unit Types
The following until types are available in systemd:
.automount
- An automount point for a file system. This declares that a mount point should be mounted on-demand, instead of when the system is booted. The names of these units result from a pathname transformation. The details of mounting must be described by a corresponding
mount
unit. .device
- A device file used by the kernel.
.mount
- A mount point for a file system. The names of these units are derived from the pathname by means of replacing all forward slashes (
/
) with hyphens (-
), and all other non-alphanumeric (as per ASCII) characters with a hexadecimal replacement, e.g.,\x2d
(the.
character is only converted if it is the first character of a pathname). The name of the root directory (/
) becomes-
, but forward slashes at the start or end of all other names are removed. You can use thesystemd-escape -p ex_object_path
command to generate such a string (e.g.,systemd-escape -p /dev/sdb
) and thesystemd-escape -pu ex_object_path
command to revert it. .path
- Observes a file or directory on a file system, and starts another unit (by default, a
.service
unit of the same name) when, for example, changes to the file have been noticed, or a file has been added to an empty directory. .scope
- An externally created process.
.service
- A process on the system that is executed and managed by systemd. This includes both background services that stay active for a long time, and processes that are only executed once. When a service is invoked by name, but no corresponding unit file can be found, systemd looks for a System V init script with the same name and generates a service unit for that service on-the-fly.
.slice
- A grouping of units in a hierarchy.
.slice
units are used to manage system processes. .snapshot
- A saved instance of the state of the systemd manager.
.socket
- A TCP/IP, UNIX Domain, or First In, First Out (FIFO) socket. systemd uses socket units to activate background services on-demand. Socket units always come with a corresponding
.service
unit that will be started when systemd notes activity on the socket in question. .swap
- A swap file or swap device. The names of these units result from a pathname transformation applied to the device file or filename in question.
.target
- A target, or synchronization point, for other units during system boot or when transitioning into other system states. A grouping of units.
.timer
- A unit that starts another unit (by default, a
.service
unit of the same name) at a certain point in time, or repeatedly at certain intervals. This makes systemd a replacement forcron
andat
.
Specifying Explicit Dependencies With Unit Files
Sometimes, it is necessary to specify explicit dependencies.
Various directives in the [Unit]
section of a .service
unit file allow you to do this. These include:
Requires=
- Configures requirement dependencies on other units. If the current unit is activated, then the listed units are also activated. If one of the listed units is deactivated or its activation fails, then the current unit will also be deactivated (i.e., the current unit depends on the listed units).
- The
Requires=
dependencies have nothing to do with the order in which the units are started or stopped. That can be separately configured with theAfter=
orBefore=
directives. If no explicit order has been specified, systemd will start all units at the same time. - You can specify
Requires=
dependencies without changing a unit file. For example, you can create a directory called/etc/systemd/system/example.service.requires
and add symbolic links to the desired unit files thatexample.service
requires. $ ls -l /etc/systemd/system/example.service.requires lrwxrwxrwx 1 root root 34 Jul 17 15:56 network.target -> /lib/systemd/system/network.target lrwxrwxrwx 1 root root 34 Jul 17 15:57 syslog.service -> /lib/systemd/system/syslog.service
-
The symbolic links above correspond to the following lines in the
example.service
unit file.
[Unit]
Requires=network.target syslog.service
Wants=
- A weaker form of
Requires=
. This means that the listed units will be started together with the current unit, but if their activation fails, this has no influence on the process as a whole. This is the recommended method of making the start of one unit depend on the start of another unit. - With
Wants=
, you can also externally specify the dependencies by creating a directory, as demonstrated for theRequires=
directive, e.g. (/etc/systemd/system/example.service.wants
). Conflicts=
- A space-separated list of unit names. The reverse of
Requires=
. The units listed here will be stopped when the current unit is started, and vice versa. - Like the
Requires=
directive, theConflicts=
directive makes no stipulation as to the order in which units are started or stopped. - If a unit
A
conflicts with another unitB
, and both are to be started at the same time, this operation fails if both units are an essential part of the operation. If one (or both) units are not essential parts of the operation, the operation is modified. Specifically, if only one unit is non-essential, that one will not be started. If both are non-essential, the unit mentioned inConflicts=
will be started and the unit whose unit file contains theConflicts=
directive will be stopped. Before=
andAfter=
- These two settings expect a space-separated list of unit names. They configure ordering dependencies between units.
- If
example.service
's unit file contains theBefore=example_2.service
option and both units are being started, the start ofexample_2.service
will be delayed untilexample.service
has been started. After=
is the inverse ofBefore=
, i.e., ifexample_2.service
's unit file contains the optionAfter=example.service
and both units are being started, the same effect results, i.e., the starting ofexample_2.service
will be delayed untilexample.service
has been started.- When deactivating units, the reverse order is observed. If a unit with a
Before=
orAfter=
dependency on another unit is deactivated, while the other unit is being started, then the deactivation takes place before the activation, no matter which direction the dependency is pointing.
Unit File Customization
You can customize unit file-related settings without modifying the default unit files provided by your GNU/Linux distribution in /lib/systemd/system
. For example, if you want to change some of the settings in an example.service
unit file, you could do one of the following:
- Copy your distribution's
example.service
file from/lib/systemd/system
to/etc/systemd/system
and make your desired customizations. This new unit file will override the one provided by your distribution in/lib/systemd/system
. -
Create a
/etc/systemd/system/example.service.d
directory containing a file, e.g.,local.conf
(the file can have a different name, but systemd requires that it end in.conf
). The settings inlocal.conf
will override the settings of the unit file with the same name in/lib/systemd/system
(i.e.,/lib/systemd/system/example.service
).Settings listed in the
/lib/systemd/system/example.service
file, but not mentioned in/etc/systemd/system/example.service.d/local.conf
, remain the same. Make sure to include any required section titles in/etc/systemd/system/example.service.d/local.conf
, so that options are correctly identified. systemd makes no stipulation about the order in which.conf
files are read. It is best to ensure that every option occurs in just a single file.
Sometimes, several services can use the same or a similar unit file, but it is best to avoid redundant unit files. To address this, systemd supports instantiation.
For example, if you have a unit file called getty@.service
, you could configure a virtual console on /dev/tty2
by creating a symbolic link from getty@tty2.service
to getty@.service
. When this console is activated, systemd reads the getty@.service
file and replaces the %I
key (as well as some other sequences, and not just in template unit files) wherever it finds it, by whatever comes between @
and .
in the name of the getty@tty2.service
unit file (i.e., tty2
). The result of that replacement is then put into force as the configuration.
Targets
systemd does away with the System V init concept of runlevels and replaces them with targets. Targets are synchronization points for other units during system boot or when transitioning into other system states. Essentially, it is a grouping of units (set of services).
While System V init allows only a relatively small number of runlevels and their configuration may be complicated, systemd makes it possible to easily define various targets. Unit files for targets do not have special options. The standard set of options for [Unit]
and [Install]
are sufficient.
These are common targets for systemd:
basic.target
- Basic system startup is finished (i.e., the early boot stage is complete).
ctrl-alt-del.target
- Executed when Control+Alt+Delete is pressed. Often, the same as
reboot.target
. default.target
- Target that systemd attempts to reach on system startup. Usually, the default target is either
multi-user.target
orgraphical.target
. emergency.target
- Starts a shell on the system console, for emergencies. Often, this is activated by means of the
systemd.unit=emergency.target
parameter on the kernel command line. This gives you nothing except for a shell, in contrast torescue.target
, which also does basic system initialization. getty.target
- Activates the statically-defined getty instances (for managing terminals). Corresponds to the
getty
lines in the/etc/inittab
file on System V init. graphical.target
- Establishes a graphical login prompt. Depends on
multi-user.target
. halt.target
- Stops the system (without powering it down).
multi-user.target
- Establishes a multi-user system without a graphical login prompt. Used by
graphical.target
. network-online.target
- Serves as a dependency for units that require network services (not ones that provide network services), e.g., mount units for remote file systems. How exactly the system determines whether the network is available or not depends on the method for network configuration.
poweroff.target
- Stops the system and powers it down.
reboot.target
- Restarts the system.
rescue.target
- Performs basic system initialization and then starts a shell.
For backwards compatibility with System V init, systemd defines a number of targets that correspond to the classical runlevels. Each of these runlevels has a corresponding runlevel.target
unit file (e.g., runlevel0.target
) that is a symbolic link to the actual systemd target unit file (e.g., poweroff.target
).
System V init Runlevel | systemd Target | Comparable Symbolic Link Target |
---|---|---|
0 |
poweroff.target |
runlevel0.target |
1 |
rescue.target |
runlevel1.target |
2 |
multi-user.target |
runlevel2.target |
3 |
multi-user.target |
runlevel3.target |
4 |
multi-user.target |
runlevel4.target |
5 |
graphical.target |
runlevel5.target |
6 |
reboot.target |
runlevel6.target |
systemctl
The systemctl
command is used to control systemd. The general format of the command is:
systemctl ex_subcommand ex_parameters
systemctl
has useful options. For example, --failed
(or --state=failed
) can be used to view all failed units.
Often, unit names are expected as parameters. These can be specified either with a filename extension (example.service
) or without (example
). In the latter case, systemd appends an extension that it considers appropriate.
There are many subcommands, and each subcommand has different parameters and options. These are some of the most useful systemctl
subcommands.
Unit Commands
systemctl list-units
- List units that systemd currently has in memory. By default, only units that are active, have pending jobs, or have failed are shown. This can be changed with the
--all
option. - You can specify a unit type with the
-t
(--type=
) option (e.g.,systemctl list-units -t target
, which is similar to therunlevel
orwho -r
commands). You can use a comma-separated list of unit types with this option, as well (e.g.,systemctl list-units -t service,socket
). - Shell search patterns are accepted.
systemctl list-sockets
- List socket units currently in memory, ordered by the listening address.
- Shell search patterns are accepted.
systemctl list-timers
- List timer units currently in memory, ordered by the time they elapse next.
- Shell search patterns are accepted.
# systemctl start ex_unit...
- Start a unit.
- Shell search patterns are accepted. The search patterns only work for units that systemd knows about. Inactive units that are not in a failed stated will not be searched, nor will units instantiated from templates whose exact names are not known before the instantiation.
# systemctl stop ex_unit
- Stop a unit(s).
- Shell search patterns are accepted.
# systemctl reload ex_unit...
- Reload a unit.
- This command causes a unit to re-read its service-specific configuration file. What actually happens depends on the unit in question (usually, it involves a
SIGHUP
command). You can configure this behavior in the unit file itself. - The configuration here is of the background services themselves, not the configuration of the services from systemd's point-of-view. If you want systemd to reload its own configuration file with respect to the service(s), you must use the
# systemctl daemon-reload
command. - Shell search patterns are accepted.
# systemctl restart ex_unit...
- Stop and then start a unit. If
ex_unit
is not already running, it is just started. - Shell search patterns are accepted.
# systemctl try-restart ex_unit...
- Stop and then start a unit if the unit is running.
- Shell search patterns are accepted.
# systemctl reload-or-restart ex_unit...
- Reload a unit, if it allows it. Otherwise, stop and then start it.
- Shell search patterns are accepted.
# systemctl try-reload-or-restart ex_unit...
- Reload a unit if it allows it. Otherwise, stop and then start it, but do not start it if it is not already running.
- Shell search patterns are accepted.
# systemctl isolate example.target
- Start the unit specified on the command line and its dependencies and stop all others, unless they have
IgnoreOnIsolate=yes
set. This is similar to changing the runlevel on a System V init system. # systemctl kill ex_unit...
- Kill a unit.
systemctl kill
sends a signal to one or several processes of the unit. This is distinct, and more specific, than using commands likekillall
andpkill
. To make the command more granular, you can use the--kill-who=
option to specify which process of a unit is targeted (accepted values includemain
,control
, andall
;all
is the default option).- You can specify which signal
systemctl kill
sends by using the--signal=
option. - Shell search patterns are accepted.
systemctl status
- Show system status.
- You can pass
systemctl status
a specific unit(s) or PID(s) as an argument to only see the status of that unit(s) or PID(s), as well as its most recent log entries. The log excerpt is usually abridged to 10 lines and long lines will be shortened. This can be changed by using the--lines
or--full
options. - Shell search patterns are accepted.
systemctl cat ex_unit...
- Display the backing file(s) for a unit, including fragments in configuration directories specifically for that unit (e.g.,
/etc/systemd/system/example.service.d
). Comments with the filenames in question are inserted for clarity in the command's output. - Shell search patterns are accepted.
systemctl help ex_unit...
- Display manual pages for a unit.
ex_unit
can be a unit name or a process ID (PID). - Shell search patterns are accepted.
Unit File Commands
systemctl list-unit-files
- View all available unit files on the system, as well as their enablement state.
- Each background service available in systemd needs a corresponding
.service
until file (e.g.,example.service
), and this file needs to be placed in the appropriate location (e.g.,/etc/systemd/system
). Then, it should appear when you runsystemctl list-unit-files
. By default, a newly installed service will be disabled, which means that the unit is available, but not automatically started when the system boots. - Shell search patterns are accepted as arguments to have
systemctl list-unit-files
only show units that match the specified pattern. # systemctl enable ex_unit...
- Enable a unit.
ex_unit
can be a unit name or unit path. - Enabling a unit means that it will automatically start at boot time. After an enable, systemd does the equivalent of a
# systemctl daemon-reload
. If you want the service to be immediately started, as well, you can add the--now
option to this command. systemctl enable
creates a symbolic link from the target unit'swants
directory that is specified inexample.service
's[Install]
section (e.g.,/etc/systemd/system/multi-user.target.wants/example.service
) toexample.service
's unit file (e.g.,/etc/systemd/system/example.service
).# systemctl enable example.service Created symlink from /etc/systemd/system/multi-user.target.wants/example.service to /etc/systemd/system/example.service
-
The
/etc/systemd/system/example.service
file has a section stating the following: [Install] WantedBy=multi-user.target
-
A service can be started without first being enabled.
# systemctl disable ex_unit...
- Disable a unit.
- Disabling a unit means that it will not automatically start at boot time. After a disable, systemd does the equivalent of a
# systemctl daemon-reload
. Ifex_unit
is currently running, it will not be stopped by this command. However, you can immediately stop it by adding the--now
option. # systemctl reenable ex_unit...
- Re-enable a unit. This command is equivalent to disabling and enabling the unit in question. It is useful to reset the symbolic links a unit file is enabled with to the defaults configured in its
[Install]
section. # systemctl mask ex_unit...
- Mask a unit. This is a stronger version of the
disable
subcommand, since it prohibits all kinds of activation of the unit. - systemd accomplishes this by symbolically linking the name of the unit file in
/etc/systemd/system
to/dev/null
. Therefore, if you need to mask a unit, first remove, move, or rename the unit file in question in/etc/systemd/system
, so that systemd can create the appropriate symbolic link. # sytemctl unmask ex_unit...
- Unmask a unit.
systemctl get-default
- Display the default systemd target. This returns the target unit name
default.target
is aliased (symbolically linked) to. # systemctl set-default example.target
- Set the default target to boot into.
- This command works by creating a symbolic link from
/etc/systemd/system/default.target
to/lib/systemd/system/example.target
(e.g.,# ln -fs /lib/systemd/system/example.target /etc/systemd/system/default.target
; the-f
(--force
) option removes the existing destination file). This is equivalent to theinitdefault
line in the/etc/inittab
file in a System V init system.
Manager Lifecycle Commands
# systemctl daemon-reload
- Reload systemd manager configuration.
- This command causes systemd to reload its configuration, which includes regenerating unit files that have been created at runtime from other configuration files on the system, and reconstructing the dependency tree. This command is implicitly run when you enable or disable a unit.
# systemctl daemon-reexec
- Re-execute the systemd manager.
- This command restarts the systemd program, which saves systemd's internal state and restores it later. Mostly, this is useful if a new version of systemd has been installed (or for debugging systemd). Communication channels that systemd manages on behalf of background services will persist across the restart.
System Commands
systemctl is-system-running
- Checks whether the system is operational.
- Possible answers include:
-
degraded
The system is operational, but one or more units are in a failed state.initializing
Early bootup (thebasic.target
,rescue.target
, oremergency.target
targets have not yet been reached).maintenance
One of therescue.target
oremergency.target
targets is active.offline
The manager is not running. Specifically, this is the operational state if an incompatible program is running system manager (PID1
).running
The system is fully operational.starting
Late bootup (there are still jobs in the queue or one of the rescue targets has not been reached yet).stopping
The manager is shutting down.unknown
The operational state could not be determined due to lack of resources or another error cause.
# systemctl default
- Enter default mode. Equivalent to
# systemctl isolate default.target
. # systemctl rescue
- Enter rescue mode. Equivalent to
# systemctl isolate rescue.target
. # systemctl emergency
- Enter emergency mode. Equivalent to
# systemctl isolate emergency.target
. # systemctl halt
- Shut down and halt the system. Mostly equivalent to
# systemctl start halt.target --job-mode=replace-irreversibly --no-block
, but also prints a wall message to all users. # systemctl poweroff
- Shut down and power-off the system. Mostly equivalent to
# systemctl start poweroff.target --job-mode=replace-irreversibly --no-block
, but also prints a wall message to all users. # systemctl reboot
- Shut down and reboot the system. Mostly equivalent to
# systemctl start reboot.target --job-mode=replace-irreversibly --no-block
, but also prints a wall message to all users.
systemd-analyze
The systemd-analyze
command can be used to analyze and debug the systemd system manager.
systemd-analyze
- Display performance stats regarding system boot, view trace and current state information.
systemd-analyze blame
- Display how long each process took to start.
systemd-analyze
has many useful subcommands, as well. Run man systemd-analyze
for more information.
Documentation
For more information on systemd, you can refer to its various man pages by running these commands:
man 1 systemd
man 5 systemd-system.conf
man 5 systemd.unit
man 7 systemd.directives
man 7 systemd.time
man 1 systemctl
man 1 systemd-analyze
Also, you can check out the systemd.io site from the systemd project.
System V init (SysV init)
Most GNU/Linux distributions use systemd as their initialization system. However, not all members of the GNU/Linux community like systemd and there are distributions that have retained System V init (SysV init) as their initialization system of choice. Also, it is advantageous to understand how SysV init works, either for backwards-compatibility, or in case you encounter a SysV init GNU/Linux distribution.
As in systemd, a service is a program that runs as a background process. Runlevels describe the system's state and the services that it offers.
The init Process
Exactly how SysV init is implemented will depend on your GNU/Linux distribution of choice.
Debian
The Debian SysV init process was as follows:
- A boot script (e.g.,
/etc/init.d/rcS
) was run to prepare the system. - The
/etc/inittab
file was processed to determine the appropriate runlevel and scripts. - Scripts in
/etc/init.d
were run from symbolic links in the appropriate runlevel directories in the/etc
directory (i.e., the/etc/rcx.d
directories).
Fedora
The Fedora SysV init process was as follows:
- A boot script (e.g.,
/etc/rc.d/init.d/boot
) was run to prepare the system. - The
/etc/inittab
file was processed to determine the appropriate runlevel and scripts. - Scripts in
/etc/rc.d/init.d
were run from symbolic links in the appropriate runlevel directories in the/etc/rc.d
directory (i.e., the/etc/rc.d/rcx.d
directories).
/etc/inittab
The /etc/inittab
file is used to configure what happens in each runlevel. Each line that is either not empty or a comment (i.e., a line that starts with a #
) consists of four fields separated by colons. For example:
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
#l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
The four fields are:
- Label
- Runlevels
- Action
- Command
- Label
- The first field's purpose is to uniquely identify the line. You may pick an arbitrary combination of up to four characters. It is probably best to use only letters and digits. For terminals, the label corresponds to the name of the device file in question, but without the
tty
at the beginning. - Runlevels
- The second field specifies the runlevels this line applies to. Usually, they are named with digits, and the line in question will be considered in all runlevels whose digit appears in this field.
- Action
- The third field specifies how to handle the line. The most important possibilities include:
-
ctrlaltdel
Specifies what the system should do if the init process is being sent aSIGINT
signal, which usually happens if the Control+Alt+Delete keyboard combination is pressed (e.g.,ca::ctrlaltdel:/sbin/shutdown -r -t 4 now
).initdefault
The runlevel field of this line specifies which runlevel the system should try for after each boot (e.g.,id:5:initdefault:
). If this entry, or the whole/etc/inittab
file is missing, you will need to state a run level on the console.powerwait
,powerfail
,powerokwait
, andpowerfailnow
are used to interface SysV init with uninterruptible power supplies (UPSs) and define what should happen when a power failure occurs.respawn
The process described by this line is executed once when the system changes to the runlevel in question, andinit
waits for it to finish.wait
The process described by this line is executed once during system startup.init
waits for it to finish. The runlevel field on this line will be ignored, since this command will be executed at every system startup.
# What to do when power fails or returns
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
#pn::powerfail:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
- Command
- The fourth field describes the command to be executed. It extends to the end of the line.
/etc/inittab
tells init
which runlevel login processes are started at login to prompt the user to enter a username and password:
1:2345:respawn:/sbin/mingetty --noclear tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
If you make a change to /etc/inittab
, you need to tell init
that the changes have been made and to re-read the configuration by entering the # telinit q
command.
The init Scripts
The system processes on the GNU/Linux system are started and stopped using an init script. An init script is used by the init
process to start processes on system boot and whenever the current runlevel is changed. init scripts support parameters like:
start
stop
restart
reload
status
Debian init Scripts
For a Debian init system, init scripts were stored in /etc/init.d
. Inside of the /etc
directory, there were a series of directories named rc0.d
through rc6.d
that were each associated with a particular runlevel (rc
is short for runcom
, which means run commands
). These rc
directories contained symbolic links that pointed to the init scripts for system daemons that were located in /etc/init.d
.
A boot script (usually /etc/init.d/rcS
, but whose exact name was specified in /etc/inittab
) performed tasks like:
- Checking and correcting file systems specified in
/etc/fstab
- Initializing the system name and Linux clock
- Completing important prerequisites for stable system operation
The /etc/init.d/rc
script was used to switch between runlevels while the system was running. This was the script that the telinit
command called to change runlevels.
Fedora init Scripts
For a Fedora init system, init scripts were stored in /etc/rc.d/init.d
. Inside of the /etc/rc.d
directory, there were a series of directories named rc0.d
through rc6.d
that were each associated with a particular runlevel. These rc
directories contained symbolic links that pointed to the init scripts for system daemons that were located in /etc/rc.d/init.d
.
A boot script (usually /etc/rc.d/init.d/boot
, but whose exact name should was specified in /etc/inittab
) performed tasks like:
- Checking and correcting file systems specified in
/etc/fstab
- Initializing the system name and Linux clock
- Completing important prerequisites for stable system operation
The /etc/rc.d/init.d/rc
script was used to switch between runlevels while the system was running. This was the script that the telinit
command called to change runlevels.
The rcx.d Directories
If you look inside of an rcx.d
directory (where x
is a number corresponding to a runlevel), there will be see two symbolic links for each system process. One symbolic link starts with a S
, and the other starts with a K
. The symbolic links that start with a S
are used to start a service, while the symbolic links that start with a K
are used to stop (kill) a service.
When the init
process calls the rc
script and sends it a runlevel to change to, the rc
script runs all of init.d
scripts in lexicographical order from the symbolic links in the corresponding rcx.d
directory to start and stop services as appropriate for the runlevel being entered. These are the scripts employed when switching between runlevels on-the-fly.
The S
or K
letter is followed by a number and the name of the init script. The numbers in filenames are important, as they determine the sequence in which the scripts are run. This ensures that services that other services depend on are started first.
When init
calls the rc
script to switch runlevels, the rc
script first looks at the rcx.d
directory for the current runlevel and compares it with the rcx.d
directory for the runlevel it is going to switch the system to. If there is a kill symbolic link for the already running service in the rcx.d
directory for the current runlevel and a start symbolic link for the same service in the rcx.d
directory for the new runlevel, the rc
script leaves the service running because it should be running in both runlevels.
On the other hand, if there is a kill symbolic link for the service in the rcx.d
directory for the current runlevel, but there is no start symbolic link for the same service in the rcx.d
directory for the new runlevel, the rc
script runs the kill script to stop the service. Conversely, if there is a start symbolic link for the service in the rcx.d
directory for the new runlevel and there is no start symbolic link for the same service in the rcx.d
directory for the current runlevel, the rc
script runs the start script to start the service.
Runlevels
Runlevels describe the system's state and the services that it offers.
The SysV init runlevels are:
0
- System poweroff.
1
- Single-user mode with no networking. Also referred to as runlevel
S
orsingle
. 2
- Multi-user mode with no networking.
3
- Multi-user mode with networking.
4
- Unused. May be individually configured if required.
5
- Same as runlevel 3, but with graphical user interface (GUI) login.
6
- System reboot.
These runlevels derive from the Linux Standard Base (LSB), but not all GNU/Linux distributions enforce them. You can use runlevels 7
through 9
, but you will need to configure them yourself.
Also, there are on-demand runlevels A
, B
, and C
. You can create entries in /etc/inittab
that are meant for any of these three runlevels with the ondemand action:
ex_label:AB:ondemand:ex_code
Then, when you issue a command line # telinit A
, the entry above will be executed, but the actual runlevel will not change.
The system runs through the S
runlevel during startup, before it changes over to runlevels 2
through 5
. If you put the system into runlevel 1
, you will end up in runlevel 5
(if you are using a GUI-based system).
In single-user mode (i.e., runlevel S
/single
/1
), only the system administrator may work on the system console. There is no way to change to other virtual consoles. The single-user mode is normally used for administrative work, especially if the file system needs to be repaired or the quota system established.
By default, passing the S
option to the kernel on the command line will mount the root file system as read-only on booting. After switching to single-user mode after a system boots up, you can also disable writing to the root file system on-the-fly using the remount
and ro
mount options (e.g., mount -o remount,ro /
).
To remount a file system as read-only while the system is running, no process may have opened a file on the file system for writing (you can use the lsof
command to display open files on a file system). All such programs must be terminated using the kill
command.
To leave single-user mode, it is best to reboot the system (# reboot
or # shutdown -r now
).
runlevel
Both the current and previous runlevel of a system can be determined with the runlevel
command. A N
for the previous runlevel means that the current runlevel was entered right after the system start (the N
stands for None
).
$ runlevel
N 5
The who -r
command will display the current runlevel, as well.
$ who -r
run-level 5 2020-08-20 08:10
telinit
The telinit
command changes the System V runlevel.
# telinit ex_runlevel
When you change runlevels, the init
process runs the rc
script, which shuts down services associated with the current runlevel and starts scripts associated with the runlevel you are changing to.
System V init Commands
There are other commands that can be used to interact with SysV init.
Parameters
As previously mentioned, init scripts accept several parameters (e.g., start
, stop
). The exact path to each script will depend on the GNU/Linux distribution that you are using.
# /etc/init.d/ex_script start
or# /etc/rc.d/init.d/ex_script start
- Start an init script.
# /etc/init.d/ex_script stop
or# /etc/rc.d/init.d/ex_script stop
- Stop an init script.
# /etc/init.d/ex_script restart
or# /etc/rc.d/init.d/ex_script restart
- Restart an init script. Restarting a service stops and restarts it.
# /etc/init.d/ex_script reload
or# /etc/rc.d/init.d/ex_script reload
- Reload an init script. Reloading a service leaves it running, but has it re-read its configuration file.
/etc/init.d/ex_script status
or/etc/rc.d/init.d/ex_script status
- Display the status of an init script service.
service
Interacting with services via init scripts and parameters is basic. On a modern SysV init system, it is preferable to use the service
command instead.
service ex_script_name ex_command
ex_command
can be any of the previously mentioned init script parameters start
, stop
, restart
, reload
, and status
.
update-rc.d (Debian)
GNU/Linux distributions like Debian use the update-rc.d
command to install and remove init script links. The command reads the information in the INIT INFO
block of an init script to determine which runlevels the associated service should run in by default.
# update-rc.d ex_script_name enable
- Enable and start a service.
- This command enables the daemon specified at the runlevels listed in the
Default-Start
directive of theINIT INFO
block of the service’s init script. It also disables the daemon at the runlevels listed in theDefault-Stop
directive of theINIT INFO
block. # update-rc.d ex_script_name disable
- Disable and stop a service.
# update-rc.d ex_script_name start ex_priority_number ex_runlevels . stop ex_priority_number ex_runlevels .
- Change the default runlevels for a service (e.g.,
# update-rc.d apache2 start 20 2 3 4 5 . stop 80 0 1 6 .
). This command re-creates the appropriate start and kill script symbolic links in the variousrcx.d
directories saved in/etc
.
chkconfig (Fedora)
GNU/Linux distributions like Fedora use the chkconfig
command to update and query runlevel information for system services.
chkconfig
orchkconfig -l
- List each service and what runlevel they are configured to run at.
-l
is short for--list
. The-l
option can be passed the name of a specific script (service) to list only that service's current runlevel. # chkconfig ex_script_name on
- Enable and start a service.
# chkconfig ex_script_name off
- Disable and stop a service.
# chkconfig --level ex_runlevels ex_script_name
- Change the default runlevels for a service (e.g.,
# chkconfig --level 35 iptables on
and# chkconfig --level 01246 iptables off
).ex_runlevels
is given as a string of numbers from0
to6
. For example,--level 35
specifies runlevels3
and5
.
Documentation
More information can be found on the commands discussed above by examining the Linux User's Manual, either at the command line or online.
For more on SysV init, its history, and how it fits into the world of GNU/Linux system initialization, check out the following posts:
Why Linux’s systemd Is Still Divisive After All These Years | How-To Geek