web-dev-qa-db-ja.com

systemdサービススクリプトでPIDファイルを作成できません

RipRightをDebianにインストールしようとしています。Debianには、ビルド済みのパッケージがないようです。 PIDファイルを/runに書き込めないため、systemdスクリプトがデーモンとしてRipRightを開始/停止するように動作させることができません。

通常のconfigure/make/make installを行いました。また、riprightユーザー/グループを作成し、riprightcdromグループに追加しました。

/etc/systemd/system/ripright.serviceに配置したsystemdスクリプトは次のとおりです。

[Unit]
Description=RipRight

[Service]
Type=forking
PrivateTmp=yes
User=ripright
Group=ripright

RuntimeDirectory=ripright
RuntimeDirectoryMode=0750

ExecStart=/usr/local/bin/ripright \
    --daemon \
    --w32-filenames \
    --require-art \
    --folder-art folder.png \
    --output-file "%B/%D/%C - %N %T.flac" \
    "/opt/ripright/data"
PIDFile=/var/run/ripright/ripright.pid

[Install]
WantedBy=multi-user.target

スクリプトに最近追加されたRuntimeDirectoryディレクティブを使用して、riprightを所有者として/run/riprightフォルダーを作成しました。このディレクトリは、実行すると作成されます。

# systemctl daemon-reload
# systemctl start ripright

別のウィンドウで:

# ls -lhrt /run
...
drwxr-x---  2 ripright ripright   40 Jan  5 20:52 ripright
drwxr-xr-x 16 root     root      400 Jan  5 20:52 systemd
# ls -lahrt /run/ripright
total 0
drwxr-xr-x 16 root     root     540 Jan  5 20:52 ..
drwxr-x---  2 ripright ripright  40 Jan  5 20:52 .
# su - ripright
$ cd /run/ripright
$ pwd
/run/ripright
$ echo test > one.txt
$ cat one.txt
test
$ rm one.txt
$ exit

これが原因でsystemctl startコマンドが返らず、ハングします。 1分ほど経過すると、次のようにタイムアウトになります。

# systemctl start ripright
Job for ripright.service failed. See 'systemctl status ripright.service' and 'journalctl -xn' for details.

推奨コマンドの出力は次のとおりです。

# systemctl status ripright.service
● ripright.service - RipRight
   Loaded: loaded (/etc/systemd/system/ripright.service; enabled)
   Active: failed (Result: timeout) since Thu 2017-01-05 20:54:40 EST; 55s ago
  Process: 35396 ExecStart=/usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - %N %T.flac /opt/ripright/data (code=exited, status=0/SUCCESS)
 Main PID: 33287 (code=killed, signal=TERM)

Jan 05 20:53:10 ripperd ripright[35397]: Started daemon mode (v0.11)
Jan 05 20:53:10 ripperd ripright[35398]: Waiting for a CD (/dev/cdrom)
Jan 05 20:54:40 ripperd systemd[1]: ripright.service start operation timed out. Terminating.
Jan 05 20:54:40 ripperd systemd[1]: Failed to start RipRight.
Jan 05 20:54:40 ripperd systemd[1]: Unit ripright.service entered failed state.

# journalctl -xn
-- Logs begin at Thu 2017-01-05 00:30:29 EST, end at Thu 2017-01-05 20:54:40 EST. --
Jan 05 20:52:00 ripperd ripright[35380]: Waiting for a CD (/dev/cdrom)
Jan 05 20:52:59 ripperd su[35385]: Successful su for ripright by root
Jan 05 20:52:59 ripperd su[35385]: + /dev/pts/1 root:ripright
Jan 05 20:52:59 ripperd su[35385]: pam_unix(su:session): session opened for user ripright by vagrant(uid=0)
Jan 05 20:53:10 ripperd ripright[35397]: Started daemon mode (v0.11)
Jan 05 20:53:10 ripperd ripright[35398]: Waiting for a CD (/dev/cdrom)
Jan 05 20:53:33 ripperd su[35385]: pam_unix(su:session): session closed for user ripright
Jan 05 20:54:40 ripperd systemd[1]: ripright.service start operation timed out. Terminating.
Jan 05 20:54:40 ripperd systemd[1]: Failed to start RipRight.
-- Subject: Unit ripright.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit ripright.service has failed.
-- 
-- The result is failed.
Jan 05 20:54:40 ripperd systemd[1]: Unit ripright.service entered failed state.

