diff options
Diffstat (limited to 'libpod/oci_linux.go')
-rw-r--r-- | libpod/oci_linux.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go index 14373cbb2..2128b7481 100644 --- a/libpod/oci_linux.go +++ b/libpod/oci_linux.go @@ -7,11 +7,15 @@ import ( "os" "os/exec" "path/filepath" + "runtime" + "sync" "github.com/containerd/cgroups" + "github.com/containers/storage/pkg/idtools" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/projectatomic/libpod/utils" "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) func (r *OCIRuntime) moveConmonToCgroup(ctr *Container, cgroupParent string, cmd *exec.Cmd) error { @@ -39,3 +43,62 @@ func (r *OCIRuntime) moveConmonToCgroup(ctr *Container, cgroupParent string, cmd } return nil } + +// newPipe creates a unix socket pair for communication +func newPipe() (parent *os.File, child *os.File, err error) { + fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0) + if err != nil { + return nil, nil, err + } + return os.NewFile(uintptr(fds[1]), "parent"), os.NewFile(uintptr(fds[0]), "child"), nil +} + +// CreateContainer creates a container in the OCI runtime +// 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 +} |