How to find out namespace of a particular process?
I'll try and answer both this and your earlier question as they are related.
The doors to namespaces are files in /proc/*/ns/*
and /proc/*/task/*/ns/*
.
A namespace is created by a process unsharing its namespace. A namespace can then be made permanent by bind-mounting the ns
file to some other place.
That's what ip netns
does for instance for net namespaces. It unshares its net
namespace and bind-mounts /proc/self/ns/net
to /run/netns/netns-name
.
In a /proc
mounted in the root pid namespace, you can list all the namespaces that have a process in them by doing:
# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]
The number in square brackets is the inode number.
To get that for a given process:
# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid
Now, there may be permanent namespaces that don't have any process in them. Finding them out can be a lot trickier AFAICT.
First, you have to bear in mind that there can be several mount namespaces.
# awk '$9 == "proc" {print FILENAME,$0}' /proc/*/task/*/mountinfo | sort -k2 -u
/proc/1070/task/1070/mountinfo 15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/19877/task/19877/mountinfo 50 49 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 57 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/1070/task/1070/mountinfo 66 39 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 68 67 0:3 / /mnt/1/a rw,nosuid,nodev,noexec,relatime unbindable - proc proc rw
Those /mnt/1/a
, /run/netns/a
may be namespace files.
We can get an inode number:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a
But that doesn't tell us much other than it's not in the list computed above.
We can try and enter it as any of the different types:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --pid=/mnt/1/a true
nsenter: reassociate to namespace 'ns/pid' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --mount=/mnt/1/a true
nsenter: reassociate to namespace 'ns/mnt' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --net=/mnt/1/a true
#
OK, that was a net
namespace file.
So it would seem we have a method to list the name spaces: list the ns
directories of all the tasks, then find all the proc
mountpoints in all the /proc/*/task/*/mountinfo
and figure out their type by trying to enter them.
If you have util-linux v2.28 or above you can use lsns:
# lsns
NS TYPE NPROCS PID USER COMMAND
4026531836 pid 78 1 root /sbin/init
4026531837 user 79 1 root /sbin/init
4026531838 uts 78 1 root /sbin/init
4026531839 ipc 78 1 root /sbin/init
4026531840 mnt 75 1 root /sbin/init
4026531857 mnt 1 12 root kdevtmpfs
4026531957 net 79 1 root /sbin/init
4026532393 mnt 1 1214 root /lib/systemd/systemd-udevd
4026532415 mnt 1 2930 systemd-timesync /lib/systemd/systemd-timesyncd
4026532477 mnt 1 32596 root -bash
4026532478 uts 1 32596 root -bash
4026532479 ipc 1 32596 root -bash
4026532480 pid 1 32596 root -bash
Correction: lsns is not available in util-linux v2.27 as this answer used to say. See https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes
ps
now has output options for the different types of namespaces associated with processes: ipcns
, mntns
, netns
, pidns
, userns
, and utsns
. For this question, the relevant one is the PID namespace, or pidns
.
so if you wanted to find out the PID namespace id for, e.g., pid 459:
# ps -h -o pidns -p 459
4026532661
and to list all processes in that namespace:
ps -o pidns,pid,cmd | awk '$1==4026532661'
or with pgrep
, you can go directly from a PID to a list of all processes sharing that same PID namespace:
pgrep -a --ns 459
Unlike ps
, pgrep
can limit the output to a specific namespace (if you know the PID of one of the processes in it), but has very limited output formatting capabilities (PIDs only, or PIDs and their command lines)
You can always pipe the output of pgrep --ns 459
to xargs ps -f
though to retrieve the information you need about the process.