supervision - discussion about system services, daemon supervision, init, runlevel management, and tools such as s6 and runit
 help / color / mirror / Atom feed
* runit-init inside docker container
@ 2020-10-09 17:54 Raul
  0 siblings, 0 replies; only message in thread
From: Raul @ 2020-10-09 17:54 UTC (permalink / raw)
  To: supervision

Hello,
I was trying to get runit-init working inside a docker container as PID 1. The problem I'm running into is shutting down runit. I have the ctrlaltdel handler configured to `touch /etc/runint/stopit` && chmod 100. This causes runit to execute stage 3, and then try to `reboot_system(RB_POWER_OFF);` followed by `reboot_system(RB_HALT_SYSTEM);`.

Using strace I can see that the reboot_system calls are failing:

> write(2, "- runit: sending KILL signal to "..., 49) = 49
> kill(-1, SIGKILL)                       = -1 ESRCH (No such process)
> clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLDstrace: Process 838211 attached
 > <unfinished ...>
> [pid 838211] stat("/etc/runit/reboot",  <unfinished ...>
> [pid 826923] <... clone resumed>, child_tidptr=0x7f217fdff810) = 1351
> [pid 838211] <... stat resumed>0x7fffd71a8880) = -1 ENOENT (No such file or directory)
> [pid 826923] rt_sigprocmask(SIG_UNBLOCK, [CHLD],  <unfinished ...>
> [pid 838211] write(2, "- runit: power off...\n", 22 <unfinished ...>
> [pid 826923] <... rt_sigprocmask resumed>NULL, 8) = 0
> [pid 838211] <... write resumed>)       = 22
> [pid 826923] wait4(1351,  <unfinished ...>
> [pid 838211] sync()                     = 0
> [pid 838211] reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF) = -1 EPERM (Operation not permitted)
> [pid 838211] clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=2, tv_nsec=0}, 0x7fffd71a87f0) = 0
> [pid 838211] write(2, "- runit: system halt.\n", 22) = 22
> [pid 838211] sync()                     = 0
> [pid 838211] reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_HALT) = -1 EPERM (Operation not permitted)
> [pid 838211] exit_group(0)              = ?
> [pid 838211] +++ exited with 0 +++
> <... wait4 resumed>NULL, 0, NULL)       = 1351
> --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1351, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
> write(4, "\0", 1)                       = 1
> rt_sigreturn({mask=[HUP INT PIPE ALRM TERM CONT]}) = 1351
> rt_sigsuspend([], 8)                    = ? ERESTARTNOHAND (To be restarted if no handler)
> --- SIGURG {si_signo=SIGURG, si_code=SI_USER, si_pid=0, si_uid=0} ---


Trying /etc/runit/reboot, the LINUX_REBOOT_CMD_RESTART call also fails:

> write(2, "- runit: sending KILL signal to "..., 49) = 49
> kill(-1, SIGKILL)                       = -1 ESRCH (No such process)
> clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLDstrace: Process 843128 attached
> , child_tidptr=0x7f64972e7810) = 57
> [pid 842660] rt_sigprocmask(SIG_UNBLOCK, [CHLD], NULL, 8) = 0
> [pid 842660] wait4(57,  <unfinished ...>
> [pid 843128] stat("/etc/runit/reboot", {st_mode=S_IFREG|0100, st_size=0, ...}) = 0
> [pid 843128] write(2, "- runit: system reboot.\n", 24) = 24
> [pid 843128] sync()                     = 0
> [pid 843128] reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART) = -1 EPERM (Operation not permitted)
> [pid 843128] exit_group(0)              = ?
> [pid 843128] +++ exited with 0 +++
> <... wait4 resumed>NULL, 0, NULL)       = 57
> --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=57, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
> write(4, "\0", 1)                       = 1
> rt_sigreturn({mask=[HUP INT PIPE ALRM TERM CONT]}) = 57
> rt_sigsuspend([], 8

I think the correct behavior when running inside a PID namespace might be to `return`. We can determine if we are running inside a PID namespace if `/proc/1/ns/pid` exists.

> 5437036aeb1f / # stat /proc/1/ns/pid
>   File: /proc/1/ns/pid -> pid:[4026532181]

Outside of a pid namespce, the symlink doesn't exist.

I tried the following patch and runit now exits the container correctly:

--- src/runit.orig.c    2020-10-09 14:39:30.334482968 -0000
+++ src/runit.c 2020-10-09 14:45:58.457307181 -0000
@@ -299,6 +299,12 @@
   strerr_warn2(INFO, "sending KILL signal to all processes...", 0);
   kill(-1, SIGKILL);

+  /* If running in a PID namespace all we can do is exit */
+  if (stat("/proc/self/ns/pid", &s) != -1) {
+    strerr_warn2(INFO, "Exiting.", 0);
+    return(0);
+  }
+
   pid =fork();
   switch (pid) {
   case  0:

What are the thoughts on integrating this patch or something like it?

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-10-09 17:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-09 17:54 runit-init inside docker container Raul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).