我正在尝试将 /mnt 上的 ext4 文件系统安装到 mount_dir 中,这是我使用 mkdtemp(2) 和 MS_SHARED 创建的临时目录,然后使用 MS_PRIVATE 重新安装,这个想法是从 /mnt 文件系统创建一个安装命名空间并防止任何从命名空间内到原始文件系统的传播事件。
我尝试了不同的标志组合,但只有 MS_BIND | MS_PRIVATE 有效,但事件似乎仍然传播到原始文件系统。
fprintf(stderr,"-->Mounting file system from base image...");
if(mount("/mnt", mount_dir, NULL, MS_SHARED , NULL)){
fprintf(stderr, "%s Failed..%m\n",mount_dir);
return -1;
}else{
fprintf(stderr,"Success\n");
}
fprintf(stderr,"-->Remounting mount point as MS_PRIVATE...");
if(mount(NULL, mount_dir, NULL, MS_REMOUNT | MS_PRIVATE, NULL)){
fprintf(stderr,"Failed..%m\n");
return -1;
}else{
fprintf(stderr, "Success.\n");
}
答案1
您显示的代码中的两个挂载调用都需要更改。在第一次调用中,创建挂载时,不应指定该MS_SHARED
标志;这会触发你的EINVAL
错误。相反,只需创建不带该标志的安装(即参数flags
应为 0)。这将创建一个具有默认传播类型的新安装点。MS_SHARED
如果父挂载也具有共享传播,则该类型为,否则传播类型为MS_PRIVATE
。 (有关更多详细信息,请参阅mount_namespaces(7)
手册页中的“注释”部分.)
在第二次mount()
调用中,您不需要该MS_REMOUNT
标志,事实上,当您使用该标志时,该MS_PRIVATE
标志将被忽略。请参阅安装(2)手册页(特别要注意“测试按照此处列出的顺序进行”):
A call to mount() performs one of a number of general types of
operation, depending on the bits specified in mountflags. The
choice of which operation to perform is determined by testing the
bits set in mountflags, with the tests being conducted in the
order listed here:
* Remount an existing mount: mountflags includes MS_REMOUNT.
* Create a bind mount: mountflags includes MS_BIND.
* Change the propagation type of an existing mount: mountflags
includes one of MS_SHARED, MS_PRIVATE, MS_SLAVE, or MS_UNBIND‐
ABLE.
* Move an existing mount to a new location: mountflags includes
MS_MOVE.
* Create a new mount: mountflags includes none of the above
flags.
MS_REMOUNT
只需在第二次调用中删除该标志mount()
,您就应该获得(我认为)您想要的结果。
我不太确定为什么需要这个两步过程,但我怀疑原因是设计mount()
API 的限制。多年来,该 API 不断添加一些内容(请参阅上面引用的文本以获取证据),并且到添加挂载传播功能时(2005 年左右),这可能是唯一向后兼容的方法。