Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion libpod/container_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,19 @@ func (c *Container) healthCheckExec(config *ExecConfig, timeout time.Duration, s
return -1, err
}
defer func() {
// cleanupExecBundle MUST be called with the parent container locked.
if !unlock && !c.batched {
c.lock.Lock()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you cannot ever lock without calling syncContainer() because the function will call c.save() with an outdated state otherwise which will cause really bad problems.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we also add the !c.batched condition? Otherwise the block here depends on unlock being false only when !c.batched and that could change without us noticing the breakage of the dependency.

unlock = true

if err := c.syncContainer(); err != nil {
logrus.Errorf("Error syncing container %s state: %v", c.ID(), err)
// Normally we'd want to continue here, get rid of the exec directory.
// But the risk of proceeding into a function that can mutate state with a bad state is high.
// Lesser of two evils is to bail and leak a directory.
return
}
}
if err := c.cleanupExecBundle(session.ID()); err != nil {
logrus.Errorf("Container %s light exec session cleanup error: %v", c.ID(), err)
}
Expand Down Expand Up @@ -971,7 +984,8 @@ func (c *Container) exec(config *ExecConfig, streams *define.AttachStreams, resi
return session.ExitCode, nil
}

// cleanupExecBundle cleanups an exec session after its done
// cleanupExecBundle cleans up an exec session after completion.
// MUST BE CALLED with container `c` locked.
// Please be careful when using this function since it might temporarily unlock
// the container when os.RemoveAll($bundlePath) fails with ENOTEMPTY or EBUSY
// errors.
Expand Down