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
This commit is contained in:
Matthew Heon
2018-02-27 15:18:44 -05:00
committed by Atomic Bot
parent f02a9cd975
commit 780baec1d9

View File

@ -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 {