contact@embeddedgeeks.com
Embedded World

All About Systemd-init

systemd 

systemd is the first daemon started by the system, similar to a big housekeeper, it provides a fairly complete service for system startup and management. The traditional Liunx distribution (CentOS5 / CentOS6) uses the init process as the system’s startup process. Its disadvantage is that it takes a long time to start (serial startup, the previous process can be started after the previous process is started) and the startup script is complicated systemd solves these problems. The schematic diagram of systemd is as follows:

systemd command

systemd is the sum of a set of commands, the common commands are listed first:

System ManagementsystemctlRestart the system sudo systemctl reboot Suspend the system sudo systemctl suspend CPU stopped working sudo systemctl halt Turn off the system, cut off the power sudo systemctl poweroff 
systemd-analyzeSee how long it takes to start systemd-analyze See how long each service started systemd-analyze blame View the startup process flow systemd-analyze critical-chain View the startup flow of the specified service systemd-analyze critical-chain sshd.service
hostnamectlView current host information hostnamectl Set Hostname sudo hostnamectl set-hostname ***
localectlView localization settings localectl
timedatectlView current time zone settings timedatectl Show all available time zones timedatectl list-timezones Set current time zone sudo timedatectl set-timezone Africa / Juba
Unitsystemctl list-unitsView the units where the system is running systemctl list-units List all units in the system systemctl list-units –all List all units that failed to load systemctl list-units –failed List all running units of type service systemctl list-units –type = service
systemctl statusView system status systemctl status View service status systemctl status ***. service View the service status of the remote host systemctl -H user @ hostname status ***. service
unit managementStart service sudo systemctl start ***. service Out of service sudo systemctl stop ***. service Restart the service sudo systemctl restart ***. service Kill all child processes spawned by the service sudo systemctl kill ***. service Reload the service configuration file sudo systemctl reload ***. service Reload the configuration files of all modified units sudo systemctl daemon-reload Display unit’s low-level parameters sudo systemctl show ***. service
systemctl list-dependenciesList service dependencies systemctl list-dependencies ***. service List the reverse dependencies of the service systemctl list-dependencies –reverse ***. service View the unit included in the target systemctl list-dependencies ***. target
unit configuration fileView the contents of the unit configuration file systemctl cat ***. service View all configuration files systemctl list-unit-files View the specified type of configuration file systemctl list-unit-files –type = service
TargetView all targets of the system systemctl list-unit-files –type = target View the unit included in the target systemctl list-dependencies ***. target View the default target at startup systemctl get-default
Log managementjournalctlView all logs of this system startup journalctl  View the log of the specified unit journalctl -u ***. service Scroll through the latest logs journalctl -f View logs at a specified time journalctl –since “2020-05-06 01:00” –until “2020-05-06 03:00”

  Briefly introduce a more important command systemd-analyze ciritical-chain:

[root@embeddedgeeks ~] $ systemd-analyze critical- chain sshd.service
The time after the unit is active or started is printed after the " @ " character.
The time the unit takes to start is printed after the " + " character.
 
sshd.service + 16ms
└─cloud -init.service @ 6 .503s + 9 .732s
  └─network.service @ 3 .352s + 3 .121s
    └─network -pre.target @ 3 .348s
      └─cloud -init-local.service @ . 1 .665s + . 1 .682s
        └─dbus.socket @ 1 .659s
          └─sysinit.target @ 1 .628s
            └─systemd -update-utmp.service @ 1 .614s + 13ms
              └─auditd.service @ 1 .424s + 182ms
                └─systemd -tmpfiles-setup.service @ 1 .394s + 16ms
                  └─rhel -import-state.service @ 1 .341s + 40ms
                    └─local -fs.target @ 1 .325s
                      └─ephemeral. Mount @ 747ms + 577ms
                        └─local -fs- pre.target @ 728ms
                          └─lvm2 -monitor.service @ 368ms + 359ms
                            └─lvm2 - lvmetad.service @ 484ms
                              └─lvm2 - lvmetad.socket @ 329ms
                                └─ -.slice

  In the output, the time after “@” indicates the start time of the unit; the time after “+” indicates how long it took the unit to start up. It should be noted that this information may be misleading, because a unit that takes a long time to start may only be waiting for another dependent unit to start, and the services are not started in order when they are started.  

Unit

The multiple system resources managed by systemd are collectively called Unit, and there are 12 types in total:

  • Service unit: system service
  • Target unit: a group of multiple units
  • Device Unit: hardware device
  • Mount Unit: Mount point of the file system
  • Automount Unit: automatic mount point
  • Path Unit: file or path
  • Scope Unit: external process not started by Systemd
  • Slice Unit: process group
  • Snapshot Unit: Systemd snapshot, you can switch back to a snapshot
  • Socket Unit: socket for inter-process communication
  • Swap Unit: swap file
  • Timer Unit: timer

  Check the status of the service unit sshd:

