Linux

Systemd 超時,因為它沒有檢測到守護程序分叉

  • September 17, 2021

我目前正在開發一個 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()我的程式碼嗎?
在這種情況下,我必須自己編寫 daemonize 函式,這並不難,但完全無用和多餘,因為為此目的已經存在 ac 函式。

不要那樣做。

完全沒有。任何一個,無論是通過庫函式還是滾動您自己的程式碼。適用於任何服務管理系統。自 1990 年代以來,這一直是一個錯誤的想法。

您的守護程序已經在服務上下文中執行,由服務管理器以這種方式呼叫。你的程序在這方面不應該做任何事情。完全停止以這種方式編寫程序。

並且不要使用forking就緒協議。您的程序是多執行緒的,如果您嘗試向其添加就緒協議,幾乎肯定無法正常執行forking,因為正確制定協議意味著在所有初始化完成分叉,包括啟動所有執行緒。幾乎沒有任何東西實際上forking在野外使用就緒協議。使用其他協議。

進一步閱讀

引用自:https://unix.stackexchange.com/questions/401590