ZNHOO Whatever you are, be a good one!

systemd

  1. systemd manager
  2. Hierarchy of Control Groups
  3. systemctl
    1. systemd drop-in
  4. journalctl
  5. User Unit

systemd manager

Systemd (system daemon) is a manager capable of managing both services and the Linux system.

The daemon locates at /lib/systemd/systemd, and /sbin/init is just a symbolic link:

~$ ll /sbin/init
lrwxrwxrwx 1 root root 22 May 18 18:32 /sbin/init -> ../lib/systemd/systemd

At the very boot of the system, systemd runs as the PID 1, namely the system manager instance:

~$ ps -1
    PID TTY      STAT   TIME COMMAND
      1 ?        Ss     0:24 /sbin/init

When a user login, a user manager instance is started for services of that particular account by user@.service:

~ $ systemctl cat user@.service

~ $ id -u
~ $ systemctl show user@1000.service

~ $ systemctl status user@1000.service

~ $ ps -eF | grep -i [s]ystemd
jim     572       1  0  4081  9208   7 Jun20 ?        00:00:00 /usr/lib/systemd/systemd --user

Hierarchy of Control Groups

  1. .slice controls the resources
  2. User processes may be started by:
    1. user@.service unit.
    2. manual startup, like sshd, displayer manager (e.g. initx/gdm), etc.
~ $ systemd-cgls

Control group /:
-.slice
├─user.slice
│ └─user-1000.slice
│   ├─user@1000.service
│   │ ├─app.slice
│   │ │ ├─dconf.service
│   │ │ │ └─10610 /usr/lib/dconf-service
│   │ │ ├─thunar.service
│   │ │ │ └─47699 /usr/bin/Thunar --daemon
│   │ │ ├─at-spi-dbus-bus.service
│   │ │ │ ├─ 816 /usr/lib/at-spi-bus-launcher
│   │ │ │ ├─2094 /usr/bin/dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-address 3
│   │ │ │ └─2098 /usr/lib/at-spi2-registryd --use-gnome-session
│   │ │ └─dbus.service
│   │ │   ├─  648 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
│   │ │   └─47703 /usr/lib/xfce4/xfconf/xfconfd
│   │ └─init.scope
│   │   ├─572 /usr/lib/systemd/systemd --user
│   │   └─573 (sd-pam)
│   └─session-1.scope
│     ├─   550 login -- jim
│     ├─   579 -bash
│     ├─   589 /usr/bin/ssh-agent -s
│     ├─   604 /bin/sh /usr/bin/startx
│     ├─   622 xinit /home/jim/.xinitrc -- /home/jim/.xserverrc :0 vt1 -keeptty -auth /tmp/serverauth.RW8Bv770dV
│     ├─   623 /usr/lib/Xorg -nolisten tcp -nolisten local -keeptty :0 vt1 -keeptty -auth /tmp/serverauth.RW8Bv770dV vt1
│     ├─   642 awesome
│     ├─   666 xautolock -detectsleep -time 3 -locker slock -corners 00+0 -cornerdelay 5 -notify 5 -notifier notify-send -u critical -t 10000 -- 'LOCKING screen in 5 seconds'
│     ├─   675 fcitx
│     ├─   680 /usr/bin/dbus-daemon --syslog --fork --print-pid 4 --print-address 6 --config-file /usr/share/fcitx/dbus/daemon.conf
│     ├─   684 /usr/bin/fcitx-dbus-watcher unix:abstract=/tmp/dbus-y7OCHgrxGl,guid=98e8dc5f3eed24ce2b4a183c60cf475a 680
│     ├─  2091 emacs --daemon
│     ├─ 16367 goldendict
│     ├─ 94741 /usr/lib/firefox/firefox
│     ├─ 94901 /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 210 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─ 94935 /usr/lib/firefox/firefox -contentproc -childID 3 -isForBrowser -prefsLen 5036 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─ 95053 /usr/lib/firefox/firefox -contentproc -parentBuildID 20210623174607 -prefsLen 6216 -prefMapSize 239063 -appdir /usr/lib/firefox/browser 94741 true rdd
│     ├─114937 /usr/lib/firefox/firefox -contentproc -childID 19 -isForBrowser -prefsLen 9718 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─128993 /usr/lib/firefox/firefox -contentproc -childID 50 -isForBrowser -prefsLen 11032 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─155942 /usr/lib/firefox/firefox -contentproc -childID 64 -isForBrowser -prefsLen 11034 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─157055 /usr/lib/firefox/firefox -contentproc -childID 69 -isForBrowser -prefsLen 11034 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─161533 /usr/lib/firefox/firefox -contentproc -childID 70 -isForBrowser -prefsLen 11035 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─165017 st
│     ├─165018 /bin/bash
│     ├─165033 tmux new -s arch
│     ├─165035 tmux new -s arch
│     ├─165036 -bash
│     ├─165051 ssh ora1
│     ├─165855 -bash
│     ├─165867 -bash
│     ├─165879 ssh ora2
│     ├─166174 /usr/lib/firefox/firefox -contentproc -childID 95 -isForBrowser -prefsLen 11070 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─166322 /usr/lib/firefox/firefox -contentproc -childID 97 -isForBrowser -prefsLen 11070 -prefMapSize 239063 -parentBuildID 20210623174607 -appdir /usr/lib/firefox/browser 94741 true tab
│     ├─167307 /usr/lib/thunderbird/thunderbird
│     ├─177691 -bash
│     ├─177791 man systemd
│     ├─177801 less
│     ├─177869 man user@.service
│     ├─177879 less
│     ├─177932 -bash
│     ├─178007 systemd-cgls
│     └─178008 less
├─init.scope
│ └─1 /sbin/init
└─system.slice
  ├─systemd-udevd.service
  │ └─431 /usr/lib/systemd/systemd-udevd
  ├─polkit.service
  │ └─94871 /usr/lib/polkit-1/polkitd --no-debug

