一尘不染

取消共享--pid / bin / bash-fork无法分配内存

linux

我正在尝试使用linux名称空间。特别是pid名称空间。

我以为我可以用bash测试一下,但是遇到了这个问题:

unshare -p /bin/bash
bash: fork: Cannot allocate memory

从那里运行ls进行了核心转储。退出是唯一的可能。

为什么这样做呢?


阅读 700

收藏
2020-06-07

共1个答案

一尘不染

该错误是由PID 1进程在新名称空间中退出引起的。

在bash开始运行之后,bash将派生几个新的子流程来执行某些操作。如果在不使用-
f的情况下运行取消共享,则bash将具有与当前“取消共享”进程相同的pid。当前的“取消共享”进程调用取消共享系统调用,创建新的pid名称空间,但是当前的“取消共享”进程不在新的pid名称空间中。这是linux内核的预期行为:进程A创建一个新的名称空间,进程A本身不会放入新的名称空间,只有进程A的子进程将被放入新的名称空间。因此,当您运行时:

取消共享-p / bin / bash

取消共享进程将执行/ bin / bash,并且/ bin / bash派生几个子进程,bash的第一个子进程将成为新名称空间的PID
1,并且该子进程将在完成其工作后退出。因此,新名称空间的PID 1退出。

PID 1进程具有特殊功能:它应该成为所有孤立进程的父进程。如果根名称空间中的PID 1进程退出,内核将出现恐慌。如果子命名空间中的PID
1进程退出,Linux内核将调用disable_pid_allocation函数,该函数将清除该命名空间中的PIDNS_HASH_ADDING标志。当Linux内核创建新进程时,内核将调用alloc_pid函数在命名空间中分配PID,并且如果未设置PIDNS_HASH_ADDING标志,则alloc_pid函数将返回-
ENOMEM错误。这就是为什么出现“无法分配内存”错误的原因。

您可以使用’-f’选项解决此问题:

取消共享-fp / bin / bash

如果使用’-f’选项运行unshare,unshare将在创建新的pid名称空间后派生一个新进程。然后在新进程中运行/ bin /
bash。新进程将是新pid名称空间的pid 1。然后bash还将派生几个子流程来完成一些工作。由于bash本身是新pid名称空间的pid
1,因此其子进程可以正常退出。

2020-06-07