summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2017-12-04 14:44:03 -0500
committerMatthew Heon <matthew.heon@gmail.com>2017-12-04 14:45:49 -0500
commit92bc448624e29fc84087bafcccd0e52b328a53e4 (patch)
tree93daf65340a091c4ac6851dac9dec40219a25abf
parentae5aac50aaacbdcc20e622e86f40c02136690fe7 (diff)
downloadpodman-92bc448624e29fc84087bafcccd0e52b328a53e4.tar.gz
podman-92bc448624e29fc84087bafcccd0e52b328a53e4.tar.bz2
podman-92bc448624e29fc84087bafcccd0e52b328a53e4.zip
Fix potential race condition in initializing libpod
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
-rw-r--r--libpod/container.go2
-rw-r--r--libpod/runtime.go15
2 files changed, 13 insertions, 4 deletions
diff --git a/libpod/container.go b/libpod/container.go
index e1b002548..c53184ea3 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -413,7 +413,7 @@ func (c *Container) refresh() error {
defer c.lock.Unlock()
if !c.valid {
- return errors.Wrapf(ErrCtrRemoved, "container %s has been removed from the state", c.ID())
+ return errors.Wrapf(ErrCtrRemoved, "container %s is not valid - may have been removed", c.ID())
}
// We need to get the container's temporary directory from c/storage
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 7997679e2..103faf3f8 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -175,7 +175,19 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
// We now need to see if the system has restarted
// We check for the presence of a file in our tmp directory to verify this
+ // This check must be locked to prevent races
+ runtimeAliveLock := filepath.Join(runtime.config.TmpDir, "alive.lck")
runtimeAliveFile := filepath.Join(runtime.config.TmpDir, "alive")
+ aliveLock, err := storage.GetLockfile(runtimeAliveLock)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error acquiring runtime init lock")
+ }
+ // Acquire the lock and hold it until we return
+ // This ensures that no two processes will be in runtime.refresh at once
+ // TODO: we can't close the FD in this lock, so we should keep it around
+ // and use it to lock important operations
+ aliveLock.Lock()
+ defer aliveLock.Unlock()
_, err = os.Stat(runtimeAliveFile)
if err != nil {
// If the file doesn't exist, we need to refresh the state
@@ -260,9 +272,6 @@ func (r *Runtime) Shutdown(force bool) error {
// Reconfigures the runtime after a reboot
// Refreshes the state, recreating temporary files
// Does not check validity as the runtime is not valid until after this has run
-// TODO: there's a potential race here, where multiple libpods could be in this
-// function before the runtime ready file is created
-// This probably doesn't matter as the actual container operations are locked
func (r *Runtime) refresh(alivePath string) error {
// We need to refresh the state of all containers
ctrs, err := r.state.AllContainers()