From b2d5924e106c2f17c23d5e8211cefcb7085a4836 Mon Sep 17 00:00:00 2001 From: lifubang Date: Wed, 5 Mar 2025 09:46:24 +0000 Subject: [PATCH 1/2] skip setup signal notifier for detached container For detached container, we don't need to setup signal notifier, because there is no customer to consume the signals in `forward()`. Signed-off-by: lifubang --- signals.go | 13 +++++++++++-- utils_linux.go | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/signals.go b/signals.go index a992dc4abeb..a195d801145 100644 --- a/signals.go +++ b/signals.go @@ -18,14 +18,23 @@ const signalBufferSize = 2048 // while still forwarding all other signals to the process. // If notifySocket is present, use it to read systemd notifications from the container and // forward them to notifySocketHost. -func newSignalHandler(enableSubreaper bool, notifySocket *notifySocket) chan *signalHandler { +func newSignalHandler(enableSubreaper bool, detach bool, notifySocket *notifySocket) chan *signalHandler { if enableSubreaper { // set us as the subreaper before registering the signal handler for the container if err := system.SetSubreaper(1); err != nil { logrus.Warn(err) } } - handler := make(chan *signalHandler) + handler := make(chan *signalHandler, 1) + // For detached container, we don't need to setup signal notifier, because + // there is no customer to consume the signals in `forward()`. + if detach { + handler <- &signalHandler{ + signals: nil, + notifySocket: notifySocket, + } + return handler + } // signal.Notify is actually quite expensive, as it has to configure the // signal mask and add signal handlers for all signals (all ~65 of them). // So, defer this to a background thread while doing the rest of the io/tty diff --git a/utils_linux.go b/utils_linux.go index 7de93340a94..ac22b0cf1de 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -252,7 +252,7 @@ func (r *runner) run(config *specs.Process) (int, error) { // Setting up IO is a two stage process. We need to modify process to deal // with detaching containers, and then we get a tty after the container has // started. - handlerCh := newSignalHandler(r.enableSubreaper, r.notifySocket) + handlerCh := newSignalHandler(r.enableSubreaper, detach, r.notifySocket) tty, err := setupIO(process, r.container, config.Terminal, detach, r.consoleSocket) if err != nil { return -1, err From efcbaaac3049d99a887bb4620d26332b5f4accc3 Mon Sep 17 00:00:00 2001 From: lifubang Date: Fri, 7 Mar 2025 05:10:19 +0000 Subject: [PATCH 2/2] refactor the code about signal and notify socket There are two paths about `detach` because we need to setup notify socket once it is exist. It will cause the code too complex to read. So refactor it to keep one path for detached container. Signed-off-by: lifubang --- signals.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/signals.go b/signals.go index a195d801145..2d0424a2a43 100644 --- a/signals.go +++ b/signals.go @@ -70,20 +70,19 @@ 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 { return -1, err } - if h.notifySocket != nil { - if detach { + if detach { + if h.notifySocket != nil { _ = h.notifySocket.run(pid1) - return 0, nil } + return 0, nil + } + + if h.notifySocket != nil { _ = h.notifySocket.run(os.Getpid()) go func() { _ = h.notifySocket.run(0) }() }