diff --git a/cmd/containerd/main.go b/cmd/containerd/main.go index f919d19be..464c7cfa3 100644 --- a/cmd/containerd/main.go +++ b/cmd/containerd/main.go @@ -78,9 +78,11 @@ func main() { var ( start = time.Now() signals = make(chan os.Signal, 2048) + serverC = make(chan *server.Server) ctx = log.WithModule(gocontext.Background(), "containerd") config = defaultConfig() ) + done := handleSignals(ctx, signals, serverC) // start the signal handler as soon as we can to make sure that // we don't miss any signals during boot signal.Notify(signals, handledSignals...) @@ -105,6 +107,7 @@ func main() { if err != nil { return err } + serverC <- server if config.Debug.Address != "" { l, err := sys.GetLocalListener(config.Debug.Address, config.Debug.Uid, config.Debug.Gid) if err != nil { @@ -127,7 +130,8 @@ func main() { serve(log.WithModule(ctx, "grpc"), l, server.ServeGRPC) log.G(ctx).Infof("containerd successfully booted in %fs", time.Since(start).Seconds()) - return handleSignals(ctx, signals, server) + <-done + return nil } if err := app.Run(os.Args); err != nil { fmt.Fprintf(os.Stderr, "containerd: %s\n", err) diff --git a/cmd/containerd/main_linux.go b/cmd/containerd/main_linux.go deleted file mode 100644 index 3f8527258..000000000 --- a/cmd/containerd/main_linux.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "context" - "os" - - "golang.org/x/sys/unix" - - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/reaper" - "github.com/containerd/containerd/server" -) - -const defaultConfigPath = "/etc/containerd/config.toml" - -var handledSignals = []os.Signal{ - unix.SIGTERM, - unix.SIGINT, - unix.SIGUSR1, - unix.SIGCHLD, -} - -func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error { - for s := range signals { - log.G(ctx).WithField("signal", s).Debug("received signal") - switch s { - case unix.SIGCHLD: - if err := reaper.Reap(); err != nil { - log.G(ctx).WithError(err).Error("reap containerd processes") - } - case unix.SIGUSR1: - dumpStacks() - default: - server.Stop() - return nil - } - } - return nil -} diff --git a/cmd/containerd/main_unix.go b/cmd/containerd/main_unix.go index 385467fd5..ba39a381d 100644 --- a/cmd/containerd/main_unix.go +++ b/cmd/containerd/main_unix.go @@ -1,4 +1,4 @@ -// +build darwin freebsd solaris +// +build linux darwin freebsd solaris package main @@ -23,22 +23,35 @@ var handledSignals = []os.Signal{ unix.SIGPIPE, } -func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error { - for s := range signals { - log.G(ctx).WithField("signal", s).Debug("received signal") - switch s { - case unix.SIGCHLD: - if err := reaper.Reap(); err != nil { - log.G(ctx).WithError(err).Error("reap containerd processes") +func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server) chan struct{} { + done := make(chan struct{}, 1) + go func() { + var server *server.Server + for { + select { + case s := <-serverC: + server = s + case s := <-signals: + log.G(ctx).WithField("signal", s).Debug("received signal") + switch s { + case unix.SIGCHLD: + if err := reaper.Reap(); err != nil { + log.G(ctx).WithError(err).Error("reap containerd processes") + } + case unix.SIGUSR1: + dumpStacks() + case unix.SIGPIPE: + continue + default: + if server == nil { + close(done) + return + } + server.Stop() + close(done) + } } - case unix.SIGUSR1: - dumpStacks() - case unix.SIGPIPE: - continue - default: - server.Stop() - return nil } - } - return nil + }() + return done } diff --git a/cmd/containerd/main_windows.go b/cmd/containerd/main_windows.go index 0ca795fa7..fd4a2af1a 100644 --- a/cmd/containerd/main_windows.go +++ b/cmd/containerd/main_windows.go @@ -19,10 +19,24 @@ var ( } ) -func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error { - for s := range signals { - log.G(ctx).WithField("signal", s).Debug("received signal") - server.Stop() - } - return nil +func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server) chan struct{} { + done := make(chan struct{}) + go func() { + var server *server.Server + for { + select { + case s := <-serverC: + server = s + case s := <-signals: + log.G(ctx).WithField("signal", s).Debug("received signal") + if server == nil { + close(done) + return + } + server.Stop() + close(done) + } + } + }() + return done } diff --git a/server/config.go b/server/config.go index 214ce8af7..764f6bdf2 100644 --- a/server/config.go +++ b/server/config.go @@ -87,5 +87,4 @@ func LoadConfig(path string, v *Config) error { } v.md = md return nil - }