github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/configs/namespaces_unix.go (about)

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