-1

The program processA is a Linux service, launched by "systemctl start processA".
This process will call std::system to run a shell script to upgrade software.
The script will run "systemctl" to stop processA first, then replace some executable files, finally restart processA.

The problem is that when "systemctl stop processA" is executed, the script is also terminated.
How to solve it?

I had tried to run the script file in terminal; it works. So there is not a problem with the script.

  //this is how the script is called
  int rs = std::system("/usr/bin/update_server.sh upgrade \"/tmp/firmware\" > \"/tmp/upgrade.log\" 2>&1");
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jason Wang
  • 14
  • 3
  • You probably need to establish which signals `systemctl stop processA` sends to the child processes, and then arrange for the script to ignore those signals. If `systemctl` is insistent, it may send a crescendo of signals, such as `SIGHUP`, `SIGTERM` and finally `SIGKILL`. If it gets stroppy enough to send `SIGKILL`, there's nothing your script can do, but `SIGHUP` and `SIGTERM` could be ignored, allowing the script to continue (and replace the executables), then run `systemctl start processA` again. Step 1 is to record which signals are sent (if possible). Then you can deal with it. – Jonathan Leffler Jun 28 '19 at 07:22
  • If the manual page for [`systemctl`](http://man7.org/linux/man-pages/man1/systemctl.1.html) is to be trusted, the `-s` option specifies which signal is to be sent, and the default is `SIGTERM`. – Jonathan Leffler Jun 28 '19 at 07:31

1 Answers1

0

systemd will also kill child processes (after all, that's what's usually desired), so you can't do the upgrade from the service.

You can, however create a oneshot service to upgrade the binary that conflicts with the main service. To upgrade, you stop the service, run the upgrade service and then start the service again.

tstenner
  • 10,080
  • 10
  • 57
  • 92