supervision - discussion about system services, daemon supervision, init, runlevel management, and tools such as s6 and runit
 help / color / mirror / Atom feed
From: Raul <pkgsrc128@fastmail.us>
To: supervision@list.skarnet.org
Subject: runit-init inside docker container
Date: Fri, 09 Oct 2020 11:54:21 -0600	[thread overview]
Message-ID: <2725dea8-7bc6-47d4-b9a3-3fd372644392@www.fastmail.com> (raw)

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?

                 reply	other threads:[~2020-10-09 17:54 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2725dea8-7bc6-47d4-b9a3-3fd372644392@www.fastmail.com \
    --to=pkgsrc128@fastmail.us \
    --cc=supervision@list.skarnet.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).