浏览代码

Add S6_CMD_RECEIVE_SIGNALS support, for ext signal diversion to CMD

Signed-off-by: Laurent Bercot <[email protected]>
Laurent Bercot 3 年之前
父节点
当前提交
a3ecae1d74

+ 11 - 1
README.md

@@ -861,7 +861,17 @@ by decreasing this number: 1 will only print warnings and errors, and 0 will onl
 print errors. You can also make the container _more_ verbose, i.e. print tracing and
 debug information, by increasing this number up to 5, but the output will quickly
 become _very_ noisy, and most people shouldn't need this.
-
+* `S6_CMD_RECEIVE_SIGNALS` (default = 0): decides whether signals sent to the
+container should be sent to the container's pid 1 or to the CMD. By default, when
+you perform for instance a `docker stop`, a TERM signal will be sent to the
+container's pid 1, which will trigger the full container shutdown sequence - but
+if a CMD is present, it will be among the last processes to be killed, only when
+everything else is down and the container is about to exit. If this variable is
+1 or more, signals are diverted from pid 1 to the CMD, which means that `docker stop`
+will send a SIGTERM to the CMD instead, and the container will only trigger its shutdown
+procedure when the CMD is dead. Note that only SIGTERM, SIGQUIT, SIGINT, SIGUSR1,
+SIGUSR2, SIGPWR and SIGWINCH are diverted; other signals either are ignored or
+cannot be diverted and are necessarily handled by pid 1.
 
 ### syslog
 

+ 7 - 0
layout/rootfs-overlay/package/admin/s6-overlay-@VERSION@/etc/s6-linux-init/skel/CMDSIG

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if pid=`cat /run/s6/cmdpid 2>/dev/null` ; then
+  kill -s "${0##*/SIG}" -- "$pid"
+else
+  exec "${0}.s6-linux-init"
+fi

+ 5 - 1
layout/rootfs-overlay/package/admin/s6-overlay-@VERSION@/etc/s6-linux-init/skel/rc.init

@@ -57,8 +57,12 @@ if test "$#" -gt 0 ; then
   cd `s6-cat < /run/s6/workdir`
   set +e
   arg0=`printcontenv S6_CMD_ARG0`
-  $arg0 "$@"
+  $arg0 "$@" &
+  cmdpid="$!"
+  echo "$cmdpid" > /run/s6/cmdpid
+  wait "$cmdpid"
   echo "$?" > /run/s6-linux-init-container-results/exitcode
   set -e
+  rm -f /run/s6/cmdpid
   exec /run/s6/basedir/bin/halt
 fi

+ 8 - 0
layout/rootfs-overlay/package/admin/s6-overlay-@VERSION@/libexec/stage0

@@ -74,6 +74,14 @@ if test -z "$dumpopt" ; then
   done
 fi
 
+if test "0$S6_CMD_RECEIVE_SIGNALS" -ne 0 ; then
+  ctldir="$basedir/run-image/service/.s6-svscan"
+  for sig in TERM QUIT INT USR1 USR2 PWR WINCH ; do
+    s6-rename "$ctldir/SIG$sig" "$ctldir/SIG$sig".s6-linux-init
+    s6-hiercopy /package/admin/s6-overlay/etc/s6-linux-init/skel/CMDSIG "$ctldir/SIG$sig"
+  done
+fi
+
 pwd > /run/s6/workdir
 
 exec "$basedir/bin/init" "$@"