systemd Tips

# ユーザを指定してサービス起動
```plaintext:xxx.service
$ cat /etc/systemd/system/xxx.service 
[Unit]
Description=xxx
StartLimitintervalSec=60
StartLimitBurst=10

[Service]
ExecStart=xxx
Restart=always
RestartSec=5
User=xxx ★ここでユーザ指定

[Install]
WantedBy=multi-user.target
```

# 各cgroupsで使われてるリソースを知りたい

以下を使う
```bash
$ systemd-cgtop
```

# serviceのログ出力先を制御

「StandardOutput」、「StandardError」ディレクティブで指定

```emergency.service
...

[Service]
...
StandardOutput=inherit
StandardError=inherit
...

```

## consoleとは

「StandardOutput=journal+console」としたときのconsoleとはなんぞや？

各端末には端末デバイスファイルが割り当てられる
```bash
$ tty
/dev/ttymxc1
```
consoleとはシステムコンソール（/dev/console）のことでカーネルメッセージはここに送られる。
```bash
$ ls -al /dev
...
crw-------    1 root     root        5,   1 Sep 20 18:55 console
...
```
で、これはブートで設定される。consoleにはnullを指定できるが、基本はttyを指定する。
```
u-boot=> printenv
...
console=ttymxc1,115200
...
```
## TTYPathの設定（自分への戒め）
ユニットファイルで、以下のように書く時、TTYPathにはttyを書くこと。
/dev/nullや/dev/zeroはttyではないよ！
```
StandardError=tty
TTYPath=/dev/ttymxc1
```

# パス監視

以下の時アクティブにする
* /root/machine-idが存在すれば、サービスユニットをアクティブにする
* 「存在しない⇒存在する」に変化すれば、サービスユニットをアクティブにする

## 事前状態
```bash
root@ubuntu:/lib/systemd/system# systemctl cat systemd-journald --no-pager
# /lib/systemd/system/systemd-journald.service
#  SPDX-License-Identifier: LGPL-2.1-or-later
#
#  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=Journal Service
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
DefaultDependencies=no
Requires=systemd-journald.socket
After=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket syslog.socket
Before=sysinit.target

[Service]
DeviceAllow=char-* rw
ExecStart=/lib/systemd/systemd-journald
FileDescriptorStoreMax=4224
IPAddressDeny=any
LockPersonality=yes
MemoryDenyWriteExecute=yes
NoNewPrivileges=yes
OOMScoreAdjust=-250
ProtectClock=yes
Restart=always
RestartSec=0
Nice=-1
RestrictAddressFamilies=AF_UNIX AF_NETLINK
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
RuntimeDirectory=systemd/journal
RuntimeDirectoryPreserve=yes
Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket
StandardOutput=null
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service
Type=notify
WatchdogSec=3min

# In case you're wondering why CAP_SYS_PTRACE is needed, access to
# /proc/<pid>/exe requires this capability. Thus if this capability is missing
# the _EXE=/OBJECT_EXE= fields will be missing from the journal entries.
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE

# If there are many split up journal files we need a lot of fds to access them
# all in parallel.
LimitNOFILE=524288
```
```bash
root@ubuntu:/lib/systemd/system# systemctl cat systemd-journald.path
# /lib/systemd/system/systemd-journald.path
[Unit]
Description=watch machine-id

[Path]
PathExists=/root/machine-id
```
```bash
root@ubuntu:/lib/systemd/system# ls /root
snap  vboxpostinstall.sh
```
```bash
root@ubuntu:/lib/systemd/system# systemctl status systemd-journald --no-pager
○ systemd-journald.service - Journal Service
     Loaded: loaded (/lib/systemd/system/systemd-journald.service; static)
     Active: inactive (dead) since Mon 2024-08-19 02:34:31 JST; 4min 36s ago
TriggeredBy: ● systemd-journald-audit.socket
             ● systemd-journald.socket
             ● systemd-journald-dev-log.socket
       Docs: man:systemd-journald.service(8)
             man:journald.conf(5)
    Process: 23465 ExecStart=/lib/systemd/systemd-journald (code=exited, status=0/SUCCESS)
   Main PID: 23465 (code=exited, status=0/SUCCESS)
     Status: "Processing requests..."
        CPU: 69ms

Aug 19 02:20:06 ubuntu systemd-journald[23465]: Journal started
Aug 19 02:20:06 ubuntu systemd-journald[23465]: System Journal (/var/log/journal/9d985ecbe7d846579fe4025d0221499d) is 64.0M, max 4.0G, 3.9G free.
Aug 19 02:34:31 ubuntu systemd-journald[23465]: Journal stopped
```
```bash
root@ubuntu:/lib/systemd/system# systemctl status systemd-journald.path --no-pager
○ systemd-journald.path - watch machine-id
     Loaded: loaded (/lib/systemd/system/systemd-journald.path; static)
     Active: inactive (dead)
   Triggers: ● systemd-journald.service

Aug 19 01:53:29 ubuntu systemd[1]: Stopped watch machine-id.
Aug 19 01:57:57 ubuntu systemd[1]: Started watch machine-id.
Aug 19 01:58:54 ubuntu systemd[1]: systemd-journald.path: Deactivated successfully.
Aug 19 01:58:54 ubuntu systemd[1]: Stopped watch machine-id.
Aug 19 02:16:11 ubuntu systemd[1]: systemd-journald.path: Deactivated successfully.
Aug 19 02:16:11 ubuntu systemd[1]: Stopped watch machine-id.
Aug 19 02:19:06 ubuntu systemd[1]: systemd-journald.path: Deactivated successfully.
Aug 19 02:19:06 ubuntu systemd[1]: Stopped watch machine-id.
Aug 19 02:34:21 ubuntu systemd[1]: systemd-journald.path: Deactivated successfully.
Aug 19 02:34:21 ubuntu systemd[1]: Stopped watch machine-id.
```

