浏览代码

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
 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
 debug information, by increasing this number up to 5, but the output will quickly
 become _very_ noisy, and most people shouldn't need this.
 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
 ### 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`
   cd `s6-cat < /run/s6/workdir`
   set +e
   set +e
   arg0=`printcontenv S6_CMD_ARG0`
   arg0=`printcontenv S6_CMD_ARG0`
-  $arg0 "$@"
+  $arg0 "$@" &
+  cmdpid="$!"
+  echo "$cmdpid" > /run/s6/cmdpid
+  wait "$cmdpid"
   echo "$?" > /run/s6-linux-init-container-results/exitcode
   echo "$?" > /run/s6-linux-init-container-results/exitcode
   set -e
   set -e
+  rm -f /run/s6/cmdpid
   exec /run/s6/basedir/bin/halt
   exec /run/s6/basedir/bin/halt
 fi
 fi

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

@@ -74,6 +74,14 @@ if test -z "$dumpopt" ; then
   done
   done
 fi
 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
 pwd > /run/s6/workdir
 
 
 exec "$basedir/bin/init" "$@"
 exec "$basedir/bin/init" "$@"