...

Source file src/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go

Documentation: github.com/opencontainers/runc/libcontainer/configs

     1  package configs
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"sync"
     7  )
     8  
     9  const (
    10  	NEWNET    NamespaceType = "NEWNET"
    11  	NEWPID    NamespaceType = "NEWPID"
    12  	NEWNS     NamespaceType = "NEWNS"
    13  	NEWUTS    NamespaceType = "NEWUTS"
    14  	NEWIPC    NamespaceType = "NEWIPC"
    15  	NEWUSER   NamespaceType = "NEWUSER"
    16  	NEWCGROUP NamespaceType = "NEWCGROUP"
    17  )
    18  
    19  var (
    20  	nsLock              sync.Mutex
    21  	supportedNamespaces = make(map[NamespaceType]bool)
    22  )
    23  
    24  // NsName converts the namespace type to its filename
    25  func NsName(ns NamespaceType) string {
    26  	switch ns {
    27  	case NEWNET:
    28  		return "net"
    29  	case NEWNS:
    30  		return "mnt"
    31  	case NEWPID:
    32  		return "pid"
    33  	case NEWIPC:
    34  		return "ipc"
    35  	case NEWUSER:
    36  		return "user"
    37  	case NEWUTS:
    38  		return "uts"
    39  	case NEWCGROUP:
    40  		return "cgroup"
    41  	}
    42  	return ""
    43  }
    44  
    45  // IsNamespaceSupported returns whether a namespace is available or
    46  // not
    47  func IsNamespaceSupported(ns NamespaceType) bool {
    48  	nsLock.Lock()
    49  	defer nsLock.Unlock()
    50  	supported, ok := supportedNamespaces[ns]
    51  	if ok {
    52  		return supported
    53  	}
    54  	nsFile := NsName(ns)
    55  	// if the namespace type is unknown, just return false
    56  	if nsFile == "" {
    57  		return false
    58  	}
    59  	_, err := os.Stat("/proc/self/ns/" + nsFile)
    60  	// a namespace is supported if it exists and we have permissions to read it
    61  	supported = err == nil
    62  	supportedNamespaces[ns] = supported
    63  	return supported
    64  }
    65  
    66  func NamespaceTypes() []NamespaceType {
    67  	return []NamespaceType{
    68  		NEWUSER, // Keep user NS always first, don't move it.
    69  		NEWIPC,
    70  		NEWUTS,
    71  		NEWNET,
    72  		NEWPID,
    73  		NEWNS,
    74  		NEWCGROUP,
    75  	}
    76  }
    77  
    78  // Namespace defines configuration for each namespace.  It specifies an
    79  // alternate path that is able to be joined via setns.
    80  type Namespace struct {
    81  	Type NamespaceType `json:"type"`
    82  	Path string        `json:"path"`
    83  }
    84  
    85  func (n *Namespace) GetPath(pid int) string {
    86  	return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type))
    87  }
    88  
    89  func (n *Namespaces) Remove(t NamespaceType) bool {
    90  	i := n.index(t)
    91  	if i == -1 {
    92  		return false
    93  	}
    94  	*n = append((*n)[:i], (*n)[i+1:]...)
    95  	return true
    96  }
    97  
    98  func (n *Namespaces) Add(t NamespaceType, path string) {
    99  	i := n.index(t)
   100  	if i == -1 {
   101  		*n = append(*n, Namespace{Type: t, Path: path})
   102  		return
   103  	}
   104  	(*n)[i].Path = path
   105  }
   106  
   107  func (n *Namespaces) index(t NamespaceType) int {
   108  	for i, ns := range *n {
   109  		if ns.Type == t {
   110  			return i
   111  		}
   112  	}
   113  	return -1
   114  }
   115  
   116  func (n *Namespaces) Contains(t NamespaceType) bool {
   117  	return n.index(t) != -1
   118  }
   119  
   120  func (n *Namespaces) PathOf(t NamespaceType) string {
   121  	i := n.index(t)
   122  	if i == -1 {
   123  		return ""
   124  	}
   125  	return (*n)[i].Path
   126  }
   127  

View as plain text