From 2c0ec315503caef320c3c8baf521b64262e26ef6 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 21 Dec 2022 15:29:04 -0500 Subject: [PATCH] cmd/run: Ensure underlying container is stopped when toolbox is killed Right now "toolbox enter" creates a container on the fly, but then lets it linger after the foreground toolbox process is killed (for instance, from a terminal hangup). Not killing the underlying container has the negative side effect of stalling shutdown if a toolbox shell is running. This commit addresses that problem by detecting when the toolbox process is signaled, and then in response, kills off the entire cgroup associated with the underlying container. Closes https://github.com/containers/toolbox/issues/1157 Signed-off-by: Ray Strode --- src/cmd/run.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/cmd/run.go b/src/cmd/run.go index 25a8f7305..64ca61379 100644 --- a/src/cmd/run.go +++ b/src/cmd/run.go @@ -21,7 +21,9 @@ import ( "fmt" "io" "os" + "os/signal" "strings" + "syscall" "time" "github.com/containers/toolbox/pkg/podman" @@ -263,6 +265,30 @@ func runCommand(container string, return fmt.Errorf("invalid entry point PID of container %s", container) } + logrus.Debugf("Setting up monitor to stop container %s on termination", container) + signalChannel := make(chan os.Signal, 1) + signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) + + go func() { + signal := <-signalChannel + + logrus.Debugf("Got signal %d, killing cgroup", signal) + cgroupFilePath := fmt.Sprintf("/proc/%d/cgroup", entryPointPID) + cgroupId, err := os.ReadFile(cgroupFilePath) + if err != nil { + logrus.Debugf("Could not look up cgroup of container %s: %s", container, err) + return + } + + cgroup := strings.Trim(string(cgroupId), "0:/\n") + killPath := fmt.Sprintf("/sys/fs/cgroup/%s/cgroup.kill", cgroup) + + if err := os.WriteFile(killPath, []byte("1"), 0644); err != nil { + logrus.Debugf("Could not write 1 to %s: %s", killPath, err) + return + } + }() + logrus.Debugf("Waiting for container %s to finish initializing", container) toolboxRuntimeDirectory, err := utils.GetRuntimeDirectory(currentUser)