現在、systemdデーモンを開発しています。私が直面している問題は、分岐が検出されないために、ビーイングが起動されてから1分30秒後にデーモンが強制終了されることです。
int daemon(int nochdir, int noclose)
を使用しています プロセスをデーモン化する関数。
int main()
{
openlog("shutdownd", LOG_PID, LOG_DAEMON);
if(daemon(0, 0) != 0)
{
syslog(LOG_ERR, "Error daemonizing process : %sn", strerror(errno));
exit(EXIT_FAILURE);
}
syslog(LOG_NOTICE, "Daemon started !n");
pthread_create(&threads[0], NULL, &alimThread, NULL);
pthread_create(&threads[1], NULL, &extinctThread, NULL);
pthread_create(&threads[2], NULL, &blinkThread, NULL);
while(1)
{
}
syslog(LOG_NOTICE, "Daemon stopped !n");
exit(EXIT_SUCCESS);
}
これがサービスファイル/etc/systemd/system/shutdownd.service
です
[Unit]
Description=Shutdown Daemon
After=syslog.target
[Service]
Type=forking
PIDFile=/var/run/shutdownd.pid
ExecStartPre=/bin/rm -f /var/run/shutdownd.pid
ExecStartPre=/usr/bin/shutdownd-exportGpio.sh
ExecStart=/usr/bin/shutdownd
Restart=on-abort
[Install]
WantedBy=multi-user.target
デーモン機能は、プロセスをフォークしてターミナルからデタッチすることになっています。また、ファイル記述子を閉じて、作業ディレクトリを/に変更します。
ただし、systemdは1分30秒後に実行中のデーモンを強制終了するため、フォークを検出しないようです。
Sep 8 13:52:50 raspberrypi systemd[1]: shutdownd.service: PID file /var/run/shutdownd.pid not readable (yet?) after start: No such file or directory
Sep 8 13:52:50 raspberrypi shutdownd[293]: Daemon started !
Sep 8 13:52:50 raspberrypi shutdownd[293]: [Extinct] Value changed to 0
Sep 8 13:52:50 raspberrypi shutdownd[293]: OFF
Sep 8 13:52:50 raspberrypi shutdownd[293]: [Alim] Value changed to 0
Sep 8 13:52:50 raspberrypi shutdownd[293]: OFF
Sep 8 13:53:46 raspberrypi shutdownd[293]: [Alim] Value changed to 1
Sep 8 13:53:46 raspberrypi shutdownd[293]: Toogle : ON
Sep 8 13:53:48 raspberrypi shutdownd[293]: Toogle : OFF
[...]
Sep 8 13:54:16 raspberrypi shutdownd[293]: [Extinct] Value changed to 1
Sep 8 13:54:16 raspberrypi shutdownd[293]: ON
Sep 8 13:54:20 raspberrypi systemd[1]: shutdownd.service: Start operation timed out. Terminating.
Sep 8 13:54:20 raspberrypi systemd[1]: shutdownd.service: Unit entered failed state.
Sep 8 13:54:20 raspberrypi systemd[1]: shutdownd.service: Failed with result 'timeout'.
systemdが分岐を検出しない理由についての手がかりとして誰かがいますか?
fork()
を明示的に呼び出す必要がありますか 私のコードでは?
この場合、daemonize関数を自分でコーディングする必要があります。これはそれほど難しくはありませんが、その目的のためにc関数がすでに存在するため、まったく役に立たず、冗長です。
承認された回答:
そうしないでください。
まったく。ライブラリ関数または独自のコードのローリングのいずれかを介して、そのいずれか。あらゆるサービス管理システムに。 1990年代以来、それは間違った考えでした。
あなたのデーモンはすでに サービスコンテキストで実行され、サービスマネージャーによってそのように呼び出されます。プログラムは何もしない必要があります この点において。そのようにプログラムを書くのはやめましょう。
また、forking
は使用しないでください 準備プロトコル。プログラムはマルチスレッドであり、forking
を追加しようとすると、ほぼ確実に正しく機能しません。 プロトコルを正しく制定することは後をフォークすることを意味するので、それに準備プロトコル すべてのスレッドの起動を含め、すべての初期化が完了しました。ほとんど何も実際には forking
を使用します 野生の準備プロトコル。別のプロトコルを使用してください。
さらに読む
- https://unix.stackexchange.com/a/200365/5132
- https://unix.stackexchange.com/a/194653/5132
- https://unix.stackexchange.com/a/211126/5132
- https://unix.stackexchange.com/a/336067/5132
- https://unix.stackexchange.com/a/283739/5132
- ジョナサンデボインポラード(2001)。 「「デーモンをバックグラウンドに置く」ためにfork()を実行しないでください。」 Unixデーモンプログラムを設計する際に避けるべき間違い 。頻繁に与えられる回答。
- ジョナサンデボインポラード(2015)。 実際にデーモン化する必要はありません。本当に。 。システム化されたHouseofHorror。
- ジョナサンデボインポラード(2015)。 Unixデーモンの準備プロトコルの問題 。頻繁に与えられる回答。