diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2018-02-27 15:18:44 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-03-01 21:17:51 +0000 |
commit | 780baec1d9fc6f733d06fafddb53655784e2f6f1 (patch) | |
tree | a85070e074cae3aae32cfd85ced4604f6318ae41 /libpod/container_api.go | |
parent | f02a9cd97547630a944df83e7e02eac11e8a7021 (diff) | |
download | podman-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/container_api.go')
-rw-r--r-- | libpod/container_api.go | 22 |
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 { |