1

Is it possible to find the PID of the child process which is in a separate PID namespace?

I am able to get the child process PID with respect to the parent namespace but I need to find the PID of the child with respect to separate PID namespace where the child is currently running.

I am able to get PID from a child via IPC, but is there any way to find it without child process help?

0
1

Given the PID of a process, the information of all the PID namespaces it belongs to is available from a proc entry in /proc/PID/status:

 NStgid                      descendant namespace thread group ID hierarchy

Or from man proc:

NStgid : Thread group ID (i.e., PID) in each of the PID namespaces of which [pid] is a member. The leftmost entry shows the value with respect to the PID namespace of the reading process, followed by the value in successively nested inner namespaces. (Since Linux 4.1.)

I don't know if there's any other method than using /proc to retrieve this information.


Here's an example with a sleep process that was started in a LXC-within-a-LXC container so will have two nested PIDs (aka tgids) when read from the initial PID namespace:

# pidof sleep
443701
# grep ^NStgid: /proc/443701/status 
NStgid: 443701  685 170

So its PID is 685 in the intermediate namespace and 170 in the final namespace: this process sees itself as having a PID of value 170.

The last entry is how the process sees itself.

If a parent process spawned a child process in an other PID namespace without using the newer clone3(2) system call, it will exist only in one additional PID namespace anyway, and its pid there will be the 3rd and last entry in the line (counting NStgid: as first entry). If doing checks by entering those PID namespaces (using nsenter(1)or setns(2)), care must be taken to also create a new dummy mount namespace (with unshare(1), unshare(2) or clone(2)) and mount again /proc there, or /proc entries will still reflect the parent PID namespace's values and won't appear to change.

Further examples following above. Check that's the sleep command:

# nsenter -t 443701 -p unshare -m --mount-proc ls -l /proc/170/exe   
lrwxrwxrwx 1 root root 0 Dec 21 23:03 /proc/170/exe -> /bin/sleep

Having a PID reference in the intermediate PID namespace (the intermediate LXC container is named stretch-amd64) will allow to know how it's seen from there:

# lxc-info -Hp -n stretch-amd64
442977
# nsenter -t 442977 -p unshare -m --mount-proc grep ^NStgid: /proc/685/status
NStgid: 685 170
0

A process can have many children. The best way to get a child PID is to get it when the child is created. Both fork and clone return child PID on success.

6
  • Yeah, but fork and clone returns the PID of the child with respect to the parent namespace. let say a parent is in ns1 namespace and the child is spawned in ns2 namespace (via CLONE_NEWPID). now child process PID is 1 because it is the first process in the ns2 namespace. how to get the child process PID as 1 from the parent process? Dec 21 '20 at 13:43
  • So, is it not 1? Dec 21 '20 at 18:13
  • No, PID returned to the parent by clone or fork will be the PID of child process with respect to namespace where parent is running. Dec 21 '20 at 19:23
  • If fork or clone returned PID as 1 then If again parent spawns the other children in another namespace say ns3, It will also has PID as 1. Which makes PID collision so, linux will not do that. Dec 21 '20 at 19:26
  • Sorry there is something very fundamental that I am missing. Only I know not what it is. Dec 21 '20 at 22:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.