[meta-virtualization] [PATCH] runc-docker: Allow "run start ..." to daemonize with $SIGUSR1_PARENT_PID
Bruce Ashfield
bruce.ashfield at gmail.com
Sun Dec 10 19:38:56 PST 2017
On Fri, Dec 8, 2017 at 10:53 AM, Jason Wessel <jason.wessel at windriver.com>
wrote:
> 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.
>
Can you define background for the commit log purposes ? Is it a container
that allocates a tty and detaches from the current terminal ? Something
else ?
Also why does the threads staying with the parent mean the stop hooks
don't run. That isn't clear to me. Is it due to lack of notification if
they exit ?
>
> This patch has three parts that happen ONLY when $SIGUSR1_PARENT_PID
> is set.
>
Where do you see that environment variable being set ? In the config.json ?
Somewhere else ? (i.e. the launching environment).
>
> 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
> ...".
>
I can't say I completely follow point #2. Maybe it is with me not having
looked at what is required to daemonize for a loooong time.
See one question on the patch below.
> 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 at windriver.com>
> ---
> .../0001-runc-docker-SIGUSR1-daemonize.patch | 131
> +++++++++++++++++++++
> recipes-containers/runc/runc-docker_git.bb | 1 +
> 2 files changed, 132 insertions(+)
> create mode 100644 recipes-containers/runc/runc-docker/0001-runc-docker-
> SIGUSR1-daemonize.patch
>
> 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..b3bd068
> --- /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 at 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 at windriver.com>
> +---
> + signals.go | 54 ++++++++++++++++++++++++++++++
> ++++++++++++++++++++----
> + utils_linux.go | 2 +-
> + 2 files changed, 51 insertions(+), 5 deletions(-)
> +
> +diff --git a/src/import/signals.go b/src/import/signals.go
> +index 910ea1ee..b6a23476 100644
> +--- a/src/import/signals.go
> ++++ b/src/import/signals.go
> +@@ -6,6 +6,7 @@ import (
> + "os"
> + "os/signal"
> + "syscall" // only for Signal
> ++ "strconv"
> +
> + "github.com/Sirupsen/logrus"
> + "github.com/opencontainers/runc/libcontainer"
> +@@ -56,9 +57,6 @@ type signalHandler struct {
> + 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 {
> +@@ -68,12 +66,60 @@ func (h *signalHandler) forward(process
> *libcontainer.Process, tty *tty, detach
> + if h.notifySocket != nil {
> + if detach {
> + h.notifySocket.run(pid1)
> +- return 0, nil
> + } else {
> + go 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
> ++ }
>
So all the code below here is the copied block and it deals with the
normal exit ? i.e. is it shutting the container down ?
The reason I ask, is that I thought this block of code was running on
startup, when the container first detaches .. and it didn't make sense
in that context.
Bruce
> ++ 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.
> + tty.resize()
> + for s := range h.signals {
> +diff --git a/src/import/utils_linux.go b/src/import/utils_linux.go
> +index e6d31b35..1bb80a63 100644
> +--- a/src/import/utils_linux.go
> ++++ b/src/import/utils_linux.go
> +@@ -308,7 +308,7 @@ func (r *runner) run(config *specs.Process) (int,
> error) {
> + if err != nil {
> + r.terminate(process)
> + }
> +- if detach {
> ++ if (detach && os.Getenv("SIGUSR1_PARENT_PID") == "") {
> + return 0, nil
> + }
> + r.destroy()
> +--
> +2.11.0
> +
> diff --git a/recipes-containers/runc/runc-docker_git.bb
> b/recipes-containers/runc/runc-docker_git.bb
> index 9db48ee..f31b82e 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 \
> file://0001-runc-Add-console-socket-dev-null.patch \
> file://0001-Use-correct-go-cross-compiler.patch \
> file://0001-Disable-building-recvtty.patch \
> + file://0001-runc-docker-SIGUSR1-daemonize.patch \
> "
>
> RUNC_VERSION = "1.0.0-rc3"
> --
> 2.11.0
>
> --
> _______________________________________________
> meta-virtualization mailing list
> meta-virtualization at yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-virtualization
>
--
"Thou shalt not follow the NULL pointer, for chaos and madness await thee
at its end"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.yoctoproject.org/pipermail/meta-virtualization/attachments/20171210/f1804efa/attachment-0001.html>
More information about the meta-virtualization
mailing list