summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox/namespace.go
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/sandbox/namespace.go')
-rw-r--r--runsc/sandbox/namespace.go204
1 files changed, 0 insertions, 204 deletions
diff --git a/runsc/sandbox/namespace.go b/runsc/sandbox/namespace.go
deleted file mode 100644
index 1d3bcfbb5..000000000
--- a/runsc/sandbox/namespace.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2018 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package sandbox
-
-import (
- "fmt"
- "os"
- "os/exec"
- "path/filepath"
- "runtime"
- "syscall"
-
- specs "github.com/opencontainers/runtime-spec/specs-go"
- "golang.org/x/sys/unix"
- "gvisor.googlesource.com/gvisor/pkg/log"
-)
-
-// nsCloneFlag returns the clone flag that can be used to set a namespace of
-// the given type.
-func nsCloneFlag(nst specs.LinuxNamespaceType) uintptr {
- switch nst {
- case specs.IPCNamespace:
- return syscall.CLONE_NEWIPC
- case specs.MountNamespace:
- return syscall.CLONE_NEWNS
- case specs.NetworkNamespace:
- return syscall.CLONE_NEWNET
- case specs.PIDNamespace:
- return syscall.CLONE_NEWPID
- case specs.UTSNamespace:
- return syscall.CLONE_NEWUTS
- case specs.UserNamespace:
- return syscall.CLONE_NEWUSER
- case specs.CgroupNamespace:
- panic("cgroup namespace has no associated clone flag")
- default:
- panic(fmt.Sprintf("unknown namespace %v", nst))
- }
-}
-
-// nsPath returns the path of the namespace for the current process and the
-// given namespace.
-func nsPath(nst specs.LinuxNamespaceType) string {
- base := "/proc/self/ns"
- switch nst {
- case specs.CgroupNamespace:
- return filepath.Join(base, "cgroup")
- case specs.IPCNamespace:
- return filepath.Join(base, "ipc")
- case specs.MountNamespace:
- return filepath.Join(base, "mnt")
- case specs.NetworkNamespace:
- return filepath.Join(base, "net")
- case specs.PIDNamespace:
- return filepath.Join(base, "pid")
- case specs.UserNamespace:
- return filepath.Join(base, "user")
- case specs.UTSNamespace:
- return filepath.Join(base, "uts")
- default:
- panic(fmt.Sprintf("unknown namespace %v", nst))
- }
-}
-
-// getNS returns true and the namespace with the given type from the slice of
-// namespaces in the spec. It returns false if the slice does not contain a
-// namespace with the type.
-func getNS(nst specs.LinuxNamespaceType, s *specs.Spec) (specs.LinuxNamespace, bool) {
- if s.Linux == nil {
- return specs.LinuxNamespace{}, false
- }
- for _, ns := range s.Linux.Namespaces {
- if ns.Type == nst {
- return ns, true
- }
- }
- return specs.LinuxNamespace{}, false
-}
-
-// filterNS returns a slice of namespaces from the spec with types that match
-// those in the `filter` slice.
-func filterNS(filter []specs.LinuxNamespaceType, s *specs.Spec) []specs.LinuxNamespace {
- if s.Linux == nil {
- return nil
- }
- var out []specs.LinuxNamespace
- for _, nst := range filter {
- if ns, ok := getNS(nst, s); ok {
- out = append(out, ns)
- }
- }
- return out
-}
-
-// setNS sets the namespace of the given type. It must be called with
-// OSThreadLocked.
-func setNS(fd, nsType uintptr) error {
- if _, _, err := syscall.RawSyscall(unix.SYS_SETNS, fd, nsType, 0); err != 0 {
- return err
- }
- return nil
-}
-
-// applyNS applies the namespace on the current thread and returns a function
-// that will restore the namespace to the original value.
-//
-// Preconditions: Must be called with os thread locked.
-func applyNS(ns specs.LinuxNamespace) (func(), error) {
- log.Infof("applying namespace %v at path %q", ns.Type, ns.Path)
- newNS, err := os.Open(ns.Path)
- if err != nil {
- return nil, fmt.Errorf("error opening %q: %v", ns.Path, err)
- }
- defer newNS.Close()
-
- // Store current netns to restore back after child is started.
- curPath := nsPath(ns.Type)
- oldNS, err := os.Open(curPath)
- if err != nil {
- return nil, fmt.Errorf("error opening %q: %v", curPath, err)
- }
-
- // Set netns to the one requested and setup function to restore it back.
- flag := nsCloneFlag(ns.Type)
- if err := setNS(newNS.Fd(), flag); err != nil {
- oldNS.Close()
- return nil, fmt.Errorf("error setting namespace of type %v and path %q: %v", ns.Type, ns.Path, err)
- }
- return func() {
- log.Infof("restoring namespace %v", ns.Type)
- defer oldNS.Close()
- if err := setNS(oldNS.Fd(), flag); err != nil {
- panic(fmt.Sprintf("error restoring namespace: of type %v: %v", ns.Type, err))
- }
- }, nil
-}
-
-// startInNS joins or creates the given namespaces and calls cmd.Start before
-// restoring the namespaces to the original values.
-func startInNS(cmd *exec.Cmd, nss []specs.LinuxNamespace) error {
- // We are about to setup namespaces, which requires the os thread being
- // locked so that Go doesn't change the thread out from under us.
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
-
- if cmd.SysProcAttr == nil {
- cmd.SysProcAttr = &syscall.SysProcAttr{}
- }
-
- for _, ns := range nss {
- if ns.Path == "" {
- // No path. Just set a flag to create a new namespace.
- cmd.SysProcAttr.Cloneflags |= nsCloneFlag(ns.Type)
- continue
- }
- // Join the given namespace, and restore the current namespace
- // before exiting.
- restoreNS, err := applyNS(ns)
- if err != nil {
- return err
- }
- defer restoreNS()
- }
-
- return cmd.Start()
-}
-
-// setUIDGIDMappings sets the given uid/gid mappings from the spec on the cmd.
-func setUIDGIDMappings(cmd *exec.Cmd, s *specs.Spec) {
- if s.Linux == nil {
- return
- }
- if cmd.SysProcAttr == nil {
- cmd.SysProcAttr = &syscall.SysProcAttr{}
- }
- for _, idMap := range s.Linux.UIDMappings {
- log.Infof("Mapping host uid %d to container uid %d (size=%d)", idMap.HostID, idMap.ContainerID, idMap.Size)
- cmd.SysProcAttr.UidMappings = append(cmd.SysProcAttr.UidMappings, syscall.SysProcIDMap{
- ContainerID: int(idMap.ContainerID),
- HostID: int(idMap.HostID),
- Size: int(idMap.Size),
- })
- }
- for _, idMap := range s.Linux.GIDMappings {
- log.Infof("Mapping host gid %d to container gid %d (size=%d)", idMap.HostID, idMap.ContainerID, idMap.Size)
- cmd.SysProcAttr.GidMappings = append(cmd.SysProcAttr.GidMappings, syscall.SysProcIDMap{
- ContainerID: int(idMap.ContainerID),
- HostID: int(idMap.HostID),
- Size: int(idMap.Size),
- })
- }
-}