mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
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>
This commit is contained in:
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user