diff options
-rw-r--r-- | libpod/runtime.go | 2 | ||||
-rw-r--r-- | libpod/shutdown/handler.go | 42 | ||||
-rw-r--r-- | pkg/api/server/server.go | 5 |
3 files changed, 32 insertions, 17 deletions
diff --git a/libpod/runtime.go b/libpod/runtime.go index 1118264f0..ccd920ab0 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -183,7 +183,7 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R return nil, err } - if err := shutdown.Register("libpod", func() error { + if err := shutdown.Register("libpod", func(sig os.Signal) error { os.Exit(1) return nil }); err != nil { diff --git a/libpod/shutdown/handler.go b/libpod/shutdown/handler.go index 7abaf065b..87538dec9 100644 --- a/libpod/shutdown/handler.go +++ b/libpod/shutdown/handler.go @@ -11,17 +11,20 @@ import ( ) var ( - stopped bool - sigChan chan os.Signal - cancelChan chan bool - handlers map[string]func() error + stopped bool + sigChan chan os.Signal + cancelChan chan bool + // Definitions of all on-shutdown handlers + handlers map[string]func(os.Signal) error + // Ordering that on-shutdown handlers will be invoked. + handlerOrder []string shutdownInhibit sync.RWMutex ) // Start begins handling SIGTERM and SIGINT and will run the given on-signal // handlers when one is called. This can be cancelled by calling Stop(). func Start() error { - if sigChan != nil && !stopped { + if sigChan != nil { // Already running, do nothing. return nil } @@ -43,9 +46,14 @@ func Start() error { case sig := <-sigChan: logrus.Infof("Received shutdown signal %v, terminating!", sig) shutdownInhibit.Lock() - for name, handler := range handlers { + for _, name := range handlerOrder { + handler, ok := handlers[name] + if !ok { + logrus.Errorf("Shutdown handler %s definition not found!", name) + continue + } logrus.Infof("Invoking shutdown handler %s", name) - if err := handler(); err != nil { + if err := handler(sig); err != nil { logrus.Errorf("Error running shutdown handler %s: %v", name, err) } } @@ -82,10 +90,11 @@ func Uninhibit() { } // Register registers a function that will be executed when Podman is terminated -// by a signal. -func Register(name string, handler func() error) error { +// by a signal. Handlers are invoked LIFO - the last handler registered is the +// first run. +func Register(name string, handler func(os.Signal) error) error { if handlers == nil { - handlers = make(map[string]func() error) + handlers = make(map[string]func(os.Signal) error) } if _, ok := handlers[name]; ok { @@ -93,6 +102,7 @@ func Register(name string, handler func() error) error { } handlers[name] = handler + handlerOrder = append([]string{name}, handlerOrder...) return nil } @@ -100,14 +110,22 @@ func Register(name string, handler func() error) error { // Unregister un-registers a given shutdown handler. func Unregister(name string) error { if handlers == nil { - handlers = make(map[string]func() error) + return nil } if _, ok := handlers[name]; !ok { - return errors.Errorf("no handler with name %s found", name) + return nil } delete(handlers, name) + newOrder := []string{} + for _, checkName := range handlerOrder { + if checkName != name { + newOrder = append(newOrder, checkName) + } + } + handlerOrder = newOrder + return nil } diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index 24ad1874b..64008767b 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -185,14 +185,11 @@ func (s *APIServer) Serve() error { if err := shutdown.Start(); err != nil { return err } - if err := shutdown.Register("server", func() error { + if err := shutdown.Register("server", func(sig os.Signal) error { return s.Shutdown() }); err != nil { return err } - // Unregister the libpod handler, which just calls exit(1). - // Ignore errors if it doesn't exist. - _ = shutdown.Unregister("libpod") errChan := make(chan error, 1) |