I already asked a question about how to list all namespaces in Linux, but there wasn't any correct and exact answers, so I want to find out a method which can help me to find out the namespace of PID of some process or group of processes. How can it be done in Linux?
Linux Process – How to Find Out Namespace of a Particular Process?
linuxnamespaceprocess
Related Solutions
Utilities for working with namespaces have improved since this question was asked in 2013.
lsns
from the util-linux package can list all of the different types of namespaces, in various useful formats.
# lsns --help
Usage:
lsns [options] [<namespace>]
List system namespaces.
Options:
-J, --json use JSON output format
-l, --list use list format output
-n, --noheadings don't print headings
-o, --output <list> define which output columns to use
-p, --task <pid> print process namespaces
-r, --raw use the raw output format
-u, --notruncate don't truncate text in columns
-t, --type <name> namespace type (mnt, net, ipc, user, pid, uts, cgroup)
-h, --help display this help and exit
-V, --version output version information and exit
Available columns (for --output):
NS namespace identifier (inode number)
TYPE kind of namespace
PATH path to the namespace
NPROCS number of processes in the namespace
PID lowest PID in the namespace
PPID PPID of the PID
COMMAND command line of the PID
UID UID of the PID
USER username of the PID
For more details see lsns(8).
lsns
only lists the lowest PID for each process - but you can use that PID with pgrep
if you want to list all processes belonging to a namespace.
e.g. if I'm running gitlab in docker and want to find all the processes running in that namespace, I can:
# lsns -t pid -o ns,pid,command | grep gitlab
4026532661 459 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
and, then use that pid (459) with pgrep
:
# pgrep --ns 459 -a
459 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
623 postgres: gitlab gitlabhq_production [local] idle
[...around 50 lines deleted...]
30172 nginx: worker process
I could also use the namespace id (4026532661) with ps
, e.g.:
ps -o pidns,pid,cmd | awk '$1==4026532661'
[...output deleted...]
You don't need to run process in some control groups if you already in certain namespace, instead you have to manipulate with namespaces. All new process in new namespace will «inherit» all control groups related to that namespace.
Moving processes between different namespaces can be done with setns() function or you can use nsenter command from util-linux
to enter new namespace and then run new tasks in it. All you need is to know PID of process, which already is new namespace, then you can use (in case you want to run links
):
# nsenter --PID --target pid_in_ns_you_want_to_enter && links
It's some cheat, because you don't moving processes, you just entered in namespace and running new processes, but with this possibility you can enter in certain NS and then fork
in it already running in other NS process.
Best Answer
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 itsnet
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:The number in square brackets is the inode number.
To get that for a given process:
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.
Those
/mnt/1/a
,/run/netns/a
may be namespace files.We can get an inode number:
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:
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 theproc
mountpoints in all the/proc/*/task/*/mountinfo
and figure out their type by trying to enter them.