systemctl

# show installed units on the system
~ $ systemctl list-unit-files [pattern]

# show all units in memory
~ $ systemctl
# filter units in memory
~ $ systemctl --type=help
~ $ systemctl --state=help
~ $ systemctl --type=service --state=running [list-units [pattern]]

# reload all installed unit files (e.g. nginx.service)
~ $ systemctl daemon-reload
# reload daemon config (e.g. nginx.conf)
~ $ systemctl reload [pattern]

# view unit configuration
# mostly default from 'systemd' config
~ $ systemctl show [pattern]
# view unit file
~ $ systemctl cat [pattern]

# manage a unit
~ $ systemctl enable UNIT
~ $ systemctl enable PATHNAME
~ $ systemctl status/start/stop/restart/disable/mask UNIT
~ $ systemctl enable name@sub.service

# dependency
~ $ systemctl [--reverse] list-dependencies UNIT
~ $ systemctl --with-dependencies [--reverse] status PATTERN

systemd drop-in

It is not unusual when we do not want to modify the shipped unit file but want customization.

For a particular unit foo.service, systemd supports merging drop-in files *.conf stored under the drop-in directory foo.d. Drop-in directories can be located in /etc/systemd/system, /usr/lib/systemd/system or /run/systemd/system.

We can manually create the drop-in directory and then add or remove drop-in files. If the drop-in directory is empty, then the unit would be cleared!

Alternatively, systemctl edit automatically create and/or remove the drop-in directory and drop-in files. After editing, it would call systemctl daemon-reload automatically.

~ $ systemctl edit kong-enterprise-edition

~ $ systemctl cat kong-enterprise-edition
...

# /etc/systemd/system/kong-enterprise-edition.service.d/override.conf
[Service]
Environment=KONG_NGINX_DAEMON=off
Environment=KONG_DATABASE=off

We can optionally add --full, --force or --runtime to systemctl edit. For details, please refer to man page of systemctl.

If somehow, we want to discard all drop-in directories and drop-in files, then run the command as follows.

~ $ systemctl revert kong-enterprise-edition
Removed /etc/systemd/system/kong-enterprise-edition.service.d/override.conf.
Removed /etc/systemd/system/kong-enterprise-edition.service.d.

journalctl

~ # journalctl -xfe
~ # journalctl -u nginx

User Unit

User unit should be under ~/.config/systemd/user/.

Firstly, let user unit know the user PATH. At the end of ~/.bash_profile, put the following line.

# ~/.bash_profile
systemctl --user import-environment PATH

Check if user unit know the PATH

~ $ systemctl --user show-environment

Now enable and start user unit.

~ $ systemctl --user daemon-reload

~ $ systemctl --user status weechat-headless.service
~ $ systemctl --user enable weechat-headless.service

~ $ systemctl --user start weechat-headless.service