package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive" import ( "github.com/docker/docker/internal/mounttree" "github.com/docker/docker/internal/unshare" "github.com/moby/sys/mount" "golang.org/x/sys/unix" ) // goInChroot starts fn in a goroutine where the root directory, current working // directory and umask are unshared from other goroutines and the root directory // has been changed to path. These changes are only visible to the goroutine in // which fn is executed. Any other goroutines, including ones started from fn, // will see the same root directory and file system attributes as the rest of // the process. func goInChroot(path string, fn func()) error { return unshare.Go( unix.CLONE_FS|unix.CLONE_NEWNS, func() error { // Make everything in new ns slave. // Don't use `private` here as this could race where the mountns gets a // reference to a mount and an unmount from the host does not propagate, // which could potentially cause transient errors for other operations, // even though this should be relatively small window here `slave` should // not cause any problems. if err := mount.MakeRSlave("/"); err != nil { return err } return mounttree.SwitchRoot(path) }, fn, ) }