Handle signals first on boot

This handles signals first thing on boot so that plugins are able to
boot with the reaper enabled.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2017-09-14 15:55:50 -04:00
parent cf1d4223be
commit 7fdf8cd31e
5 changed files with 55 additions and 64 deletions

View File

@ -78,9 +78,11 @@ func main() {
var ( var (
start = time.Now() start = time.Now()
signals = make(chan os.Signal, 2048) signals = make(chan os.Signal, 2048)
serverC = make(chan *server.Server)
ctx = log.WithModule(gocontext.Background(), "containerd") ctx = log.WithModule(gocontext.Background(), "containerd")
config = defaultConfig() config = defaultConfig()
) )
done := handleSignals(ctx, signals, serverC)
// start the signal handler as soon as we can to make sure that // start the signal handler as soon as we can to make sure that
// we don't miss any signals during boot // we don't miss any signals during boot
signal.Notify(signals, handledSignals...) signal.Notify(signals, handledSignals...)
@ -105,6 +107,7 @@ func main() {
if err != nil { if err != nil {
return err return err
} }
serverC <- server
if config.Debug.Address != "" { if config.Debug.Address != "" {
l, err := sys.GetLocalListener(config.Debug.Address, config.Debug.Uid, config.Debug.Gid) l, err := sys.GetLocalListener(config.Debug.Address, config.Debug.Uid, config.Debug.Gid)
if err != nil { if err != nil {
@ -127,7 +130,8 @@ func main() {
serve(log.WithModule(ctx, "grpc"), l, server.ServeGRPC) serve(log.WithModule(ctx, "grpc"), l, server.ServeGRPC)
log.G(ctx).Infof("containerd successfully booted in %fs", time.Since(start).Seconds()) 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 { if err := app.Run(os.Args); err != nil {
fmt.Fprintf(os.Stderr, "containerd: %s\n", err) fmt.Fprintf(os.Stderr, "containerd: %s\n", err)

View File

@ -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
}

View File

@ -1,4 +1,4 @@
// +build darwin freebsd solaris // +build linux darwin freebsd solaris
package main package main
@ -23,22 +23,35 @@ var handledSignals = []os.Signal{
unix.SIGPIPE, unix.SIGPIPE,
} }
func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error { func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server) chan struct{} {
for s := range signals { done := make(chan struct{}, 1)
log.G(ctx).WithField("signal", s).Debug("received signal") go func() {
switch s { var server *server.Server
case unix.SIGCHLD: for {
if err := reaper.Reap(); err != nil { select {
log.G(ctx).WithError(err).Error("reap containerd processes") 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
} }

View File

@ -19,10 +19,24 @@ var (
} }
) )
func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error { func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *server.Server) chan struct{} {
for s := range signals { done := make(chan struct{})
log.G(ctx).WithField("signal", s).Debug("received signal") go func() {
server.Stop() var server *server.Server
} for {
return nil 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
} }

View File

@ -87,5 +87,4 @@ func LoadConfig(path string, v *Config) error {
} }
v.md = md v.md = md
return nil return nil
} }