SystemdサービススクリプトのPIDFileディレクティブをコメントアウトした場合:

#PIDFile=/var/run/ripright/ripright.pid

次に、問題はありませんが、フォークのサービスタイプで推奨されるPIDファイルもありません。

# systemctl daemon-reload
# systemctl start ripright
# ps -ef | grep ripright
ripright  35438      1  0 21:03 ?        00:00:00 /usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - ripright %T.flac /opt/ripright/data
ripright  35439  35438  0 21:03 ?        00:00:00 /usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - ripright %T.flac /opt/ripright/data
root      35442  31942  0 21:03 pts/0    00:00:00 grep ripright
root@ripperd:~# systemctl status ripright
● ripright.service - A minimal CD ripper for Linux modeled on autorip.
   Loaded: loaded (/etc/systemd/system/ripright.service; enabled)
   Active: active (running) since Thu 2017-01-05 21:03:11 EST; 13s ago
  Process: 35437 ExecStart=/usr/local/bin/ripright --daemon --w32-filenames --require-art --folder-art folder.png --output-file %B/%D/%C - %N %T.flac /opt/ripright/data (code=exited, status=0/SUCCESS)
 Main PID: 35438 (ripright)
   CGroup: /system.slice/ripright.service
           ├─35438 /usr/local/bin/ripright --daemon --w32-filenames --require...
           └─35439 /usr/local/bin/ripright --daemon --w32-filenames --require...

Jan 05 21:03:11 ripperd ripright[35438]: Started daemon mode (v0.11)
Jan 05 21:03:11 ripperd ripright[35439]: Waiting for a CD (/dev/cdrom)
# ls -la /run/ripright
total 0
drwxr-x---  2 ripright ripright  40 Jan  5 21:04 .
drwxr-xr-x 16 root     root     540 Jan  5 21:04 ..
# systemctl stop ripright

興味深いことに、PIDFilesを元に戻し、UserGroupをコメントアウトしてriprightをrootとして実行すると、デーモンの再読み込みとスクリプトの起動がまだハングします。

#User=ripright
#Group=ripright
PIDFile=/var/run/ripright/ripright.pid

UserGroupをコメント化したままにし、PIDFileを設定して/ runディレクトリに直接PIDファイルを生成する場合も同じことが起こります(/ var/runは単にDebian Jessieの/ runへのシンボリックリンク):

#User=ripright
#Group=ripright
#PIDFile=/var/run/ripright/ripright.pid
PIDFile=/run/ripright.pid

すべてのケースで、ハング中にCtrl + Cを押すことができ、Riprightデーモンは引き続き実行されます。ただし、開始タイムアウトを許可すると、デーモンが停止してからエラーが出力されて戻ります。

この投稿 とそのコメントも確認しました。 ExecStartPreを使用する最初のアプローチは同じ結果でした。再起動せずに変更を有効にする方法に関する情報が見つからなかったため、tmpfiles.dを使用することはできませんでした。 mount -aを試しましたが、うまくいきませんでした。

1
jia103

SystemdがデーモンのPIDファイルを作成するかどうかを尋ねている場合、次のようには作成されません。

https://www.freedesktop.org/software/systemd/man/systemd.service.html#PidFile=

PIDFile =

このデーモンのPIDファイルを指す絶対ファイル名を取ります。 Type =がforkingに設定されているサービスでは、このオプションの>を使用することをお勧めします。 systemdは、サービスの起動後にデーモンのメインプロセスのPIDを読み取ります。 systemdはここで設定されたファイルに書き込みませんが、サービスがまだ存在する場合は、サービスのシャットダウン後にファイルを削除します。

空白のままにして、GuessMainPID =を使用することをお勧めします。

4
Dale

残念ながら、systemdは、サービスのユニットファイルでPIDFile=行を指定しても、fork以外のサービスのPIDファイルを作成しません。ただし、次のようなExecStartPost=行でごまかすことができる場合があります。

ExecStartPost=/bin/sh -c 'umask 022; pgrep YOURSERVICE > /var/run/YOURSERVICE.pid'
3
Mike Gleason