Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to launch a process outside a systemd control group

I have a server process (launched from systemd) which can launch an update process. The update process self-daemonizes itself and then (in theory) kills the server with SIGTERM. My problem is that the SIGTERM propagates to the update process and it's children.

For debugging purposes, the update process just sleeps, and I send the kill by hand.

Sample PS output before the kill:

    1  1869  1869  1869 ?           -1 Ss       0   0:00 /usr/local/bin/state_controller --start
 1869  1873  1869  1869 ?           -1 Sl       0   0:00  \_ ProcessWebController --start
 1869  1886  1869  1869 ?           -1 Z        0   0:00  \_ [UpdateSystem] <defunct>
    1  1900  1900  1900 ?           -1 Ss       0   0:00 /bin/bash /usr/local/bin/UpdateSystem refork /var/ttm/update.bin
 1900  1905  1900  1900 ?           -1 S        0   0:00  \_ sleep 10000

Note that UpdateSystem is in a separate PGID and TPGID. (The <defunct> process is a result of the daemonization, and is not (I think) a problem.)

UpdateSystem is a bash script (although I can easily make it a C program if that will help). After the daemonization code taken from https://stackoverflow.com/a/29107686/771073, the interesting bit is:

#############################################
trap "echo Ignoring SIGTERM" SIGTERM
sleep 10000
echo Awoken from sleep - presumably by the SIGTERM
exit 0

When I kill 1869 (which sends SIGTERM to the state_controller server process, my logfile contains:

Terminating
Ignoring SIGTERM
Awoken from sleep - presumably by the SIGTERM

I really want to prevent SIGTERM being sent to the sleep process.


(Actually, I really want to stop it being sent to apt-get upgrade which is stopping the system via the moral equivalent of systemctl stop ttm.service and the ExecStop is specified as /bin/kill $MAINPID - just in case that changes anyone's answer.)

This question is similar, but the accepted answer (use KillMode=process) doesn't work well for me - I want to kill some of the child processes, just not the update process: Can't detach child process when main process is started from systemd

like image 277
Martin Bonner supports Monica Avatar asked Feb 04 '16 11:02

Martin Bonner supports Monica


People also ask

What is Systemctl Cgroup?

Using cgroups for process managementsystemd collects related processes into control groups, called cgroups (short for control groups), and manages system resources for the cgroup as a whole. This means resources can be managed per application rather than by the individual processes that make up an application.

Is systemd the first process?

systemd is the first daemon to start during booting and the last daemon to terminate during shutdown. The systemd daemon serves as the root of the user space's process tree; the first process (PID 1) has a special role on Unix systems, as it replaces the parent of a process when the original parent terminates.

What is process systemd?

systemd is a system and service manager for Linux operating systems. When run as first process on boot (as PID 1), it acts as init system that brings up and maintains userspace services. Separate instances are started for logged-in users to start their services.


1 Answers

We were having exactly the same problem. What we ended up doing is launching the update process as transient cgroup with systemd-run:

systemd-run --unit=my_system_upgrade --scope --slice=my_system_upgrade_slice -E  setsid nohup start-the-upgrade &> /tmp/some-logs.log &

That way, the update process will run in a different cgroup and will not be terminated. Additionally, we use setsid + nohup to make sure the process has its own group and session and that the parent process is the init process.

like image 87
tsauerwein Avatar answered Oct 13 '22 22:10

tsauerwein