aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch')
-rw-r--r--recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch131
1 files changed, 131 insertions, 0 deletions
diff --git a/recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch b/recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch
new file mode 100644
index 0000000..4350c40
--- /dev/null
+++ b/recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch
@@ -0,0 +1,131 @@
+From cd7d76a6d1ecb1856f6ed666fb5c30dc105aa94e Mon Sep 17 00:00:00 2001
+From: Jason Wessel <jason.wessel@windriver.com>
+Date: Tue, 5 Dec 2017 18:28:28 -0800
+Subject: [PATCH] runc-docker: Allow "run start ..." to daemonize with $SIGUSR1_PARENT_PID
+
+The runc-docker has all the code in it to properly run a stop hook if
+you use it in the foreground. It doesn't work in the back ground
+because there is no way for a golang application to fork a child exit
+out of the parent process because all the golang threads stay with the
+parent.
+
+This patch has three parts that happen ONLY when $SIGUSR1_PARENT_PID
+is set.
+
+1) The code was copied which performs the normal the signal handling
+ block which is used for the foreground operation of runc.
+
+2) At the point where runc start would normally exit, it closes
+ stdin/stdout/stderr so it would be possible to daemonize "runc start ...".
+
+3) The code to send a SIGUSR1 to the parent process was added. The
+ idea being that a parent process would simply exit at that point
+ because it was blocking until runc performed everything it was
+ required to perform.
+
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+---
+ signals.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
+ utils_linux.go | 2 +-
+ 2 files changed, 51 insertions(+), 5 deletions(-)
+
+Index: git/src/import/signals.go
+===================================================================
+--- git.orig/src/import/signals.go
++++ git/src/import/signals.go
+@@ -5,7 +5,9 @@
+ import (
+ "os"
+ "os/signal"
++ "syscall" // only for Signal
+
++ "strconv"
+ "github.com/opencontainers/runc/libcontainer"
+ "github.com/opencontainers/runc/libcontainer/system"
+ "github.com/opencontainers/runc/libcontainer/utils"
+@@ -55,9 +57,6 @@
+ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) {
+ // make sure we know the pid of our main process so that we can return
+ // after it dies.
+- if detach && h.notifySocket == nil {
+- return 0, nil
+- }
+
+ pid1, err := process.Pid()
+ if err != nil {
+@@ -67,12 +66,61 @@
+ if h.notifySocket != nil {
+ if detach {
+ _ = h.notifySocket.run(pid1)
+- return 0, nil
+ }
+ _ = h.notifySocket.run(os.Getpid())
+ go func() { _ = h.notifySocket.run(0) }()
+ }
+
++ if (detach) {
++ // This allows the parent process to daemonize this process
++ // so long as stdin/stderr/stdout are closed
++ if envVal := os.Getenv("SIGUSR1_PARENT_PID"); envVal != "" {
++ // Close stdin/stdout/stderr
++ os.Stdin.Close()
++ os.Stdout.Close()
++ os.Stderr.Close()
++ // Notify parent to detach
++ i, err := strconv.Atoi(envVal)
++ if (err != nil) {
++ return 0, nil
++ }
++ unix.Kill(i, unix.SIGUSR1)
++ // Loop waiting on the child to signal or exit,
++ // after which all stop hooks will be run
++ for s := range h.signals {
++ switch s {
++ case unix.SIGCHLD:
++ exits, err := h.reap()
++ if err != nil {
++ logrus.Error(err)
++ }
++ for _, e := range exits {
++ logrus.WithFields(logrus.Fields{
++ "pid": e.pid,
++ "status": e.status,
++ }).Debug("process exited")
++ if e.pid == pid1 {
++ // call Wait() on the process even though we already have the exit
++ // status because we must ensure that any of the go specific process
++ // fun such as flushing pipes are complete before we return.
++ process.Wait()
++ if h.notifySocket != nil {
++ h.notifySocket.Close()
++ }
++ return e.status, nil
++ }
++ }
++ default:
++ logrus.Debugf("sending signal to process %s", s)
++ if err := unix.Kill(pid1, s.(syscall.Signal)); err != nil {
++ logrus.Error(err)
++ }
++ }
++ }
++ }
++ return 0, nil
++ }
++
+ // Perform the initial tty resize. Always ignore errors resizing because
+ // stdout might have disappeared (due to races with when SIGHUP is sent).
+ _ = tty.resize()
+Index: git/src/import/utils_linux.go
+===================================================================
+--- git.orig/src/import/utils_linux.go
++++ git/src/import/utils_linux.go
+@@ -345,7 +345,7 @@
+ if err != nil {
+ r.terminate(process)
+ }
+- if detach {
++ if (detach && os.Getenv("SIGUSR1_PARENT_PID") == "") {
+ return 0, nil
+ }
+ if err == nil {