summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal.go3
-rw-r--r--libpod/define/errors.go5
-rw-r--r--libpod/runtime_ctr.go3
-rw-r--r--libpod/runtime_volume.go3
-rw-r--r--libpod/runtime_volume_linux.go3
5 files changed, 14 insertions, 3 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 11f9721dc..ff43bfc8f 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1401,6 +1401,9 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string)
return nil, errors.Wrapf(err, "error retrieving named volume %s for container %s", v.Name, c.ID())
}
+ if vol.config.LockID == c.config.LockID {
+ return nil, errors.Wrapf(define.ErrWillDeadlock, "container %s and volume %s share lock ID %d", c.ID(), vol.Name(), c.config.LockID)
+ }
vol.lock.Lock()
defer vol.lock.Unlock()
if vol.needsMount() {
diff --git a/libpod/define/errors.go b/libpod/define/errors.go
index 523062866..b79cf08dc 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -61,6 +61,11 @@ var (
// the user.
ErrDetach = utils.ErrDetach
+ // ErrWillDeadlock indicates that the requested operation will cause a
+ // deadlock. This is usually caused by upgrade issues, and is resolved
+ // by renumbering the locks.
+ ErrWillDeadlock = errors.New("deadlock due to lock mismatch")
+
// ErrNoCgroups indicates that the container does not have its own
// CGroup.
ErrNoCgroups = errors.New("this container does not have a cgroup")
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 3ad09f27c..39284026c 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -412,6 +412,9 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool,
}
// Lock the pod while we're removing container
+ if pod.config.LockID == c.config.LockID {
+ return errors.Wrapf(define.ErrWillDeadlock, "container %s and pod %s share lock ID %d", c.ID(), pod.ID(), c.config.LockID)
+ }
pod.lock.Lock()
defer pod.lock.Unlock()
if err := pod.updatePod(); err != nil {
diff --git a/libpod/runtime_volume.go b/libpod/runtime_volume.go
index 835dccf9c..efc3c5bd9 100644
--- a/libpod/runtime_volume.go
+++ b/libpod/runtime_volume.go
@@ -36,9 +36,6 @@ func (r *Runtime) RemoveVolume(ctx context.Context, v *Volume, force bool) error
}
}
- v.lock.Lock()
- defer v.lock.Unlock()
-
return r.removeVolume(ctx, v, force)
}
diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_linux.go
index 037cf4cc2..e9cfda9d4 100644
--- a/libpod/runtime_volume_linux.go
+++ b/libpod/runtime_volume_linux.go
@@ -124,6 +124,9 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool) error
return define.ErrVolumeRemoved
}
+ v.lock.Lock()
+ defer v.lock.Unlock()
+
// Update volume status to pick up a potential removal from state
if err := v.update(); err != nil {
return err