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

What is the way to avoid systemctl from killing one of my child processes on a stop?

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

sudo apt-get upgrade

但是,如果升级包括我自己(即说我有一个名为 server 的包,并且升级的一部分包括更新版本的 server,) 则升级失败。更准确地说,每当 dpkg 运行s preinst 脚本时,进程 运行ning 前面显示的命令被杀死,因为它 运行s 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...
}

根据 我了解到 systemd 将杀死(发送 SIGTERM)同一个 control-group.

中的所有子进程

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

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

您可以使用 systemd-run command.

要求 systemd 在新的控制组内启动进程