[root@embeddedgeeks ~ ] $ systemctl status sshd.service
● sshd.service - OpenSSH server daemon
   Loaded: loaded ( / usr / lib / systemd / system / sshd.service; enabled; vendor preset: enabled)
   The Active: Active (running) Operating since Fri 2019 - . 11 - 01  18 is : 35 : 20 is CST; . 6 months . 3 Days ago Member
     Docs: man : sshd ( 8 )
            man : sshd_config ( 5 )
Main PID: 8621 (sshd)
   Memory: 24.7M 
   CGroup: /system.slice/ sshd.service
           └─ 8621 / usr / sbin / sshd- D
 
Nov 01  18 : 35 : 20 lianhua systemd [ 1 ]: Starting OpenSSH server daemon .
[root@embeddedgeeks ~] $ systemctl list- dependencies sshd.service
sshd.service
● ├─sshd - keygen.service
● ├─system.slice
● └─basic.target
● ├─microcode.service
● ├─rhel - dmesg.service
● ├─selinux -policy-migrate-local- changes@targeted.service
...

  See which units need to depend on sshd.service:

[root@embeddedgeeks ~] $ systemctl list-dependencies- reverse sshd.service
sshd.service
● ├─cloud - init.service
● └─multi - user.target
● └─graphical.target

  View the configuration file of sshd.service:

[root@embeddedgeeks ~] $ systemctl cat sshd.service
# / usr / lib / systemd / system / sshd.service
[Unit]
Description = OpenSSH server daemon
Documentation = man : sshd ( 8 ) man : sshd_config ( 5 )
After = network.target sshd- keygen.service
Wants = sshd- keygen.service
 
[Service]
Type = notify
EnvironmentFile = / etc / sysconfig / sshd
ExecStart = / usr / sbin / sshd- D $ OPTIONS
ExecReload = / bin / kill - HUP $ MAINPID
KillMode = process
Restart = on- failure
RestartSec = 42s
 
[Install]
WantedBy = multi-user.target

  It can be seen that the configuration file is divided into three Units, Service and Install, each parameter is introduced as follows: [Unit] Description: A string that briefly describes the Unit. Documentation: A detailed description of Unit. After: Emphasizes the startup sequence between units. After starts after the specified unit. Before: Corresponding to After, emphasizing the sequence between the units and starting before the unit specified later. Requires: Set the dependency relationship between the units. Note that After and Before only emphasize the startup sequence, and do not set the dependency relationship. Requires sets the unit to be strongly dependent on the specified unit. If the specified unit fails to start, the unit will not be started. Wants: Weak dependency, if the specified Unit fails to start, the current Unit will still start. BindsTo: Similar to Requires, but more dependent. In Requires, if the dependent unit fails the condition check or the unit actively stops, it does not cause the dependent unit to stop along with it. Using BindsTo can realize that if the dependent unit stops, the dependent unit will stop. Conflicts: Conflicts between specified units. If the specified unit starts, the current unit will not start. If the current unit starts, the specified unit must stop.   [Service] Unit executes the main body. Type: Set the startup type of the process, which must be set to simple, exec, forking, oneshot, dbus, notify and idle:

  • simple: The default value is to use the main process to execute the command specified by ExecStart.
  • forking: Create a child process from the parent process in the form of fork, and the parent process exits immediately after creation.
  • oneshot: One-time process, systemd waits for the current service to exit, and then executes it.
  • dbus: The current service is started via D-Bus.
  • notify: The current service is started, notify systemd, and then continue to execute.
  • idle: If there are other services completed, the current service will run.

ExecStart: Command to start the current service. EnvironmentFile: The environment configuration file of the current service. The variable $ OPTIONS in ExecStart comes from this configuration file. ExecReload: The current service needs to execute the command line specified by ExecReload when reloading the configuration, where $ MAINPID is a special environment variable that represents the PID of the main process. KillMode: Set the method to kill the process when the unit is stopped. process means only kill the main process. Restart: When the service process exits normally, exits abnormally, and is killed, whether to restart the service when it times out. on-failue means to restart the service only when the service exits abnormally. RestartSec: Set how long to pause the service before restarting, the default unit is s.   [Install] Install is used to define how the Unit starts and whether to start automatically after booting. WantedBy: When using systemctl enable to enable this unit, a soft link to the unit file will be created in the .wants / directory of each list unit. Equivalent to adding Wants = unit option to the unit file in each list. In this way, when any unit in the list is started, the unit will be started. RequiredBy: Similar to WantedBy is equivalent to adding Requires = unit option.  

