將 /etc/init.d 服務轉換為 systemd

將 /etc/init.d 服務轉換為 systemd

我正在將現有的 /etc/init.d 服務轉換為 systemd。它似乎有效,但我遇到了一個奇怪的問題。 systemd 服務將愉快地以命令“systemctl start service_name”啟動,並以“systemctl stop service_name”停止,但它似乎並沒有完全停止。底層應用程式檢查它是否已經在運行,如果是,則立即終止。這就是正在發生的事情。

以下是舊 /etc/init.d 腳本中的等效片段:

kill_process() {
    pkill -SIGINT service_name
    sleep 1
    if [ -n "$(pgrep service_name)" ]; then
        pkill -SIGTERM service_name
        sleep 1
    fi 
    if [ -n "$(pgrep service_name)" ]; then
        pkill -SIGKILL service_name
        sleep 1
    fi 
    if [ -z "$(pgrep service_name)" ]; then
        rm -f /var/lock/subsys/service_name
    fi
}

start() {
    action $"Starting Service: " /sbin/service_name
}

stop() {
    action $"Stopping Service: " kill_process
}

restart() {
    stop
    start
}

這是我對 systemd 等價物的初步嘗試:

[Unit]
Description=Service Name

[Service]
ExecStart=/sbin/service_name

[Install]
WantedBy=multi-user.target

我的理解是 systemd 服務將使用 SIGTERM 處理進程終止,但我已經嘗試了 KillSignal 和 ExecStop 的其他值。然而,我還沒有理解終止行為的這種差異。此外,如果我使用 SIGINT 手動終止應用程序,它也不會徹底終止服務。我想知道 /etc/init.d 是否在幕後做其他事情。

任何建議表示讚賞。

答案1

我只是想在這篇文章下方畫一條線,以防其他人有興趣。

如果 getppid() 尚未為 1(即尚未分叉),則作為服務一部分執行的 C 應用程式之前會使用 fork()。看起來,當應用程式由systemd 運行時,它的父PID 已經為1。 。我新增了一個特定的 SIGTERM 處理程序,該服務現在的行為符合預期。

相關內容