summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2018-02-27 15:18:44 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-03-01 21:17:51 +0000
commit780baec1d9fc6f733d06fafddb53655784e2f6f1 (patch)
treea85070e074cae3aae32cfd85ced4604f6318ae41 /libpod
parentf02a9cd97547630a944df83e7e02eac11e8a7021 (diff)
downloadpodman-780baec1d9fc6f733d06fafddb53655784e2f6f1.tar.gz
podman-780baec1d9fc6f733d06fafddb53655784e2f6f1.tar.bz2
podman-780baec1d9fc6f733d06fafddb53655784e2f6f1.zip
Relax locking in Exec()
This allows containers to be used by `ps` and other commands while they have ongoing exec sessions. Concurrent exec should also work but is not tested. Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #412 Approved by: baude
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_api.go22
1 files changed, 21 insertions, 1 deletions
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 1e233109b..17cd68972 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -219,9 +219,16 @@ func (c *Container) Kill(signal uint) error {
func (c *Container) Exec(tty, privileged bool, env, cmd []string, user string) error {
var capList []string
+ locked := false
if !c.locked {
+ locked = true
+
c.lock.Lock()
- defer c.lock.Unlock()
+ defer func() {
+ if locked {
+ c.lock.Unlock()
+ }
+ }()
if err := c.syncContainer(); err != nil {
return err
@@ -309,8 +316,21 @@ func (c *Container) Exec(tty, privileged bool, env, cmd []string, user string) e
return errors.Wrapf(err, "error saving exec sessions %s for container %s", sessionID, c.ID())
}
+ // Unlock so other processes can use the container
+ c.lock.Unlock()
+ locked = false
+
waitErr := execCmd.Wait()
+ // Lock again
+ locked = true
+ c.lock.Lock()
+
+ // Sync the container again to pick up changes in state
+ if err := c.syncContainer(); err != nil {
+ return errors.Wrapf(err, "error syncing container %s state to remove exec session %s", c.ID(), sessionID)
+ }
+
// Remove the exec session from state
delete(c.state.ExecSessions, sessionID)
if err := c.save(); err != nil {