Unit profile status

  Systemd reads Unit configuration files from the directory / etc / systemd / system / by default. However, most of the files stored therein are symbolic links, pointing to the directory / usr / lib / systemd / system /, and the real configuration files are stored in this directory. If a symbolic link is established between the two directories, it means that the Unit has established a start link.   The command systemctl list-unit-files can show the status of each Unit configuration file:

[root@embededgeeks ~] $ systemctl list-unit- files
UNIT FILE STATE
tmp. mount                                      disabled
brandbot.path enabled
auth -rpcgss- module.service static
autofs.service disabled
systemd - timedated.service masked
...

  There are four types of Unit files: enabled: The startup link has been established; disabled: The startup link is not established, but there is a value in the Install block where the startup link can be established; masked: The unit configuration file is forbidden to establish a startup link, corresponding to the / etc / systemd / system / directory soft link pointing to / dev / null; static: This configuration file does not have an Install part, and can only be enabled as a dependency of other Units;   View the file configuration information in four states:

# autofs.service disabled
[root@embeddedgeeks ~] # systemctl cat autofs.service
# / usr / lib / systemd / system / autofs.service
[Unit]
...
[Service]
...
[Install]
WantedBy = multi- user.target
[root @ lianhua ~] # ll /etc/systemd/system/multi-user.target.wants/ | grep autofs.service
[root @ lianhua ~ ] #
 
# brandbot.path enabled
[root@embeddedgeeks ~] $ systemctl cat brandbot.path
# / usr / lib / systemd / system / brandbot.path
[Unit]
...
[Path]
...
[Install]
WantedBy = multi- user.target
[root@embeddedgeeks ~] $ ll /etc/systemd/system/multi-user.target.wants/ | grep brand
lrwxrwxrwx. 1 root root 37 May   9   2018 brandbot.path-> / usr / lib / systemd / system / brandbot.path

 
# systemd - timedated.service masked
[root@embeddedgeeks ~] # ll / etc / systemd / system | grep systemd- timedated.service
lrwxrwxrwx. 1 root root     9 Aug 12   2018 systemd-timedated.service-> / dev / null
 
 
# auth -rpcgss- module.service static
[root@embeddedgeeks ~] # systemctl cat auth-rpcgss- module.service
[Unit]
...
[Service]
...

  The commands systemctl enable and systemctl diable can establish a startup link (provided that they can be established) and cancel the startup link respectively. The command systemctl is-enable can check whether the unit is enabled, for example:

[root@embeddedgeeks ~] # systemctl is- enabled autofs.service
disabled
[root@embeddedgeeks ~ ] # systemctl enable autofs.service
Created symlink /etc/systemd/system/multi-user.target.wants/autofs.service → / usr / lib / systemd / system / autofs.service.
[root@embeddedgeeks ~] # systemctl is- enabled autofs.service
enabled

    In addition to the command to check whether Unit is enabled, there is also a method to check whether Unit is enabled through systemctl status:

