summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch131
-rw-r--r--recipes-containers/runc/runc-docker_git.bb1
2 files changed, 132 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 00000000..b3bd0680
--- /dev/null
+++ b/recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch
@@ -0,0 +1,131 @@
1From cd7d76a6d1ecb1856f6ed666fb5c30dc105aa94e Mon Sep 17 00:00:00 2001
2From: Jason Wessel <jason.wessel@windriver.com>
3Date: Tue, 5 Dec 2017 18:28:28 -0800
4Subject: [PATCH] runc-docker: Allow "run start ..." to daemonize with $SIGUSR1_PARENT_PID
5
6The runc-docker has all the code in it to properly run a stop hook if
7you use it in the foreground. It doesn't work in the back ground
8because there is no way for a golang application to fork a child exit
9out of the parent process because all the golang threads stay with the
10parent.
11
12This patch has three parts that happen ONLY when $SIGUSR1_PARENT_PID
13is set.
14
151) The code was copied which performs the normal the signal handling
16 block which is used for the foreground operation of runc.
17
182) At the point where runc start would normally exit, it closes
19 stdin/stdout/stderr so it would be possible to daemonize "runc start ...".
20
213) The code to send a SIGUSR1 to the parent process was added. The
22 idea being that a parent process would simply exit at that point
23 because it was blocking until runc performed everything it was
24 required to perform.
25
26Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
27---
28 signals.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
29 utils_linux.go | 2 +-
30 2 files changed, 51 insertions(+), 5 deletions(-)
31
32diff --git a/src/import/signals.go b/src/import/signals.go
33index 910ea1ee..b6a23476 100644
34--- a/src/import/signals.go
35+++ b/src/import/signals.go
36@@ -6,6 +6,7 @@ import (
37 "os"
38 "os/signal"
39 "syscall" // only for Signal
40+ "strconv"
41
42 "github.com/Sirupsen/logrus"
43 "github.com/opencontainers/runc/libcontainer"
44@@ -56,9 +57,6 @@ type signalHandler struct {
45 func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) {
46 // make sure we know the pid of our main process so that we can return
47 // after it dies.
48- if detach && h.notifySocket == nil {
49- return 0, nil
50- }
51
52 pid1, err := process.Pid()
53 if err != nil {
54@@ -68,12 +66,60 @@ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach
55 if h.notifySocket != nil {
56 if detach {
57 h.notifySocket.run(pid1)
58- return 0, nil
59 } else {
60 go h.notifySocket.run(0)
61 }
62 }
63
64+ if (detach) {
65+ // This allows the parent process to daemonize this process
66+ // so long as stdin/stderr/stdout are closed
67+ if envVal := os.Getenv("SIGUSR1_PARENT_PID"); envVal != "" {
68+ // Close stdin/stdout/stderr
69+ os.Stdin.Close()
70+ os.Stdout.Close()
71+ os.Stderr.Close()
72+ // Notify parent to detach
73+ i, err := strconv.Atoi(envVal)
74+ if (err != nil) {
75+ return 0, nil
76+ }
77+ unix.Kill(i, unix.SIGUSR1)
78+ // Loop waiting on the child to signal or exit,
79+ // after which all stop hooks will be run
80+ for s := range h.signals {
81+ switch s {
82+ case unix.SIGCHLD:
83+ exits, err := h.reap()
84+ if err != nil {
85+ logrus.Error(err)
86+ }
87+ for _, e := range exits {
88+ logrus.WithFields(logrus.Fields{
89+ "pid": e.pid,
90+ "status": e.status,
91+ }).Debug("process exited")
92+ if e.pid == pid1 {
93+ // call Wait() on the process even though we already have the exit
94+ // status because we must ensure that any of the go specific process
95+ // fun such as flushing pipes are complete before we return.
96+ process.Wait()
97+ if h.notifySocket != nil {
98+ h.notifySocket.Close()
99+ }
100+ return e.status, nil
101+ }
102+ }
103+ default:
104+ logrus.Debugf("sending signal to process %s", s)
105+ if err := unix.Kill(pid1, s.(syscall.Signal)); err != nil {
106+ logrus.Error(err)
107+ }
108+ }
109+ }
110+ }
111+ return 0, nil
112+ }
113 // perform the initial tty resize.
114 tty.resize()
115 for s := range h.signals {
116diff --git a/src/import/utils_linux.go b/src/import/utils_linux.go
117index e6d31b35..1bb80a63 100644
118--- a/src/import/utils_linux.go
119+++ b/src/import/utils_linux.go
120@@ -308,7 +308,7 @@ func (r *runner) run(config *specs.Process) (int, error) {
121 if err != nil {
122 r.terminate(process)
123 }
124- if detach {
125+ if (detach && os.Getenv("SIGUSR1_PARENT_PID") == "") {
126 return 0, nil
127 }
128 r.destroy()
129--
1302.11.0
131
diff --git a/recipes-containers/runc/runc-docker_git.bb b/recipes-containers/runc/runc-docker_git.bb
index 9db48ee6..f31b82ec 100644
--- a/recipes-containers/runc/runc-docker_git.bb
+++ b/recipes-containers/runc/runc-docker_git.bb
@@ -10,6 +10,7 @@ SRC_URI = "git://github.com/docker/runc.git;nobranch=1;name=runc-docker \
10 file://0001-runc-Add-console-socket-dev-null.patch \ 10 file://0001-runc-Add-console-socket-dev-null.patch \
11 file://0001-Use-correct-go-cross-compiler.patch \ 11 file://0001-Use-correct-go-cross-compiler.patch \
12 file://0001-Disable-building-recvtty.patch \ 12 file://0001-Disable-building-recvtty.patch \
13 file://0001-runc-docker-SIGUSR1-daemonize.patch \
13 " 14 "
14 15
15RUNC_VERSION = "1.0.0-rc3" 16RUNC_VERSION = "1.0.0-rc3"