systemdでリアルタイムプロセスを動かす

## systemdでJACK Audio Connection Kitを動かす

jackdをsystemdで稼働させる際に、リアルタイムが有効にできなかったため苦労しました。
ログインコンソール上で以下のコマンドで動かすと、リアルタイムが有効になった状態でjackdが稼働します。

```shell-session
$ /usr/local/bin/jackd -R -P89 -dalsa -dhw:0 -r48000 -p256 -n3
```

systemdで動かすために、以下のユニットファイルを作成し稼働させてみました。

```:/etc/systemd/system/jackd.service
[Unit]
Description=JACK 2

[Service]
Type=simple
ExecStart=/usr/local/bin/jackd -R -P83 -dalsa -dhw:sndrpiwsp -r48000 -p256 -n3
User=hoge
Group=audio

[Install]
WantedBy=multi-user.target
```
```:jackdログ
Jan 01 00:18:22 raspberry jackd[724]: jackdmp 1.9.11
Jan 01 00:18:22 raspberry jackd[724]: Copyright 2001-2005 Paul Davis and others.
Jan 01 00:18:22 raspberry jackd[724]: Copyright 2004-2016 Grame.
Jan 01 00:18:22 raspberry jackd[724]: jackdmp comes with ABSOLUTELY NO WARRANTY
Jan 01 00:18:22 raspberry jackd[724]: This is free software, and you are welcome to redistribute it
Jan 01 00:18:22 raspberry jackd[724]: under certain conditions; see the file COPYING for details
```

リアルタイムが有効でないために、正しく稼働していません。

## リソース制限について

リアルタイムプロセスを稼働させるためには、リソース制限が必要です。
"JACK Audio Connection Kit"で必要な設定としては、limits.confが必要で下記の通り書いてます。

```:/etc/security/limits.d/99-audio.conf
@audio - memlock unlimited
@audio - rtprio 95
```

しかし、リソース制限は"pam_limits.so"の認証を受けたプロセスしか制限できません。
"pam_limits.so"が有効なログインは、

```shell-session
$ grep pam_limits.so /etc/pam.d/*
/etc/pam.d/cron:session     required   pam_limits.so
/etc/pam.d/login:session    required   pam_limits.so
/etc/pam.d/runuser:session  required   pam_limits.so
/etc/pam.d/sshd:session     required   pam_limits.so
/etc/pam.d/su:session       required   pam_limits.so
```

ですので、systemdで動かすためには"runuser”で動かすべきかと思ったんですが…

## systemdでのリソース制限

systemd以下のプロセスでのリソース制限は、systemdで行うべきことを途中で気づきユニットファイルを書き換えてみました。

```:/etc/systemd/system/jackd.service
[Unit]
Description=JACK 2

[Service]
Type=simple
LimitRTPRIO=95
LimitMEMLOCK=infinity
ExecStart=/usr/local/bin/jackd -R -P83 -dalsa -dhw:sndrpiwsp -r48000 -p256 -n3
User=hoge
Group=audio

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

"systemctl daemon-reload","systemctl restart jackd"としたところ、リアルタイムが有効になった状態で起動できました。

```:jackdログ
Jan 01 00:19:36 raspberry jackd[804]: jackdmp comes with ABSOLUTELY NO WARRANTY
Jan 01 00:19:36 raspberry jackd[804]: This is free software, and you are welcome to redistribute it
Jan 01 00:19:36 raspberry jackd[804]: under certain conditions; see the file COPYING for details
Jan 01 00:19:36 raspberry jackd[804]: JACK server starting in realtime mode with priority 83
Jan 01 00:19:36 raspberry jackd[804]: self-connect-mode is "Don't restrict self connect requests"
Jan 01 00:19:37 raspberry jackd[804]: creating alsa driver ... hw:sndrpiwsp|hw:sndrpiwsp|256|3|48000|0|0|nomon|swmeter|-|32bit
Jan 01 00:19:37 raspberry jackd[804]: configuring for 48000Hz, period = 256 frames (5.3 ms), buffer = 3 periods
Jan 01 00:19:37 raspberry jackd[804]: ALSA: final selected sample format for capture: 32bit integer little-endian
Jan 01 00:19:37 raspberry jackd[804]: ALSA: use 3 periods for capture
Jan 01 00:19:37 raspberry jackd[804]: ALSA: final selected sample format for playback: 32bit integer little-endian
Jan 01 00:19:37 raspberry jackd[804]: ALSA: use 3 periods for playback
```

コンソールログインでは稼働するが、systemdでデーモン化したら動かないケースはリソース制限を疑ってみると良いかもしれません。