Systemd

如何要求 systemd 服務在執行時重新載入其環境變數

  • October 7, 2016

問題

我的 C++ 應用程序作為 systemd 服務執行。我需要使用環境變數對其進行配置,並且能夠在執行時重新載入變數的值而無需重新啟動應用程序。

我創建了一個*.conf文件並在其中使用了Environment指令,並在更改**.conf*文件中的值後執行 daemon-reload 。但是服務沒有註意到變化。

我知道systemctl reload命令,但我不知道在ExecReload指令中設置什麼。

C++ 應用程式碼

#include <unistd.h>
#include <fstream>

using namespace std;

int main(int argc, char** argv)
{
   while (true)
   {
       char * cp = getenv("BAR");
       string s = "";
       if (cp)
           s = (string) cp;
       fstream fs;
       fs.open("/tmp/foo", ios_base::app);
       fs << s << endl;
       fs.close();
       sleep(1);
   }
   return 0;
}

服務說明

路徑:/etc/systemd/system/foo.service

[Unit]
Description=Testing configuration reloading

[Service]
ExecStart=/home/user/foo_application
Type=simple

[Install]
WantedBy=default.target

服務配置文件

路徑:/etc/systemd/system/foo.service.d/foo.conf

[Service]
Environment="BAR=2"

我以前的(重新)搜尋

https://serverfault.com/a/590732/379539

https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html

https://www.freedesktop.org/software/systemd/man/systemctl.html

創建程序時,環境被複製到程序的地址空間中。環境的變化只影響新啟動的程序,不能從外部改變正在執行的程序的環境。

您將需要某種程序間通信 (IPC) 機制來實現您想要實現的目標,或者只是簡單地將新值寫入文件並讓您的程序輪詢文件的內容。

除非您願意重新啟動正在考慮的服務(即終止正在執行的程序並啟動一個新程序),否則這是行不通的。環境變數是程序的一個單獨屬性,它們在啟動時從父程序繼承(即父程序forks時)。無法更改正在執行的程序的環境變數(不涉及通過 直接操作程序的記憶體等黑客行為/proc/pid/mem)。因此,即使喚醒程序SIGUSR1並讓它重新讀取其配置(正如許多服務和守護程序被實現的那樣)也無濟於事 - 程序將找到與以前完全相同的環境變數。

對於您要求的行為,我建議您考慮從文件中獲取配置參數。

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