1
miniliuke OP 换句话说怎么能够让一个进程成为 Pid 命名空间的 1 号进程(在所有 Pid 命名空间里的进程都关闭的情况下)?
|
2
miniliuke OP 怎么才能把这个 Pid 命名空间重新运行起来?
|
3
miniliuke OP 难道 pid namespace 的 1 号进程关了就不能用了?
|
4
miniliuke OP 是不是 init 进程结束 pid namespace 就销毁了??????那 docker stop、start 后 pid namespace 不变意味着 docker 不关 init 进程???????
|
5
raysonx 2018-08-28 10:44:16 +08:00
根据文档( man 9 namespaces ),你无法把一个已经存在的进程变成 PID1,只能在 setns 之后用 clone 或者 fork 创建 PID 为 1 的新进程。
|
8
miniliuke OP 如果 PID namespace 中的 init 进程被 kill 掉(SIGKILL),内核会给该 init 的所有其它进程发送 SIGKILL。当 init 结束时,PID namespace 也会被释放,但是也有例外,如果 /proc//ns/pid 被 bind mounted 或者其它进程打开,PID namespace 不会被释放,但是不通过 setns 将新的进程加入到该 PID namespace。
那么问题来了这个 PID namespace 还有救么? |
9
miniliuke OP 可以不被销毁不?
|
10
raysonx 2018-08-28 11:55:34 +08:00 via Android
有点乱。大致思路是 你要先用 setns 把当前进程加入到一个 PID namespace,再调用 fork 或者 clone,这样新进程就被加入新的 PID namespace 了。细节性的东西我得回去翻一下文档。
|
11
raysonx 2018-08-28 11:58:37 +08:00 via Android
PID 1 退出通常意味着 PID namespace 被释放了,类似于电脑关机了。
docker 有一个后台进程( docker daemon )不退出,但是它本身不是 container 里的 PID 1。container 里的 PID 1 是由用户指定的(通过 dockerfile 里的 entrypoint 和 cmd 指令) |
12
miniliuke OP @raysonx 我使用 docker stop 命令发现 container 的进程没了,然后再 docker start 发现 container 的 pid namespace 还是同一个。按理说 pid 1 已经关过了,那 docker 是怎么重用这个 pid namespace 的呢?
|
13
miniliuke OP @raysonx 甚至于我关闭 docker 以后重启还是同一个 pid ns,除非我关机
|
15
miniliuke OP @raysonx 但我自己实现时关闭 pid1 后 pid ns 就不能新建进程但是能 setns,
|
16
miniliuke OP @raysonx 但是 pid namespace 是一样的啊,就是 ls -l /proc/1/ns,发现还是同一个 pid ns
|
17
miniliuke OP @raysonx 对了,大佬还有我去 mount 命名空间只有 mnt ns 没有 mount 上且没有报错,为什么啊? pid 的问题我能理解但解决不了,mnt 的问题我都不知道为什么......
|
18
raysonx 2018-08-28 12:45:46 +08:00
@miniliuke 那可能只是 inode 号被重用了而已,你多执行几次看看,会发现数字会变化,并不是同一个 PID namespace.
关于 mount namespace 的问题,我没有看懂,还请重新描述一遍。 |
19
miniliuke OP @raysonx 就是为将 /proc/进程号 /ns 里面的文件不在进程结束时被销毁,使用 mount 命令挂载到其他文件上,但是只有 mnt 文件没有被挂载上,也不能 setns......
|
20
miniliuke OP @miniliuke 报错 mount: wrong fs type, bad option, bad superblock on /proc/14422/ns/mnt,
missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so. |
21
zealot0630 2018-08-28 13:59:20 +08:00
是的,pid namespace 里面的 init 进程如果退出,这个 namespace 就用不了了。这点和其他 namespace 行为不一样,因为 init 进程在 pid namespace 里面有特殊作用
|
22
miniliuke OP @zealot0630 那为什么 setns 无法设置 mnt namespace,这又是为什么......
|
23
henglinli 2018-08-28 16:51:04 +08:00 via iPhone
@miniliuke 最近折腾过 flatpak,你试试 unprivileged user namespaces kernel.unprivileged_userns_clone
|
24
miniliuke OP @raysonx
@zealot0630 看了 docker 的实现,终于知道为什么加载不了 mnt ns 了,是 golang 的锅......但是 mount --bind /proc/22752/ns/mnt namespace/test/mnt 还是会报错,不知道为什么 mnt 不能被 mount,其他都可以,可能有什么奇奇怪怪的机制吧 |
25
miniliuke OP @henglinli 发现全是 Golang 的锅,现在只有一个问题了,为什么 mount --bind /proc/22752/ns/mnt namespace/test/mnt 会报错.......报错:mount: wrong fs type, bad option, bad superblock on /proc/22752/ns/mnt,missing codepage or helper program, or other error
|
26
raysonx 2018-08-28 17:45:17 +08:00
@miniliuke 应该是 propagation flag 造成的问题。
建议你参考一下"man unshare" 给出的示例: # mount --bind /root/namespaces /root/namespaces # mount --make-private /root/namespaces # touch /root/namespaces/mnt # unshare --mount=/root/namespaces/mnt 换句话讲,你的 namespace/test/mnt 文件所属的 mounting point 的 propagation flag 必须是 private. |