diff options
author | Matthew Heon <mheon@redhat.com> | 2021-01-25 15:29:00 -0500 |
---|---|---|
committer | Matthew Heon <mheon@redhat.com> | 2021-01-25 15:44:42 -0500 |
commit | 5350254f0578162c226f8990f9835b7920bf9835 (patch) | |
tree | 7432c1a3cdea333189f2af5d50264342dab3e6f7 /libpod/shutdown/handler.go | |
parent | f4e857245ab5ad414c466158775b14eeb268181d (diff) | |
download | podman-5350254f0578162c226f8990f9835b7920bf9835.tar.gz podman-5350254f0578162c226f8990f9835b7920bf9835.tar.bz2 podman-5350254f0578162c226f8990f9835b7920bf9835.zip |
Ensure shutdown handler access is syncronized
There was a potential race where two handlers could be added at
the same time. Go Maps are not thread-safe, so that could do
unpleasant things. Add a mutex to keep things safe.
Also, swap the order or Register and Start for the handlers in
Libpod runtime created. As written, there was a small gap between
Start and Register where SIGTERM/SIGINT would be completely
ignored, instead of stopping Podman. Swapping the two closes this
gap.
Signed-off-by: Matthew Heon <mheon@redhat.com>
Diffstat (limited to 'libpod/shutdown/handler.go')
-rw-r--r-- | libpod/shutdown/handler.go | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/libpod/shutdown/handler.go b/libpod/shutdown/handler.go index f0f228b19..ac1d33910 100644 --- a/libpod/shutdown/handler.go +++ b/libpod/shutdown/handler.go @@ -18,6 +18,8 @@ var ( stopped bool sigChan chan os.Signal cancelChan chan bool + // Syncronize accesses to the map + handlerLock sync.Mutex // Definitions of all on-shutdown handlers handlers map[string]func(os.Signal) error // Ordering that on-shutdown handlers will be invoked. @@ -50,6 +52,7 @@ func Start() error { case sig := <-sigChan: logrus.Infof("Received shutdown signal %v, terminating!", sig) shutdownInhibit.Lock() + handlerLock.Lock() for _, name := range handlerOrder { handler, ok := handlers[name] if !ok { @@ -61,6 +64,7 @@ func Start() error { logrus.Errorf("Error running shutdown handler %s: %v", name, err) } } + handlerLock.Unlock() shutdownInhibit.Unlock() return } @@ -97,6 +101,9 @@ func Uninhibit() { // 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 { + handlerLock.Lock() + defer handlerLock.Unlock() + if handlers == nil { handlers = make(map[string]func(os.Signal) error) } @@ -113,6 +120,9 @@ func Register(name string, handler func(os.Signal) error) error { // Unregister un-registers a given shutdown handler. func Unregister(name string) error { + handlerLock.Lock() + defer handlerLock.Unlock() + if handlers == nil { return nil } |