How to list processes belonging to a network namespace?

I am on Ubuntu 12.04, and the ip utility does not have ip netns identify <pid> option, I tried installing new iproute, but still, the option identify doesn’t
seem to be working!.

If I were to write a script (or code) to list all processes in a network-namespace, or given a PID, show which network-namespace it belongs to, how should I proceed ?
(I need info on a handful of processes, to check if they are in the right netns)

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You could do something like:

netns=myns
find -L /proc/[1-9]*/task/*/ns/net -samefile /run/netns/"$netns" | cut -d/ -f5

Or with zsh:

print -l /proc/[1-9]*/task/*/ns/net(e:'[ $REPLY -ef /run/netns/$netns ]'::h:h:t)

It checks the inode of the file which the /proc/*/task/*/ns/net symlink points to agains those of the files bind-mounted by ip netns add in /run/netns. That’s basically what ip netns identify or ip netns pid in newer versions of iproute2 do.

That works with the 3.13 kernel as from the linux-image-generic-lts-trusty package on Ubuntu 12.04, but not with the 3.2 kernel from the first release of 12.04 where /proc/*/ns/* are not symlinks and each net file there from every process and task gets a different inode which can’t help determine namespace membership.

Support for that was added by that commit in 2011, which means you need kernel 3.8 or newer.

With older kernels, you could try and run a program listening on an ABSTRACT socket in the namespace, and then try to enter the namespace of every process to see if you can connect to that socket there like:

sudo ip netns exec "$netns" socat abstract-listen:test-ns,fork /dev/null &
ps -eopid= |
  while read p; do
    nsenter -n"/proc/$p/ns/net" socat -u abstract:test-ns - 2> /dev/null &&
      echo "$p"
  done

Method 2

ps $(ip netns pids myns)
where myns is your namespace

Method 3

The question specifically mentions Ubuntu 12.04, but I note that on newer distros like 16.04 there is a command that does exactly this: ip netns pids <nsname>

Method 4

Namespace-Lister:

You can use listns.py with: ./listns.py or python2 listns.py
(source: github-mirror and article; all credit to Ralf Trezeciak)

IP-Netns:

Can be done with the following (replace $namespace-name):

ip netns pids $namespace-name | xargs ps -o pid,command -p

Nsutils

Provide netnslist that list all the net namespaces and all the processes running in each namespace:

Method 5

When running inside the container as opposed to outside, I found the -samefile trick sadly didn’t work. Not sure why as it was the same inode. Anyway, this however did work, just in case it is of use to anyone:

netns=mynamespace
inode=$(ls -i /var/run/netns/$netns | cut -f1 -d" ")
pids=$(find -L /proc/[1-9]*/task/*/ns/net -inum $inode | cut -f3 -d"/" | uniq)
ps -p $pids


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x