diff --git a/api/server/init.go b/api/server/init.go index e02403d40..d09104110 100644 --- a/api/server/init.go +++ b/api/server/init.go @@ -4,10 +4,13 @@ import ( "context" "os" "os/signal" + "runtime" "strconv" + "syscall" "github.com/fnproject/fn/api/common" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" ) func init() { @@ -55,3 +58,34 @@ func contextWithSignal(ctx context.Context, signals ...os.Signal) (context.Conte }() return newCTX, halt } + +// Installs a child process reaper if init process +func installChildReaper() { + // assume responsibilities of init process if running as init process for Linux + if runtime.GOOS != "linux" || os.Getpid() != 1 { + return + } + + var sigs = make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGCHLD) + + // we run this forever and leak a go routine. As init, we must + // reap our children until the very end, so this is OK. + go func() { + for { + <-sigs + for { + var status syscall.WaitStatus + var rusage syscall.Rusage + + pid, err := syscall.Wait4(-1, &status, syscall.WNOHANG, &rusage) + // no children + if pid <= 0 { + break + } + + logrus.Infof("Child terminated pid=%d err=%v status=%v usage=%v", pid, err, status, rusage) + } + } + }() +} diff --git a/api/server/server.go b/api/server/server.go index 1081a8681..acfa08e31 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -394,6 +394,8 @@ func (s *Server) startGears(ctx context.Context, cancel context.CancelFunc) { logrus.WithField("type", s.nodeType).Infof("Fn serving on `%v`", listen) + installChildReaper() + server := http.Server{ Addr: listen, Handler: s.Router, diff --git a/images/dind/preentry.sh b/images/dind/preentry.sh index 405ba7065..4d81d7fb2 100755 --- a/images/dind/preentry.sh +++ b/images/dind/preentry.sh @@ -1,5 +1,5 @@ #!/bin/sh -set -e +set -euo pipefail fsdriver=$(grep -Eh -w -m1 "overlay|aufs" /proc/filesystems | cut -f2) if [ $fsdriver == "overlay" ]; then @@ -10,6 +10,8 @@ mtu=$(ip link show dev $(ip route | awk '$1 == "default" { print $NF }') | awk '{for (i = 1; i <= NF; i++) if ($i == "mtu") print $(i+1)}') +# activate job control, prevent docker process from receiving SIGINT +set -m dockerd-entrypoint.sh --storage-driver=$fsdriver --mtu=$mtu & # give docker a few seconds