Home > Net >  Using boost::process to completely detach a process
Using boost::process to completely detach a process

Time:09-06

I have a systemd service which runs and does its thing. Periodically I need it to upgrade itself, which requires a shutdown and a restart of the service. For question purposes the upgrade script can be as simple as:

echo "Stopping service..."
systemctl stop myservice
echo "Doing some stuff..."
sleep 10s
echo "Starting service..."
systemctl start myservice

I want to call this within the service itself, preferably using boost::process:

boost::process::child instexe{
    boost::process::search_path("bash"), 
    std::vector<std::string>{"installerscript.sh"},
    boost::process::start_dir("/installer/folder"),
    boost::process::std_out > "/some/log/file.txt"
};
instexe.detach();

The problem is that as soon as the script calls systemctl stop myservice, the installer script is killed.

Is there a way I can do what I want to do with boost::process? Or how can I do it?

CodePudding user response:

If the upgrades are at predefined period you can think of using crontab. https://opensource.com/article/17/11/how-use-cron-linux

00 09-17 * * 1-5 /usr/local/bin/installerScript.sh

The above entry in crontab will make the program upgrade every hour between 9 am to 5pm from Monday to Friday. There are many combinations that you can think and configure.

CodePudding user response:

Is there a way I can do what I want to do with boost::process? Or how can I do it?

If you have the child process killing the parent, there's always going to be a race condition by definition.

The quick hack is to put a sleep statement at the start of the installer script, but the correct solution is to explicitly synchronize with the child:

  1. have the installer script detect whether it's running interactively (ie, being run manually from a terminal instead of by your service)
  2. if it is non-interactive (your use case), have it wait for some input in stdin
  3. connect the stdin pipe when you create the child
  4. detach the child and then write something to tell the child it's safe

Other synchronization mechanisms are available, you could use a lockfile or a signal - you just need to make sure the child doesn't do anything until after the parent has detached it.

It may be sufficient to just use bp::spawn, but it's not obvious from the documentation that is race-free in this situation.

You should probably create a process group for the child as well, in case systemd kills the whole group when it stops a service.

  • Related