我正在学习linux核心,现在我正在讨论名字包的话题。我试着使用"unshare“命令,只是为了了解名称空间及其要点。问题是它没有,或者,更有可能的是,我做错了什么。如果你能帮我理解我会很感激。我试图在它自己的PID命名空间中执行busybox程序。我就是这么做的:
[ab@a ~]$ sudo unshare --pid busybox sh
/home/ab # ps
PID TTY TIME CMD
6014 pts/1 00:00:00 sudo
6016 pts/1 00:00:00 busybox
6026 pts/1 00:00:00 ps因此,正如我从ps命令的输出中看到的那样,在新的env中所有进程都是可见的。当我检查新创建的进程和当前进程的pid命名空间id时,它得到了确认。见下文
[ab@a ~]$ ps -p 6016,$$
PID TTY TIME CMD
4604 pts/0 00:00:00 bash
6016 pts/1 00:00:00 busybox
[ab@a ~]$ sudo ls -l /proc/4604/ns
total 0
lrwxrwxrwx. 1 ab ab 0 Aug 8 23:49 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 ab ab 0 Aug 8 23:49 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 ab ab 0 Aug 8 23:49 net -> net:[4026531968]
lrwxrwxrwx. 1 ab ab 0 Aug 8 23:49 pid -> pid:[4026531836]
lrwxrwxrwx. 1 ab ab 0 Aug 8 23:49 user -> user:[4026531837]
lrwxrwxrwx. 1 ab ab 0 Aug 8 23:49 uts -> uts:[4026531838]
[ab@a ~]$ sudo ls -l /proc/6016/ns
total 0
lrwxrwxrwx. 1 root root 0 Aug 9 00:07 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 root root 0 Aug 9 00:07 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 root root 0 Aug 9 00:07 net -> net:[4026531968]
lrwxrwxrwx. 1 root root 0 Aug 9 00:07 pid -> pid:[4026531836]
lrwxrwxrwx. 1 root root 0 Aug 9 00:07 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 Aug 9 00:07 uts -> uts:[4026531838]因此,pid命名空间保持不变,尽管我为取消共享调用提供了--pid参数。你能帮我理解一下为什么会发生这种事吗。谢谢
发布于 2021-08-09 02:07:23
解决方案
您应该按照手册页中的说明将--fork和--mount-proc开关添加到unshare中。
-f,-叉叉将指定的程序作为取消共享的子进程,而不是直接运行它。这在创建新的PID命名空间时非常有用。注意,当unshare正在等待子进程时,它会忽略SIGINT和SIGTERM,并且不会向子进程转发任何信号。有必要向子进程发送信号。
解释(来自man pid_namespaces)
进程的PID命名空间成员资格是在创建进程时确定的,以后不能更改。
unshare在提供--pid时实际上所做的是将当前进程的文件描述符设置为新的PID命名空间,从而导致随后由该进程创建的子进程位于不同的PID命名空间中(其子进程不是其本身!重要!)。
因此,当您向--fork提供unshare时,它将将您的程序(在本例中为busybox sh)作为取消共享的子进程进行分叉,并将其放在新的PID命名空间中。
为什么我需要--mount-proc?
尝试只使用--pid和--fork运行unshare,让我们看看会发生什么。
wendel@gentoo-grill ~λsudo unshare --pid --叉式busybox sh /home/wendel # echo $$ 1 /home/wendel # ps PID用户时间命令12443 root 0:00 unshare -pid-叉busybox sh 12444 root 0:00 busybox sh 24370 root 0:00 {ps} busybox sh。。。//更多
从echo $$中我们可以看到pid实际上是1,所以我们知道我们必须在新的PID命名空间中,但是当我们运行ps时,我们看到了其他进程,就好像我们仍然在父PID命名空间中一样。
这是因为/proc是一个名为procfs的特殊文件系统,内核是在内存中和手册页中创建的。
--
/proc文件系统只显示(在/proc/[pid]目录中)执行挂载的进程的PID命名空间中可见的进程,即使从其他名称空间的进程中查看/proc文件系统也是如此。
因此,为了使诸如ps这样的工具正确工作,我们需要使用新命名空间中的进程重新挂载/proc。
但是,假设您的进程位于根挂载命名空间中,如果我们重新挂载/proc,对于相同挂载命名空间中的其他进程来说,这将给许多事情带来麻烦,因为现在他们看不到任何东西(在/proc中)。因此,您还应该将您的进程放在新的挂载命名空间中。
好的是取消共享有--mount-proc。
--挂载- proc =挂载点就在运行程序之前,在挂载点挂载proc文件系统(默认为/proc)。这在创建新的PID命名空间时非常有用。这还意味着创建一个新的挂载命名空间,因为否则/proc挂载会扰乱系统上的现有程序。新的proc文件系统显式地以私有方式挂载(使用MS_PRIVATE|MS_REC)。
让我们验证一下--mount-proc是否也将您的进程放置在新的挂载命名空间中。
在外面巴什:
wendel@gentoo-grill ~λls -go /proc/$/ns/{user,mnt,pid} lrwxrwxrwx 1 08月9日10:05 /proc/17011/ns/mnt -> 'mnt:4026531840‘lrwxrwxrwx 10:10 /proc/17011/ns/pid -> 'pid:4026531836’lrwxrwxrwx1 08月9日10:10 :10/proc/17011/ns/ ->‘用户:4026531837’
百事箱:
wendel@gentoo-grill ~λdoas ls -go /proc/16436/ns/{user,mnt,pid} lrwxrwxrwx 1 0 8月9日10:05 /proc/16436/ns/mnt -> 'mnt:4026533479‘lrwxrwxrwx 10:04 /proc/16436/ns/pid -> 'pid:4026533481’lrwxrwxrwx10:17/proc/16436/ns/ ->‘用户:4026531837’
注意,他们的用户名称空间是相同的,但是挂载和pid不是。
注意:你可以看到我从手册中引用了很多。如果您想了解更多关于linux名称空间(或任何真正的unix )的知识,首先要做的就是读取每个名称空间的手册页。它写得很好,内容也很丰富。
https://stackoverflow.com/questions/68704803
复制相似问题