我正在尝试将 /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");
}
您显示的代码中的两个挂载调用都需要更改。在第一次调用中,创建挂载时,不应指定
MS_SHARED
标志;这是触发你的EINVAL
错误。相反,只需创建不带该标志的挂载(即,flags
参数应为 0)。这将创建一个具有默认传播类型的新挂载点。如果父挂载也具有共享传播,则该类型为MS_SHARED
,否则传播类型为MS_PRIVATE
. (有关更多详细信息,请参阅手册页中的注释部分mount_namespaces(7)
。)在第二次
mount()
调用中,您不需要该MS_REMOUNT
标志,实际上当您使用该标志时,该MS_PRIVATE
标志被忽略。请参阅mount(2)手册页(特别注意“按照此处列出的顺序进行测试”):只需在第二次调用中删除
MS_REMOUNT
标志,mount()
您应该获得(我认为)您想要的结果。我不确定为什么需要这个两步过程,但我怀疑原因是设计
mount()
API 的限制。多年来,该 API 一直在不断添加片段(请参阅上面引用的文本以获取证据),并且在添加挂载传播功能时(大约 2005 年),这可能是唯一向后兼容的方式来做到这一点.