web-dev-qa-db-ja.com

デーモンフォークを検出しないため、systemdタイムアウト

私は現在、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 : %s\n", 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()を明示的に呼び出す必要がありますか?
この場合、私はデーモン化関数を自分でコーディングする必要があります。これはそれほど難しくはありませんが、c関数がその目的ですでに存在するため、まったく役に立たず、冗長です。

3
Arkaik

やめてください。

全然。ライブラリ関数を介して、または独自のコードをローリングして、そのいずれか。任意のサービス管理システム。 1990年代以来、それは間違った考えでした。

あなたのデーモンは、すでにサービスコンテキストで実行されており、サービスマネージャーによってその方法で呼び出されます。この点に関して、プログラムは何もしない必要があります。そのようにプログラムを書くのをやめてください。

また、forking準備プロトコルは使用しないでください。プログラムはマルチスレッド化されており、forkingレディネスプロトコルをプログラムに追加しようとすると、ほぼ確実に正しく機能しません。プロトコルを正しく実行すると、afterすべてのスレッドの起動を含め、すべての初期化が完了しました。ほとんど何も実際には_forking準備プロトコルを実際に使用していません。別のプロトコルを使用してください。

参考文献

7
JdeBP