mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-10 21:53:57 +08:00
Merge pull request #4661 from lifubang/skip-setup-signalNotify-for-detached
skip setup signal notifier for detached container
This commit is contained in:
@@ -151,6 +151,22 @@ func (s *notifySocket) run(pid1 int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// forward reads systemd notifications from the container and forwards them
|
||||||
|
// to notifySocketHost.
|
||||||
|
func (s *notifySocket) forward(process *libcontainer.Process, detach bool) error {
|
||||||
|
if detach {
|
||||||
|
pid, err := process.Pid()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_ = s.run(pid)
|
||||||
|
} else {
|
||||||
|
_ = s.run(os.Getpid())
|
||||||
|
go func() { _ = s.run(0) }()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// notifyHost tells the host (usually systemd) that the container reported READY.
|
// notifyHost tells the host (usually systemd) that the container reported READY.
|
||||||
// Also sends MAINPID and BARRIER.
|
// Also sends MAINPID and BARRIER.
|
||||||
func notifyHost(client *net.UnixConn, ready []byte, pid1 int) error {
|
func notifyHost(client *net.UnixConn, ready []byte, pid1 int) error {
|
||||||
|
|||||||
+4
-28
@@ -5,7 +5,6 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
"github.com/opencontainers/runc/libcontainer/system"
|
|
||||||
"github.com/opencontainers/runc/libcontainer/utils"
|
"github.com/opencontainers/runc/libcontainer/utils"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -16,15 +15,7 @@ const signalBufferSize = 2048
|
|||||||
|
|
||||||
// newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals
|
// newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals
|
||||||
// while still forwarding all other signals to the process.
|
// while still forwarding all other signals to the process.
|
||||||
// If notifySocket is present, use it to read systemd notifications from the container and
|
func newSignalHandler() chan *signalHandler {
|
||||||
// forward them to notifySocketHost.
|
|
||||||
func newSignalHandler(enableSubreaper 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)
|
||||||
|
|
||||||
// Ensure that we have a large buffer size so that we do not miss any
|
// Ensure that we have a large buffer size so that we do not miss any
|
||||||
@@ -40,8 +31,7 @@ func newSignalHandler(enableSubreaper bool, notifySocket *notifySocket) chan *si
|
|||||||
// handle all signals for the process.
|
// handle all signals for the process.
|
||||||
signal.Notify(s)
|
signal.Notify(s)
|
||||||
handler <- &signalHandler{
|
handler <- &signalHandler{
|
||||||
signals: s,
|
signals: s,
|
||||||
notifySocket: notifySocket,
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return handler
|
return handler
|
||||||
@@ -55,33 +45,19 @@ type exit struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type signalHandler struct {
|
type signalHandler struct {
|
||||||
signals chan os.Signal
|
signals chan os.Signal
|
||||||
notifySocket *notifySocket
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward handles the main signal event loop forwarding, resizing, or reaping depending
|
// forward handles the main signal event loop forwarding, resizing, or reaping depending
|
||||||
// on the signal received.
|
// on the signal received.
|
||||||
func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) {
|
func (h *signalHandler) forward(process *libcontainer.Process, tty *tty) (int, error) {
|
||||||
// make sure we know the pid of our main process so that we can return
|
// make sure we know the pid of our main process so that we can return
|
||||||
// after it dies.
|
// after it dies.
|
||||||
if detach && h.notifySocket == nil {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pid1, err := process.Pid()
|
pid1, err := process.Pid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.notifySocket != nil {
|
|
||||||
if detach {
|
|
||||||
_ = h.notifySocket.run(pid1)
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
_ = h.notifySocket.run(os.Getpid())
|
|
||||||
go func() { _ = h.notifySocket.run(0) }()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform the initial tty resize. Always ignore errors resizing because
|
// Perform the initial tty resize. Always ignore errors resizing because
|
||||||
// stdout might have disappeared (due to races with when SIGHUP is sent).
|
// stdout might have disappeared (due to races with when SIGHUP is sent).
|
||||||
_ = tty.resize()
|
_ = tty.resize()
|
||||||
|
|||||||
+30
-16
@@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
"github.com/opencontainers/runc/libcontainer/specconv"
|
"github.com/opencontainers/runc/libcontainer/specconv"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/system"
|
||||||
"github.com/opencontainers/runc/libcontainer/system/kernelversion"
|
"github.com/opencontainers/runc/libcontainer/system/kernelversion"
|
||||||
"github.com/opencontainers/runc/libcontainer/utils"
|
"github.com/opencontainers/runc/libcontainer/utils"
|
||||||
)
|
)
|
||||||
@@ -219,14 +220,16 @@ type runner struct {
|
|||||||
subCgroupPaths map[string]string
|
subCgroupPaths map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) run(config *specs.Process) (int, error) {
|
func (r *runner) run(config *specs.Process) (_ int, retErr error) {
|
||||||
var err error
|
detach := r.detach || (r.action == CT_ACT_CREATE)
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
// For a non-detached container, or we get an error, we
|
||||||
|
// should destroy the container.
|
||||||
|
if !detach || retErr != nil {
|
||||||
r.destroy()
|
r.destroy()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if err = r.checkTerminal(config); err != nil {
|
if err := r.checkTerminal(config); err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
process, err := newProcess(config)
|
process, err := newProcess(config)
|
||||||
@@ -255,11 +258,19 @@ func (r *runner) run(config *specs.Process) (int, error) {
|
|||||||
}
|
}
|
||||||
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(i)))
|
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(i)))
|
||||||
}
|
}
|
||||||
detach := r.detach || (r.action == CT_ACT_CREATE)
|
|
||||||
// Setting up IO is a two stage process. We need to modify process to deal
|
// 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
|
// with detaching containers, and then we get a tty after the container has
|
||||||
// started.
|
// started.
|
||||||
handlerCh := newSignalHandler(r.enableSubreaper, r.notifySocket)
|
if r.enableSubreaper {
|
||||||
|
// set us as the subreaper before registering the signal handler for the container
|
||||||
|
if err := system.SetSubreaper(1); err != nil {
|
||||||
|
logrus.Warn(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var handlerCh chan *signalHandler
|
||||||
|
if !detach {
|
||||||
|
handlerCh = newSignalHandler()
|
||||||
|
}
|
||||||
tty, err := setupIO(process, r.container, config.Terminal, detach, r.consoleSocket)
|
tty, err := setupIO(process, r.container, config.Terminal, detach, r.consoleSocket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
@@ -287,29 +298,32 @@ func (r *runner) run(config *specs.Process) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
// We should terminate the process once we got an error.
|
||||||
|
if retErr != nil {
|
||||||
|
r.terminate(process)
|
||||||
|
}
|
||||||
|
}()
|
||||||
if err = tty.waitConsole(); err != nil {
|
if err = tty.waitConsole(); err != nil {
|
||||||
r.terminate(process)
|
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
tty.ClosePostStart()
|
tty.ClosePostStart()
|
||||||
if r.pidFile != "" {
|
if r.pidFile != "" {
|
||||||
if err = createPidFile(r.pidFile, process); err != nil {
|
if err = createPidFile(r.pidFile, process); err != nil {
|
||||||
r.terminate(process)
|
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handler := <-handlerCh
|
if r.notifySocket != nil {
|
||||||
status, err := handler.forward(process, tty, detach)
|
if err = r.notifySocket.forward(process, detach); err != nil {
|
||||||
if err != nil {
|
return -1, err
|
||||||
r.terminate(process)
|
}
|
||||||
}
|
}
|
||||||
if detach {
|
if detach {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
if err == nil {
|
// For non-detached container, we should forward signals to the container.
|
||||||
r.destroy()
|
handler := <-handlerCh
|
||||||
}
|
return handler.forward(process, tty)
|
||||||
return status, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) destroy() {
|
func (r *runner) destroy() {
|
||||||
|
|||||||
Reference in New Issue
Block a user