是否可以找到位于单独 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。