重新挂载为只读而不更改其他选项

重新挂载为只读而不更改其他选项

在工作中systemd-shutdown,它用于mount()将文件系统重新挂载为只读。

/* MS_REMOUNT requires that the data parameter
 * should be the same from the original mount
 * except for the desired changes. Since we want
 * to remount read-only, we should filter out
 * rw (and ro too, because it confuses the kernel) */
...filter_options(m->options, "rw\0ro\0", NULL, NULL, &options);

...mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options)...

但是当我查看时strace mount -oremount,rw /bootmount系统调用传递了 NULL 作为其最后一个参数。这是否表明实际上没有必要复制和修改旧的选项字符串?

答案1

不。

如果您编辑/etc/fstab并添加非通用选项foo/sbin/mount则会将“foo”作为最后一个参数传递给mount()。在您的示例中,它传递了 NULL,但我认为这意味着空 string ""。想必它们具有相同的效果。


/sbin/mount如果您同时传递路径和设备,显然行为会有所不同(!)。

重新挂载功能遵循 mount 命令与 fstab 中的选项配合使用的标准方式。这意味着仅当同时指定了 device 和 dir 时,mount 才不会读取 fstab(或 mtab)。

 mount -o remount,rw /dev/foo /dir

在此调用之后,所有旧的挂载选项都将被替换,并且 fstab(或 mtab)中的任意内容都将被忽略,除了由 mount 命令内部生成和维护的 Loop= 选项。

 mount -o remount,rw  /dir

在此调用之后,mount 读取 fstab 并将这些选项与命令行 (-o) 中的选项合并。如果在 fstab 中找不到挂载点,则允许使用未指定的源重新挂载。

言外之意是,最后一种情况似乎也覆盖了挂载点的任何当前选项。


问题中引用的代码有些可疑。它似乎重置了安装标志。当前行为:

重新安装现有安装

... mountflags 和 data 参数应该与原始 mount() 调用中使用的值匹配,除了那些被故意更改的参数之外。

所以这可能就是评论的来源。

可以更改以下安装标志:MS_LAZYTIME、MS_MANDLOCK、MS_NOATIME、MS_NODEV、MS_NODIRATIME、MS_NOEXEC、MS_NOSUID、MS_RELATIME、MS_RDONLY 和 MS_SYNCHRONOUS。

我猜代码是现在工作正常。以只读方式重新挂载可以避免有关后续写入的问题,或者由于 blockdev 是只读而导致读写重新挂载被拒绝。systemd-shutdown此时应该已将 SIGKILL 发送到有权访问文件系统的任何其他进程,因此我们可以忽略 NOEXEC 等安全选项。

在重新安装期间更改 MS_DIRSYNC 标志设置的尝试将被静默忽略。

尽管这意味着其他标志可能不会被默默地忽略,并且如果它们不匹配可能会导致调用失败,但我不认为核心内核代码会执行类似的操作。

从 Linux 3.17 开始,如果在 mountflags 中未指定 MS_NOATIME、MS_NODIRATIME、MS_RELATIME 或 MS_STRICTATIME 中的任何一个,则重新挂载操作将保留这些标志的现有值(而不是默认为 MS_RELATIME)。

从 Linux 2.6.26 开始,此标志还可以通过将 mountflags 指定为只读来使现有的绑定挂载变为只读:

MS_REMOUNT | MS_BIND | MS_RDONLY

我想 systemd-shutdown 没有以完全相同的方式处理 fstab 就好mount -oremount,ro /boot了:)。 (旧的 sysvinit 脚本至少在 Debian 中没问题,因为除了根文件系统之外,它们不使用 remount RO)。

相关内容