Detecting per-process namespaces

Back with per-process namespaces. This time, I will give several methods to more or less reliably detect their use, some requiring root access, some not. We will, though, limit ourselves to "mount namespaces", that is, not PID, UTS or network namespaces.

The first method, which is based on the contents of /proc/pid/mounts should work on any kernel supporting namespaces (since 2.4.19):

$ md5sum /proc/[0-9]*/mounts | awk -F'[ /]*' '{ ns[$1] = ns[$1] ? ns[$1] "," $3 : $3 } END { for (n in ns) { print n, ns[n] } }'

/proc/[0-9]* is used instead of /proc/* to avoid listing self, too. The awk script displays a summary : a md5 sum followed by the PID of all processes which /proc/self/mounts file has this md5 sum.
This method relies on the fact that the /proc/pid/mounts files may be different between namespaces, even when the same mount points are used because the ordering may differ. This method is obviously unreliable, except when all namespaces have different mount points. During my tests, it has been reliable to detect whether a process uses the same namespace as the init process, but different processes with different namespaces were reliably listed together as having the same namespace.

The next method, based on the contents of /proc/pid/mountinfo will work on any kernel implementing this file (since 2.6.26):

$ md5sum /proc/[0-9]*/mountinfo | awk -F'[ /]*' '{ ns[$1] = ns[$1] ? ns[$1] "," $3 : $3 } END { for (n in ns) { print n, ns[n] } }'

The script is essentially the same, only pointing at mountinfo instead of mounts.
This method is quite reliable, as /proc/pid/mountinfo does contain different information even when no mount point was changed within a namespace. Unfortunately, chrooted processes can have a different content while not being in a separate namespace. I've not investigated further, but you may be able to spot chrooted processes by comparing /proc/pid/mountinfo and /proc/pid/mounts.

Both the above methods can be executed as unprivileged user, which alleviates the fact they are not totally reliable.

The last method, on the other hand, is reliable, but requires root privileges, and cgroup filesystem support in the kernel (since 2.6.24).

$ mkdir -p /dev/cgroup/ns
$ mount -t cgroup -o ns /dev/cgroup/ns
$ find /dev/cgroup/ns -name tasks | xargs -l1 sed ':a;N;s/\n/,/g;ta'

The output here is a group of PID on separate lines for separate namespaces. The sed one-liner replaces all carriage returns in the tasks files with a comma.
You don't actually need root privileges for the last command, if the cgroup filesystem is already mounted. But there has been no normalization as to where the cgroup filesystems should be mounted yet, and they aren't mounted by default on most GNU/Linux distributions, I believe.

Cgroups (Control groups) allow to put sets of processes together to give them special behaviour (cpu provisioning, memory limitations, namespaces, etc.). They also allow to do so in a hierarchical way, such that a cgroup can inherit the properties of its parent cgroup.

As its name and the way it is mounted indicates, our /dev/cgroup/ns is specialized for namespaces cgroups. The directory itself contains a few files, most notably a tasks file containing a list of processes in the current set/cgroup (in our case, namespace). It also contains a subdirectory for each child namespace. Each of these subdirectories is similarly structured, so that it also contains a tasks list and possible subdirectories for its own children.

This means that not only can you spot different namespaces, but you can also spot how they relate to each other.

There are a few glitches, though. As with other cgroups subsystems, you can create new cgroups by creating a directory in the cgroup filesystem, but it happens not to create a new namespace in the case of the namespace subsystem. With all the kind of namespaces that now exist in Linux, this is not a big surprise, but there doesn't seem to be neither a feedback in the cgroup filesystem to know what kind of namespace is involved, nor a control to force creation of a really separate namespace. You also can't move processes from one mount namespace into another by writing a PID in the tasks file in a given namespace ; that just gives an "Operation not permitted" error.

On the other hand, contrary to the second method, chrooted processes are not separated out.

I will investigate further cgroups with PID, UTS and network namespaces and will post my findings.

2009-04-08 21:43:10+0900

p.d.o

Both comments and pings are currently closed.

Comments are closed.