proc_ns.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package procfs
  2. import (
  3. "fmt"
  4. "os"
  5. "strconv"
  6. "strings"
  7. )
  8. // Namespace represents a single namespace of a process.
  9. type Namespace struct {
  10. Type string // Namespace type.
  11. Inode uint32 // Inode number of the namespace. If two processes are in the same namespace their inodes will match.
  12. }
  13. // Namespaces contains all of the namespaces that the process is contained in.
  14. type Namespaces map[string]Namespace
  15. // NewNamespaces reads from /proc/[pid/ns/* to get the namespaces of which the
  16. // process is a member.
  17. func (p Proc) NewNamespaces() (Namespaces, error) {
  18. d, err := os.Open(p.path("ns"))
  19. if err != nil {
  20. return nil, err
  21. }
  22. defer d.Close()
  23. names, err := d.Readdirnames(-1)
  24. if err != nil {
  25. return nil, fmt.Errorf("failed to read contents of ns dir: %v", err)
  26. }
  27. ns := make(Namespaces, len(names))
  28. for _, name := range names {
  29. target, err := os.Readlink(p.path("ns", name))
  30. if err != nil {
  31. return nil, err
  32. }
  33. fields := strings.SplitN(target, ":", 2)
  34. if len(fields) != 2 {
  35. return nil, fmt.Errorf("failed to parse namespace type and inode from '%v'", target)
  36. }
  37. typ := fields[0]
  38. inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32)
  39. if err != nil {
  40. return nil, fmt.Errorf("failed to parse inode from '%v': %v", fields[1], err)
  41. }
  42. ns[name] = Namespace{typ, uint32(inode)}
  43. }
  44. return ns, nil
  45. }