10

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)

5 Answers 5

17

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
13
  • I used the first form (I use bash), but I get an error when I run find -L /proc/*/task/*/ns/net -samefile /run/netns/"$netns" find: '/proc/self/task/8964/ns/net': No such file or directory (where 8964 is current pid [$$] ) - should I be running this in the default namespace ?
    – Ani
    Jun 30, 2015 at 12:08
  • @vyom, yes from the top level pid and mount namespace (though I suppose you could create netns'es in other mount namespaces which would void that command). Jun 30, 2015 at 12:25
  • doesn't seem to be working for me :(. I tried from /, and I have created the netns, in the usual way - ip netns add, and I can see it in /var/run/netns/. Not sure what I am missing
    – Ani
    Jun 30, 2015 at 12:33
  • @vyom, does grep /run/netns /proc/self/mountinfo report anything? What kernel version are you using (uname -rs)? Jun 30, 2015 at 12:40
  • 2
    ip netns help lists the command netns pids NAME which, as I think, is supposed to list all of the pids in a name netns.
    – mikeserv
    Jun 30, 2015 at 22:03
6

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

2
  • 2
    Pretty similar to unix.stackexchange.com/a/354038/117549
    – Jeff Schaller
    Aug 1, 2018 at 13:06
  • some namespace don't have a file in /var/run/netns/, so the namespace is no NAME, (such as process 1 , the init process). ip command can not work in this situation
    – tinyhare
    Nov 23, 2022 at 17:57
4

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>

1
  • 2
    Unfortunately, ip netns only works on network namespaces bind-mounted on /run/netns (also /var/run/netns). It is completely ignorant to any other network namespaces, either bind-mounted in other places, such as /run/docker, and it especially is totally ignorant of /proc.
    – TheDiveO
    Jun 12, 2018 at 20:30
1

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:

0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .