2

I am checking the namespaces associated with a shell process as follows:

# ll /proc/$$/ns
total 0
dr-x--x--x 2 root root 0 May  2 15:10 ./
dr-xr-xr-x 9 root root 0 May  1 18:39 ../
lrwxrwxrwx 1 root root 0 May  2 15:11 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 May  2 15:11 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 May  2 15:11 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 May  2 15:11 net -> net:[4026531957]
lrwxrwxrwx 1 root root 0 May  2 15:11 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 May  2 15:11 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 May  2 15:11 uts -> uts:[4026531838]

I understand that the entries indicate which namespaces a process is associated with. I want to ask where the numbers, identifying each namespace, come from?

For example, the output above indicates that the process mount namespace is mnt:[4026531840]. I checked the mount namespace structure:

 8  struct mnt_namespace {
 9      atomic_t        count;
10      struct ns_common    ns;
11      struct mount *  root;
12      struct list_head    list;
13      struct user_namespace   *user_ns;
14      struct ucounts      *ucounts;
15      u64         seq;    /* Sequence number to prevent loops */
16      wait_queue_head_t poll;
17      u64 event;
18      unsigned int        mounts; /* # of mounts in the namespace */
19      unsigned int        pending_mounts;
20  } __randomize_layout;

I don't see a field that serves as an identifier to be used in /proc/PID/ns/ entries. So how are these identifiers generated?

Jake
  • 1,353

1 Answers1

3

They're the inode numbers of files implemented by the nsfs filesystem, which could be opened and used with the setns(2) to associate a process with a namespace.

You can have a look at fs/nsfs.c:

int ns_get_name(char *buf, size_t size, struct task_struct *task,
                        const struct proc_ns_operations *ns_ops)
{
        struct ns_common *ns;
        int res = -ENOENT;
        const char *name;
        ns = ns_ops->get(task);
        if (ns) {
                name = ns_ops->real_ns_name ? : ns_ops->name;
                res = snprintf(buf, size, "%s:[%u]", name, ns->inum);

and fs/proc/namespaces.c:

static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
en)
{
        ...
        if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
                res = ns_get_name(name, sizeof(name), task, ns_ops);
  • If a program puts different threads in different namespaces, then what do the entries in /proc/$$/ns correspond to .. namespace of the main thread of the process ? Because for each thread there would be an entry in /proc/$$/task/ID/ns. – Jake May 02 '19 at 23:33
  • 2
    The namespaces are per-task (thread), not per-process -- so you can say that /proc/$$/ns corresponds to the namespaces of the main thread (the thread whose TID = PID) –  May 03 '19 at 00:10