clone和fork+unshare之间的区别

3
以某种方式调用 fork 然后调用 unshare 更容易,因为许多参数通过 fork 复制,否则需要手动包装为 clone。我的问题是,在调用 (1) 以不同命名空间分叉新进程的 clone 和 (2) fork+unshare 之间有什么区别,它们都会分叉一个新进程,并留下父进程的命名空间。假设传递给 cloneunshare 的所有命名空间标志都相同。
auto flag = CLONE_NEWUSER | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD;

因此,使用fork,子进程可以轻松地重用从父进程继承的数据。
int mydata;  // this could be even more complicated, class, struct, etc.
auto pid = fork();
if(pid == 0) {
  // reuse inherited data in a copy-on-write manner
  unshare(flag);
}

在克隆过程中,有时我们需要将数据包装到另一个结构体中,并将其作为 void* 传递给 clone 系统调用。

int mydata;
clone(func, stack+stack_size, flag, &wrapper_of_data);

在上面的例子中,我认为唯一的区别在于性能问题,其中fork可能会更昂贵一些。但是,fork的特性使我在创建新命名空间时节省了很多精力。

1个回答

0
不知为何,调用fork 然后再unshare 更容易,因为通过fork 复制了许多参数,否则这些参数将需要手动包装到clone中。 这仅适用于libc包装函数。 底层系统调用更像是fork(),在这种情况下可能效果更好。
long flags = CLONE_NEWUSER | ... | SIGCHLD;
long pid = syscall(__NR_clone, flags, 0, 0, 0, 0);

if(pid == 0) {
    /* child with unshared namespaces */
}

自从引入了克隆系统调用以来,fork()只是使用flags=SIGCHLD和其他参数都为0的特定情况下的克隆。

可能没有理由优先选择fork/unshare对而不是直接将相同的标志传递给克隆函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接