什么方法可以避免systemctl在停止时杀死我的一个子进程?

时间:2016-07-20 02:15:03

标签: c++ process systemd

我一直在尝试通过运行简单的Debian升级命令在服务器内进行升级:

sudo apt-get upgrade

但是,如果该升级包括我自己(即我说有一个名为服务器的软件包,部分升级包括更新版本的服务器),则升级失败。更确切地说,每当dpkg运行preinst脚本时,运行前面显示的命令的进程就会被杀死,因为它运行systemctl stop server

代码执行如下操作:

// start with systemd
systemctl start server

// the server runs another daemon which manages the computer packages
// this is C++ code within server doing something like:
if(fork() == 0)
{
    execv("package_manager", ...);
}

// if I look at the output of systemctl status server, I see:
systemctl status server
  CGroup: server
          +-- package_manager

// then package_manager decides to do an upgrade, it starts a process
system("do_server_upgrade");

// in the do_server_upgrade code, I use fork() again to leave the
// existing set of daemons (server and package_manager)
int main()
{
    if(fork() != 0)
    {
        return 0;
    }
    setsid();
    signal(SIGHUP, SIG_IGN);
    ...run the commands to apply the upgrades...
}

根据this stackoverflow answer,我了解到systemd将在同一control-group中杀死(发送SIGTERM)所有子进程。

所以我认为这是服务器运行的所有其他守护进程的一个简洁功能...除了那个do_server_upgrade。换句话说,我希望保持这种方式(即KillMode=control-group),但看起来没有办法让子进程离开该控制组。

我的问题是:有人知道这种能力吗?我可以将服务设置为control-group并将某些流程从该控制组中删除吗?

1 个答案:

答案 0 :(得分:1)

您可以要求systemd使用systemd-run command在新控制组内启动流程。