Fix runtime panic when having concurrent writes to runtime impl map
We now protect the map of runtime implementations with a RWMutex to
allow concurrent reads, but restrict single write access.
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"io"
+ "sync"
"syscall"
"time"
@@ -58,7 +59,8 @@ type Runtime struct {
noPivot bool
ctrStopTimeout int64
- runtimeImplList map[string]RuntimeImpl
+ runtimeImplMap map[string]RuntimeImpl
+ runtimeImplMapMutex sync.RWMutex
}
// RuntimeImpl is an interface used by the caller to interact with the
@@ -132,7 +134,7 @@ func New(defaultRuntime string,
logToJournald: logToJournald,
noPivot: noPivot,
ctrStopTimeout: ctrStopTimeout,
- runtimeImplList: make(map[string]RuntimeImpl),
+ runtimeImplMap: make(map[string]RuntimeImpl),
}, nil
}
@@ -250,7 +252,9 @@ func (r *Runtime) newRuntimeImpl(c *Container) (RuntimeImpl, error) {
// RuntimeImpl returns the runtime implementation for a given container
func (r *Runtime) RuntimeImpl(c *Container) (RuntimeImpl, error) {
- impl, ok := r.runtimeImplList[c.ID()]
+ r.runtimeImplMapMutex.RLock()
+ impl, ok := r.runtimeImplMap[c.ID()]
+ r.runtimeImplMapMutex.RUnlock()
if !ok {
return r.newRuntimeImpl(c)
}
@@ -267,7 +271,9 @@ func (r *Runtime) CreateContainer(c *Container, cgroupParent string) error {
}
// Assign this runtime implementation to the current container
- r.runtimeImplList[c.ID()] = impl
+ r.runtimeImplMapMutex.Lock()
+ r.runtimeImplMap[c.ID()] = impl
+ r.runtimeImplMapMutex.Unlock()
return impl.CreateContainer(c, cgroupParent)
}
@@ -329,7 +335,11 @@ func (r *Runtime) DeleteContainer(c *Container) error {
return err
}
- defer delete(r.runtimeImplList, c.ID())
+ defer func() {
+ r.runtimeImplMapMutex.Lock()
+ delete(r.runtimeImplMap, c.ID())
+ r.runtimeImplMapMutex.Unlock()
+ }()
return impl.DeleteContainer(c)
}
