Systemd

systemd 在啟動服務時忽略返回碼

  • July 18, 2019

我在為一個簡單的守護程序編寫單元文件時遇到了這個問題。當守護程序在啟動時返回“1”時,systemd 會忽略它,看起來守護程序已成功啟動,但實際上它已經死了。

例如,我有非常簡單的 shell 腳本:

#!/bin/bash
exit 1

所以單元文件看起來像這樣:

[Unit]
Description=test service
After=syslog.target

[Service]
User=testuser
Group=testuser
ExecStart=/usr/local/bin/return1

[Install]
WantedBy=multi-user.target

嘗試開始,似乎沒問題:

# service testservice start
# echo $?
0

但實際上它已經死了:

# service testservice status
● testservice.service - test service
  Loaded: loaded (/etc/systemd/system/testservice.service; enabled)
  Active: failed (Result: exit-code) since Fri 2016-01-22 14:51:45 MSK; 1min 13s ago
 Process: 16416 ExecStart=/usr/local/bin/return1 (code=exited, status=1/FAILURE)
Main PID: 16416 (code=exited, status=1/FAILURE)

Jan 22 14:51:45 servername systemd[1]: Started test service.
Jan 22 14:51:45 servername systemd[1]: testservice.service: main process exited, code=exited, status=1/FAILURE
Jan 22 14:51:45 servername systemd[1]: Unit testservice.service entered failed state.

看起來 systemd 認為守護程序已成功啟動,但後來崩潰了。

我試圖通過將服務類型更改為“分叉”等來解決這個問題 - 這在非零程式碼的情況下工作正常,但服務實際上是“簡單的”,所以在成功啟動的情況下,它只會保持並保持終端忙。

如何管理此類服務?或者可能有必要修復守護程式碼中的某些內容?

作業系統 debian 8 x64,systemd 215

systemd檢測程序是否成功啟動,您必須使用Type=forking,然後在幫助腳本中分叉您的程序,並在程序啟動成功時簽入該腳本。使用分叉systemd將等待ExecStart命令完成並檢查其退出狀態。

您應該像這樣更改您的單元文件:

[Unit]
Description=test service
After=syslog.target

[Service]
Type=forking
User=testuser
Group=testuser
ExecStart=/usr/local/bin/fork_service

[Install]
WantedBy=multi-user.target

/usr/local/bin/fork_service你應該有這樣的東西:

#!/bin/bash

# Run your process in background
/path/to/your_service &

# Check if the services started successfully 
if ! kill -0 $! 2>/dev/null; then
   # Return 1 so that systemd knows the service failed to start
   exit 1
fi

我在這裡只是檢查後台程序 PID 是否仍處於活動狀態,但您可以進行任何您想要的檢查。唯一重要的是,如果程序成功啟動,則此腳本以 0 退出,如果失敗,則以正的非零值退出。

此外,您不必使用 Bash 來分叉程序,您可以使用任何您想要的語言。

引用自:https://serverfault.com/questions/751030