Namespaces reads from /proc/ /ns/* to get the namespaces of which the process is a member.
()
| 32 | // Namespaces reads from /proc/<pid>/ns/* to get the namespaces of which the |
| 33 | // process is a member. |
| 34 | func (p Proc) Namespaces() (Namespaces, error) { |
| 35 | d, err := os.Open(p.path("ns")) |
| 36 | if err != nil { |
| 37 | return nil, err |
| 38 | } |
| 39 | defer d.Close() |
| 40 | |
| 41 | names, err := d.Readdirnames(-1) |
| 42 | if err != nil { |
| 43 | return nil, fmt.Errorf("%w: failed to read contents of ns dir: %w", ErrFileRead, err) |
| 44 | } |
| 45 | |
| 46 | ns := make(Namespaces, len(names)) |
| 47 | for _, name := range names { |
| 48 | target, err := os.Readlink(p.path("ns", name)) |
| 49 | if err != nil { |
| 50 | return nil, err |
| 51 | } |
| 52 | |
| 53 | fields := strings.SplitN(target, ":", 2) |
| 54 | if len(fields) != 2 { |
| 55 | return nil, fmt.Errorf("%w: namespace type and inode from %q", ErrFileParse, target) |
| 56 | } |
| 57 | |
| 58 | typ := fields[0] |
| 59 | inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32) |
| 60 | if err != nil { |
| 61 | return nil, fmt.Errorf("%w: inode from %q: %w", ErrFileParse, fields[1], err) |
| 62 | } |
| 63 | |
| 64 | ns[name] = Namespace{typ, uint32(inode)} |
| 65 | } |
| 66 | |
| 67 | return ns, nil |
| 68 | } |