Package: runit Version: 2.1.2-39.1 Severity: normal Tags: upstream Hi,
runsv(8) says: CUSTOMIZE CONTROL For each control character c sent to the control pipe, runsv first checks if service/control/c exists and is executable. If so, it starts service/control/c and waits for it to terminate, before interpreting the command. If the program exits with return code 0, runsv refrains from sending the service the corresponding signal. The command o is always considered as command u. On command d first service/control/t is checked, and then service/control/d. On command x first service/control/t is checked, and then service/control/x. The control of the optional log service cannot be customized. This is, however, not what the code actually does. For the 'd' control character (https://github.com/vulk-archive/runit/blob/master/src/runsv.c#L324): case 'd': /* down */ s->want =W_DOWN; update_status(s); if (s->state == S_RUN) stopservice(s); break; 'x' is handled analogously. The stopservice() function (https://github.com/vulk-archive/runit/blob/master/src/runsv.c#L246) looks like this: void stopservice(struct svdir *s) { if (s->pid && ! custom(s, 't')) { kill(s->pid, SIGTERM); s->ctrl |=C_TERM; update_status(s); } if (s->want == W_DOWN) { kill(s->pid, SIGCONT); custom(s, 'd'); return; } if (s->want == W_EXIT) { kill(s->pid, SIGCONT); custom(s, 'x'); } } i.e. the control/d or control/x script is only run after runsv sent its child a SIGTERM, not before as the manpage suggests. I would suggest that the code should be changed to reflect the documented behaviour, not vice versa. Perhaps the following code would work (but I have not tested it): void stopservice(struct svdir *s) { if (s->pid) { if (s->want == W_DOWN) { kill(s->pid, SIGCONT); if (custom(s, 'd')) return; } if (s->want == W_EXIT) { kill(s->pid, SIGCONT); if (custom(s, 'x')) return; } if (! custom(s, 't')) { kill(s->pid, SIGTERM); s->ctrl |=C_TERM; update_status(s); } } } Credits to https://serverfault.com/users/135556/keith for pointing the bug out. Best regards, AndrĂ¡s -- System Information: Debian Release: bullseye/sid APT prefers unstable APT policy: (350, 'unstable'), (350, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 5.10.0-3-amd64 (SMP w/8 CPU threads) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=hu_HU.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 Shell: /bin/sh linked to /bin/bash Init: runit (via /run/runit.stopit) LSM: AppArmor: enabled Versions of packages runit depends on: ii libc6 2.31-9 ii sysuser-helper 1.3.5.1 Versions of packages runit recommends: ii runit-init 2.1.2-39.1 Versions of packages runit suggests: ii socklog 2.1.0+repack-4+b1 -- Configuration Files: /etc/runit/1 changed [not included] /etc/runit/2 changed [not included] /etc/runit/3 changed [not included] -- no debconf information -- Laughing stock: cattle with a sense of humour.