systemdお勉強メモ① systemdは全ての親プロセス

## systemdは全ての親プロセス
systemdを採用したシステムでは、全てのプロセスの始まりとして `systemd`プロセスが起動する。`ps -aux` でプロセスを確認するとPID=1に `/usr/lib/systemd/systemd` がある。全てのプロセスの親プロセス。

```bash
$ ps -aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  1.7 170840 16612 ?        Ss   Jan21   0:26 /usr/lib/systemd/systemd --
root           2  0.0  0.0      0     0 ?        S    Jan21   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   Jan21   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   Jan21   0:00 [rcu_par_gp]
root           5  0.0  0.0      0     0 ?        I<   Jan21   0:00 [slub_flushwq]
root           6  0.0  0.0      0     0 ?        I<   Jan21   0:00 [netns]
...
```

`pstree` でプロセスの親子関係を見てみる

```bash
$ pstree
systemd─┬─2*[agetty]
        ├─amazon-ssm-agen───7*[{amazon-ssm-agen}]
        ├─atd
        ├─auditd───{auditd}
        ├─chronyd
        ├─dbus-broker-lau───dbus-broker
        ├─gssproxy───5*[{gssproxy}]
        ├─lsmd
        ├─rngd───{rngd}
        ├─sshd─┬─sshd───sshd───bash───bash───sh───node─┬─node───11*[{node}]
        │      │                                       ├─node─┬─bash───pstree
        │      │                                       │      └─11*[{node}]
        │      │                                       └─10*[{node}]
        │      └─sshd───sshd───bash───bash─┬─code-1a5daa3a02───{code-1a5daa3a02}
        │                                  └─sleep
        ├─sssd─┬─sssd_be
        │      └─sssd_nss
        ├─systemd───(sd-pam)
        ├─systemd-homed
        ├─systemd-inhibit───acpid
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-network
        ├─systemd-resolve
        ├─systemd-udevd
        └─systemd-userdbd───3*[systemd-userwor]
```

`systemd`は以下のデーモンプロセスからなる。

- `systemd`：メインプロセス
- `systemd-journal`：ジャーナル（ログ）管理プロセス
- `systemd-logind`：ログイン管理プロセス
- `systemd-udevd`：デバイス動的検知プロセス

`systemd`では各処理がUnit単位で管理される。Unitは `target` `mount`  `device` `service` など、役割によってタイプが分かれる。それぞれのUnitには依存関係がある。

`systemd` は起動された時に各種依存関係の一覧を作成し、この環境で起動すべきUnitから順に処理していく。依存関係のないUnitはなるべく並列化して処理するので起動が従来（=かつてのinitプログラム）より早い。

`sudo systemctl list-dependencies` で各Unitの依存関係が見える。

```bash
$ sudo systemctl list-dependencies
default.target
○ ├─display-manager.service
○ ├─systemd-update-utmp-runlevel.service
● └─multi-user.target
●   ├─amazon-ssm-agent.service
●   ├─atd.service
●   ├─auditd.service
●   ├─chronyd.service
○   ├─hibinit-agent.service
○   ├─irqbalance.service
●   ├─libstoragemgmt.service
●   ├─rngd.service
●   ├─sshd.service
●   ├─sssd.service
●   ├─sysstat.service
●   ├─systemd-ask-password-wall.path
●   ├─systemd-homed.service
●   ├─systemd-logind.service
●   ├─systemd-networkd.service
○   ├─systemd-update-utmp-runlevel.service
●   ├─systemd-user-sessions.service
○   ├─update-motd.service
●   ├─basic.target
●   │ ├─-.mount
○   │ ├─rpmdb-rebuild.service
●   │ ├─tmp.mount
●   │ ├─paths.target
●   │ ├─slices.target
●   │ │ ├─-.slice
●   │ │ └─system.slice
●   │ ├─sockets.target
●   │ │ ├─dbus.socket
●   │ │ ├─sssd-kcm.socket
●   │ │ ├─systemd-coredump.socket
●   │ │ ├─systemd-initctl.socket
●   │ │ ├─systemd-journald-audit.socket
●   │ │ ├─systemd-journald-dev-log.socket
●   │ │ ├─systemd-journald.socket
●   │ │ ├─systemd-networkd.socket
●   │ │ ├─systemd-udevd-control.socket
●   │ │ ├─systemd-udevd-kernel.socket
●   │ │ └─systemd-userdbd.socket
●   │ ├─sysinit.target
●   │ │ ├─dev-hugepages.mount
●   │ │ ├─dev-mqueue.mount
```

 `.target` はUnitの集合を表していて、何か特定の処理をしているわけではない。 `/etc/systemd/system/hoge.target.wants` や`/etc/systemd/system/hoge.target.requires`に `hoge.target` がラップしてるUnitが入ってるっぽい。（ラップしてるで表現が合ってるかは不明）

起動後はまず `default.target` というUnitが処理される。 `default.target` は `/etc/systemd/system` 配下にあるらしい。私の環境からは見えないけど。

```bash
$ ls -l /etc/system/systemd/default.target
```

GUI環境では `default.target` は `graphical.target` にリンクされている。

```bash
$ systemctl get-default
graphical.target
```

なので（おそらく） `sudo systemctl list-dependencies` で `[default.target](http://default.target)` の下にあったUnitたちの実態は `[graphical.target](http://graphical.target)` ということになる気がする。

`default.target` のリンク先は `systemctl set-default` で設定できる。以下は `default.target` のリンク先を `multi-user.targe[t](http://multiuser.target)` に変更する例

```bash
$ systemctl set-default multiuser.target
```

もしくはシンボリックリンクを作成する

```bash
$ ln -sf /lib/systemd/system/graphical.target /etc/systemd/system/default.target
```