为什么Linux内核支持“umount /”?

sou*_*edi 1 compatibility mount linux-kernel

为什么 Linux 支持这个:

umount /
Run Code Online (Sandbox Code Playgroud)

为什么会有人写这个,而不是这个:

mount / -oremount,ro
Run Code Online (Sandbox Code Playgroud)

我在这里查看内核代码:

if (&mnt->mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
    /*
     * Special case for "unmounting" root ...
     * we just try to remount it readonly.
     */
    if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
        return -EPERM;
    down_write(&sb->s_umount);
    if (!sb_rdonly(sb))
        retval = do_remount_sb(sb, SB_RDONLY, NULL, 0);
Run Code Online (Sandbox Code Playgroud)

https://elixir.bootlin.com/linux/v4.18/source/fs/namespace.c#L1612

sou*_*edi 5

Luciano Andress Martini 指出:

我第一次在 linux 的文件系统中遇到问题时,我收到一条消息,fsck如“/dev/hda2 已安装读写”。在那个时代(1999 年),我不明白这意味着什么。我 11 岁我唯一想到的是:umount /,并且它可以工作(因为它重新安装为只读)。

(这要求没有打开文件进行写入。例如,它可以在系统以单用户模式运行时工作。请注意,运行 fsck 后,要修复仍以只读模式挂载的文件系统,您必须始终重新启动出于安全原因)。

换句话说,如果您甚至不知道重新挂载只读文件系统的命令,您可以尝试与需要 fsck(修复)/dev/fd0或您的/home文件系统相同的命令。特殊情况允许它工作,即使fsck命令位于您显然已卸载的文件系统上:-)。当您尝试修复损坏的系统时,Linux 可以像这样提供帮助,这很好。

这种特殊情况还有另一种用途:umount -a,用于旧的关闭脚本。这被定义为简单地以相反的顺序卸载所有文件系统,以根文件系统结束。它确保所有文件系统在磁盘上都处于一致状态,因此它们fsck在下次启动时不需要。Linux内核并不会自动关闭任何文件系统; 您需要有一些关闭程序或“初始化系统”来执行此操作。

我不确定为什么这个特殊情况是在内核中,而不是在umount命令中。一个原因可能是旧内核接受了挂载设备的名称,而不是文件系统挂载的目录。也许这使得将这些代码放入内核中看起来更简单或更可靠。

当前的手册页中没有记录umount(2)或的特殊情况umount(8)。所以当前的手册页暗示umount -a将始终显示错误,但事实并非如此。我怀疑这umount -a在当今并没有被广泛使用。

在早期版本的 Linux 中有一个非常相似的代码注释,包括 0.99.10 (1993)

这似乎不是传统 UNIX 的标准。FreeBSD 内核反而返回一个错误。我不确定为什么要针对这种情况进行特定的错误检查,与卸载当前正在使用的文件系统的一般错误检查不同。FreeBSD 等价物umount -a意识到了这个问题,并在卸载第一个文件系统即根文件系统之前停止。(代码在这里,但您需要了解for循环和数组索引在 C 中是如何工作的:-)。

依赖于umount -aSysVinit 的较新脚本对比的旧脚本,例如在 Debian 中仍然可用。 /etc/init.d/umount_root明确地重新挂载/为只读。其余的挂载由/etc/init.d/umountfs和单独处理/etc/init.d/umountnfs.sh

umount -a在现代系统上并不理想。保留/proc挂载的文件系统以便/proc/mounts仍然可以使用更简单。并且/dev通常是一个单独的挂载文件系统,它会显示一个卸载错误,因为/dev/console它仍然是打开的。

有关旧关闭脚本的示例,请参阅etc/rc.d/rc.0SysVinit-2.4.tar.z/ 中的参考脚本SysVinit-2.4.tar.gz

#! /bin/sh
#
# brc       This file is executed by init(8) when the system is being
#       shutdown (i.e. set to run at level 0).  It usually takes
#       care of un-mounting al unneeded file systems.
#
# Version:  @(#)/etc/brc        2.01    02/17/93
#
# Authors:  Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
#       Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
#

  PATH=/bin:/etc:/usr/bin
  echo Unmounting file systems.....
  umount -a
  echo Done.
Run Code Online (Sandbox Code Playgroud)