是否可以检查不同 pid 命名空间中子进程的进程 id?

是否可以检查不同 pid 命名空间中子进程的进程 id?

是否可以找到位于单独 PID 命名空间中的子进程的 PID?

我能够获取相对于父命名空间的子进程 PID,但我需要相对于子进程当前运行的单独 PID 命名空间找到子进程的 PID。

我可以通过 IPC 从子进程获取 PID,但是有没有办法在没有子进程帮助的情况下找到它?

答案1

给定一个进程的 PID,它所属的所有 PID 命名空间的信息都可以从过程入口/proc/PID/status

 NStgid                      descendant namespace thread group ID hierarchy

或来自man proc:

NStgid : [pid] 所属的每个 PID 命名空间中的线程组 ID(即 PID)。最左边的条目显示了相对于读取进程的PID命名空间, 其次是连续嵌套的内部命名空间中的值。 (从 Linux 4.1 开始。)

我不知道除了使用之外是否还有其他方法/proc来检索此信息。


下面是一个在 LXC-within-LXC 容器中启动的睡眠进程示例,因此从初始 PID 命名空间读取时将有两个嵌套 PID(又名 tgids):

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

因此,其 PID 在中间命名空间中为 685,在最终命名空间中为 170:该进程将自己视为具有值为 170 的 PID。

最后一个条目是进程如何看待自身。

如果父进程在其他 PID 命名空间中生成了一个子进程而不使用较新的clone3(2)系统调用,则无论如何它都将仅存在于一个附加的 PID 命名空间中,并且其 pid 将是该行中的第三个也是最后一个条目(计NStgid:为第一个条目) )。如果通过输入这些 PID 命名空间(使用nsenter(1)setns(2))进行检查,还必须注意创建一个新的虚拟挂载命名空间(使用unshare(1)unshare(2)clone(2))并/proc在此处再次挂载,否则/proc条目仍将反映父 PID 命名空间的值并且不会出现改变。

进一步的例子如下。检查这是睡眠命令:

# 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

在中间 PID 命名空间中有一个 PID 引用(中间 LXC 容器名为拉伸-amd64)将允许知道从那里看到的如何:

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

答案2

一个进程可以有多个子进程。获取子进程 PID 的最佳方法是在创建子进程时获取它。成功fork时 和都会clone返回子 PID。

相关内容