diff options
-rw-r--r-- | recipes-containers/runc/runc-docker/0001-runc-docker-SIGUSR1-daemonize.patch | 131 | ||||
-rw-r--r-- | recipes-containers/runc/runc-docker_git.bb | 1 |
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 @@ | |||
1 | From cd7d76a6d1ecb1856f6ed666fb5c30dc105aa94e Mon Sep 17 00:00:00 2001 | ||
2 | From: Jason Wessel <jason.wessel@windriver.com> | ||
3 | Date: Tue, 5 Dec 2017 18:28:28 -0800 | ||
4 | Subject: [PATCH] runc-docker: Allow "run start ..." to daemonize with $SIGUSR1_PARENT_PID | ||
5 | |||
6 | The runc-docker has all the code in it to properly run a stop hook if | ||
7 | you use it in the foreground. It doesn't work in the back ground | ||
8 | because there is no way for a golang application to fork a child exit | ||
9 | out of the parent process because all the golang threads stay with the | ||
10 | parent. | ||
11 | |||
12 | This patch has three parts that happen ONLY when $SIGUSR1_PARENT_PID | ||
13 | is set. | ||
14 | |||
15 | 1) The code was copied which performs the normal the signal handling | ||
16 | block which is used for the foreground operation of runc. | ||
17 | |||
18 | 2) 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 | |||
21 | 3) 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 | |||
26 | Signed-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 | |||
32 | diff --git a/src/import/signals.go b/src/import/signals.go | ||
33 | index 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 { | ||
116 | diff --git a/src/import/utils_linux.go b/src/import/utils_linux.go | ||
117 | index 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 | -- | ||
130 | 2.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 | ||
15 | RUNC_VERSION = "1.0.0-rc3" | 16 | RUNC_VERSION = "1.0.0-rc3" |