Documentation ¶
Overview ¶
Package execsupport implements wrappers around os/exec.Cmd Start() and Wait() functions that acquire a read lock on a R/W mutex to work around fork+exec concurrency issue with open file handle on POSIX. See https://github.com/golang/go/issues/22315 and https://github.com/golang/go/issues/22220 for background.
This specifically affects the nsjail executable: if one goroutine of a subprocess has the nsjail file handle open for writing at the time that another goroutine forks a subprocess (any subprocess, whether it be git or a subprocess run by `ctx.os.exec()`), the forked subprocess will inherit the open file handle and it will remain open even after the parent closes it. Then if the parent or any other process tries to run the nsjail executable, it will fail with ETXTBSY due to being open for writing.
So the code that writes the nsjail executable must acquire this package's mutex for writing, to prevent any forks while the nsjail file is open for writing, and all shac code must use this package's Start() and Wait() functions instead of calling Cmd.Start() and Cmd.Wait() directly.
This is only strictly necessary when running unit tests, because many shac instances are run in parallel in the same process. In normal execution, there are no subprocesses forks run concurrently when the nsjail executable is being written.
TODO(olivernewman): This hack will no longer be necessary when we switch from using a prebuilt nsjail to implementing our own sandboxing using cgroups.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Mu sync.RWMutex
Mu enables blocking all exec(), for example while writing an executable that will later be exec()'ed.
Functions ¶
Types ¶
This section is empty.