diff options
Diffstat (limited to 'libpod/oci.go')
-rw-r--r-- | libpod/oci.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/libpod/oci.go b/libpod/oci.go index b59525de7..9c842f2c9 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -8,11 +8,14 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strconv" + "sync" "syscall" "time" "github.com/containerd/cgroups" + "github.com/containers/storage/pkg/idtools" "github.com/coreos/go-systemd/activation" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -186,6 +189,53 @@ func waitPidsStop(pids []int, timeout time.Duration) error { // TODO terminal support for container // Presently just ignoring conmon opts related to it func (r *OCIRuntime) createContainer(ctr *Container, cgroupParent string) (err error) { + if ctr.state.UserNSRoot == "" { + // no need of an intermediate mount ns + return r.createOCIContainer(ctr, cgroupParent) + } + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + runtime.LockOSThread() + + fd, err := os.Open(fmt.Sprintf("/proc/%d/task/%d/ns/mnt", os.Getpid(), unix.Gettid())) + if err != nil { + return + } + defer fd.Close() + + // create a new mountns on the current thread + if err = unix.Unshare(unix.CLONE_NEWNS); err != nil { + return + } + defer unix.Setns(int(fd.Fd()), unix.CLONE_NEWNS) + + // don't spread our mounts around + err = unix.Mount("/", "/", "none", unix.MS_REC|unix.MS_SLAVE, "") + if err != nil { + return + } + err = unix.Mount(ctr.state.Mountpoint, ctr.state.RealMountpoint, "none", unix.MS_BIND, "") + if err != nil { + return + } + if err := idtools.MkdirAllAs(ctr.state.DestinationRunDir, 0700, ctr.RootUID(), ctr.RootGID()); err != nil { + return + } + + err = unix.Mount(ctr.state.RunDir, ctr.state.DestinationRunDir, "none", unix.MS_BIND, "") + if err != nil { + return + } + err = r.createOCIContainer(ctr, cgroupParent) + }() + wg.Wait() + + return err +} + +func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string) (err error) { var stderrBuf bytes.Buffer parentPipe, childPipe, err := newPipe() |