## 検証
1. パスユニットをアクティブにする

    パスユニットはactive(waiting)になるが、サービスユニットはinactiveのまま。
    waitingは/root/machine-idファイルの有無を監視してる状態。
    ```bash
    root@ubuntu:/lib/systemd/system# systemctl start systemd-journald.path           
    root@ubuntu:/lib/systemd/system# systemctl status systemd-journald.path --no-pager
    ● systemd-journald.path - watch machine-id
         Loaded: loaded (/lib/systemd/system/systemd-journald.path; static)
         Active: active (waiting) since Mon 2024-08-19 02:48:04 JST; 5s ago
       Triggers: ● systemd-journald.service
    ```
    ```bash
    root@ubuntu:/lib/systemd/system# systemctl status systemd-journald --no-pager
    ○ systemd-journald.service - Journal Service
         Loaded: loaded (/lib/systemd/system/systemd-journald.service; static)
         Active: inactive (dead) since Mon 2024-08-19 02:46:57 JST; 1min 55s ago
    TriggeredBy: ● systemd-journald-audit.socket
                 ● systemd-journald.path
                 ● systemd-journald.socket
                 ● systemd-journald-dev-log.socket
           Docs: man:systemd-journald.service(8)
                 man:journald.conf(5)
        Process: 23521 ExecStart=/lib/systemd/systemd-journald (code=exited, status=0/SUCCESS)
       Main PID: 23521 (code=exited, status=0/SUCCESS)
         Status: "Processing requests..."
            CPU: 111ms
    
    Aug 19 02:41:27 ubuntu systemd-journald[23521]: Journal started
    Aug 19 02:41:27 ubuntu systemd-journald[23521]: System Journal (/var/log/journal/9d985ecbe7d846579fe4025d0221499d) is 64.0M, max 4.0G, 3.9G free.
    Aug 19 02:46:57 ubuntu systemd-journald[23521]: Journal stopped
    ```
1. /root/machine-idを作成する

    パスユニットがactive(running)に変化し、サービスユニットをactiveにする
    ```bash
    root@ubuntu:/lib/systemd/system# touch /root/machine-id
    root@ubuntu:/lib/systemd/system# systemctl status systemd-journald.path --no-pager
    ● systemd-journald.path - watch machine-id
         Loaded: loaded (/lib/systemd/system/systemd-journald.path; static)
         Active: active (running) since Mon 2024-08-19 02:48:04 JST; 3min 49s ago
       Triggers: ● systemd-journald.service
    ```
    ```bash
    root@ubuntu:/lib/systemd/system# systemctl status systemd-journald --no-pager
    ● systemd-journald.service - Journal Service
         Loaded: loaded (/lib/systemd/system/systemd-journald.service; static)
         Active: active (running) since Mon 2024-08-19 02:51:49 JST; 17s ago
    TriggeredBy: ● systemd-journald-audit.socket
                 ● systemd-journald.path
                 ● systemd-journald.socket
                 ● systemd-journald-dev-log.socket
           Docs: man:systemd-journald.service(8)
                 man:journald.conf(5)
       Main PID: 23561 (systemd-journal)
         Status: "Processing requests..."
          Tasks: 1 (limit: 17537)
         Memory: 1.2M
            CPU: 17ms
         CGroup: /system.slice/systemd-journald.service
                 └─23561 /lib/systemd/systemd-journald
    
    Aug 19 02:51:49 ubuntu systemd-journald[23561]: Journal started
    Aug 19 02:51:49 ubuntu systemd-journald[23561]: System Journal (/var/log/journal/9d985ecbe7d846579fe4025d0221499d) is 64.0M, max 4.0G, 3.9G free.
    ```

# 参考
* [systemd.exec(5) — Linux manual page](https://man7.org/linux/man-pages/man5/systemd.exec.5.html)
* [Linuxシステムの仕組みと運用、管理](https://manual.atmark-techno.com/armadillo-guide/armadillo-guide-2_ja-2.1.0/ch03.html#sec_console_terminal)