0

Question

My C++ application runs as a systemd service. I need to configure it using environment variables, and be able to reload the value of the variables during runtime without restarting the application.

I created a .conf file and used the Environment directive in it, and I execute daemon-reload after changing the value in the .conf file. But the service does not notice the change.

I know about the systemctl reload command, but I don't know what to set in the ExecReload directive.

C++ application code

#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;
}

Service description

Path: /etc/systemd/system/foo.service

[Unit]
Description=Testing configuration reloading

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

[Install]
WantedBy=default.target

Service configuration file

Path: /etc/systemd/system/foo.service.d/foo.conf

[Service]
Environment="BAR=2"

My previous (re)search

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

1

The environment is copied into the process' address space when the process is created. Changes in the environment only affect newly started processes, you can't change the environment of a running program from the outside.

You'll need some kind of interprocess communication (IPC) mechanism for what you are trying to achieve, or just simply write a new value into a file and have your program poll the contents of the file.

1

Unless you are willing to restart the service under consideration (i.e. terminate the running process and launch a new one), this won't work. Environment variables are an individual attribute of a process, they are inherited from the parent upon startup (i.e. when the parent process forks). There is no way to alter environment variables of running processes (not regarding hacks like directly manipulating the process' memory via /proc/pid/mem). Thus, even waking the process up by SIGUSR1 and having it reread its configuration (as many services and daemons are implemented to do) won't help - the process would find the very same environment variables as before.

For the behavior you ask for I suggest you consider to get configuration parameters from a file.

  • Thanks for your answer. Both yours and the previous one are valid answers. I accepted the previous one because it was posted first. But upvoted both of them (will be effective once I have 15 reputation on this site). – ferranrigual Oct 7 '16 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.