[root@embeddedgeeks ~ ] # systemctl status autofs.service
● autofs.service - Automounts filesystems on demand
   Loaded: loaded ( / usr / lib / systemd / system / autofs.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

  The first enabled in the first line of Loaded indicates whether the current Unit is powered on and self-started, which is the value that systemctl is-enable wants to show. The second disabled indicates whether the unit is enabled or disabled by default in the systemd preset file. You can view Unit’s preset files from the following directory:

/ etc / systemd / system-preset / * .preset
/run/systemd/system-preset/*.preset
/usr/lib/systemd/system-preset/*.preset
/etc/systemd/user-preset/*.preset
/run/systemd/user-preset/*.preset
/usr/lib/systemd/user-preset/*.preset

  Examples:

[root@embeddedgeeks ~] # ll / usr / lib / systemd / system-preset / 
total 24 
-rw-r--r--. 1 root root   264 Sep 25   2019  85 -display- manager.preset
 -rw-r- -r--. 1 root root 3982 Sep 25   2019  90 - default.preset
 -rw-r--r--. 1 root root   951 Jun 22   2018  90 - systemd.preset
 
[root@embeddedgeeks ~] # cat / usr / lib / systemd / system-preset / 90 - systemd.preset
Remote enable - fs.target
disable console - getty.service
disable debug -shell.service

  The format of the preset file is “priority-policy name.preset”, where the smaller the priority number, the higher the priority. The preset files included in the general software package should be placed in the / usr / lib directory, and the preset files set by the system administrator are placed in the / etc directory. For the preset files with the same name in different directories, only the highest priority The one in the directory shall prevail, that is, / etc / has the highest priority, / run / has the priority, and / usr / lib / has the lowest priority. The content of the preset file enable means that the specified unit is enabled by default, and disable means that the specified unit is disabled by default.     Now imagine a situation where if the service (unit) configuration files are all written, but the user who executes the service needs to be temporarily changed, is it necessary to rewrite the configuration file at this time? The answer is no, you can change the Unit configuration through the Drop-in mechanism of systemd, for example:

[root@embeddedgeeks ~] $ systemctl status autofs.service
● autofs.service - Automounts filesystems on demand
   Loaded: loaded ( / usr / lib / systemd / system / autofs.service; enabled; vendor preset: disabled)
   The Active: Active (running) Operating since Mon 2019 - 08 - 05  . 17 : 42 is : 46 is CST; . 9 months 0 Days ago Member
  Process: 23921 ExecReload = / usr / bin / kill -HUP $ MAINPID (code = exited, status = 0 / SUCCESS)
 
[root@embeddedgeeks ~] $ cat /usr/lib/systemd/system/autofs.service.d/ app.conf
[Service]
User = 
User = app
[root@embeddedgeeks ~] $ systemctl daemon - reload
[root@embeddedgeeks ~] $ systemctl restart autofs.service
[root@embeddedgeeks ~] $ systemctl status autofs.service
● autofs.service - Automounts filesystems on demand
   Loaded: loaded ( / usr / lib / systemd / system / autofs.service; enabled; vendor preset: disabled)
  Drop -In: / usr / lib / systemd / system / autofs.service.d
           └─app.conf
   The Active: Active (running) Operating since Mon 2019 - 08 - 05  . 17 : 42 is : 46 is CST; . 9 months 0 Days ago Member

  To use the Drop-in mechanism in systemd, you need to build the ***. d directory under the same level directory of the unit, and configure the file ending with .conf in the directory. The first line in the file indicates the changed configuration block, the first User = indicates the user who canceled the service execution, and the second User indicates that the user executed the service is specified as the given value. In the example, the user app is configured. After the configuration, you need to reload the systemd configuration file, and then restart the relevant unit. Check the status of the unit and find that there is an additional Drop-In file, and the status is active.  

Target

Target is a special type of Unit. It represents a unit group. When systemd starts Target, it starts all units included in Target. So systemd starts to a certain target is equivalent to start to a certain state. View target status:

[root@embeddedgeeks ~] # systemctl cat cloud- config.target
[Unit]
Description = Cloud- config availability
Wants = cloud-init-local.service cloud- init.service
After = cloud-init-local.service cloud- init.service
[root@embeddedgeeks ~] # systemctl status cloud- config.target
● cloud -config.target-Cloud- config availability
   Loaded: loaded ( / usr / lib / systemd / system / cloud- config.target; static; vendor preset: disabled)
   The Active: Fri Active Operating since 2020 - 03 - 13 is  09 : 18 is : 36 UTC; . 1 months 22 is Days ago Member

path unit

[root@embeddedgeeks ~] # systemctl status systemd-ask-password- wall .path
● systemd -ask-password- wall .path- Forward Password Requests to Wall Directory Watch
   Loaded: loaded ( / usr / lib / systemd / system / systemd-ask-password- wall .path; static; vendor preset: disabled)
   The Active: Active (Waiting) Fri Operating since 2020 - 03 - 13 is  09 : . 17 : 52 is UTC; . 1 months 22 is Days ago Member
     Docs: man : systemd-ask-password-console.service ( 8 )
 
[root@embeddedgeeks ~] # systemctl cat systemd-ask-password- wall .path
[Unit]
Description = Forward Password Requests to Wall Directory Watch
...
 
[Path]
DirectoryNotEmpty = / run / systemd / ask- password
MakeDirectory = yes
[root@embeddedgeeks ~] # systemctl status systemd-ask-password- wall 
● systemd -ask-password- wall .service- Forward Password Requests to Wall
   Loaded: loaded ( / usr / lib / systemd / system / systemd-ask-password- wall .service; static; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man : systemd-ask-password-console.service ( 8 )

path is also one of many units. It is used by systemd to monitor file system paths to support path-based units. Each path unit must have a matching unit for starting when the path changes. The matching unit can be specified explicitly with the Unit = option. If not specified, the default is the .service unit with the same name as the unit (not suffixed). For example, systemd-ask-password-wall.path matches the systemd-ask-password-wall.service unit by default.

If the file system path of a path unit is under another mount unit, then it will automatically get the Requires = and After = dependency on the mount point unit it depends on. Mount is also one of many units. It is a unit used by systemd to manage file system mount points.