当闪存驱动器/硬盘驱动器连接到系统时,应该安装它。安装过程中到底发生了什么?系统/内核如何跟踪闪存驱动器中存在的内容?
答案1
首先,除非您运行软件来执行此操作,否则它实际上不会自动安装。这种行为完全是从用户空间处理的,而不是在内核中,这一点相当重要,因为自动挂载对于安全来说是一场噩梦(有可能崩溃,或者至少对大多数具有精心制作的文件系统映像的系统进行 DoS)。
现在,至于实际发生的情况,这是 Linux 上使用 udev 和 udisks 的标准组合来触发自动挂载的一般顺序:
- 该设备已物理连接,并由内核进行枚举。内核将其识别为某种块设备,设置适当的驱动程序以将此接口公开给用户空间,然后触发 uevent 告诉用户空间中正在侦听的任何内容新硬件已连接。
- 内核扫描设备的分区。
/dev
Udev 看到此 uevent,并为设备设置各种设备节点和链接。然后,它扫描设备及其分区,以查看存在哪些文件系统以及位置,并将这些数据存储在其他程序可以查询的位置。- Udisks 从内核中查看 uevent,验证 udev 是否已完成设置,然后检查 udev 在步骤 3 中完成的扫描是否发现任何文件系统。如果是这样,并且 udisks 配置为自动挂载新连接的文件系统,它会向内核发出每个文件系统的挂载请求。
- 内核通过在内部执行以下操作(大大简化)来挂载文件系统:
- 它首先检查是否有适合该文件系统类型的驱动程序,如果没有,则尝试加载一个。
- 文件系统驱动程序从文件系统超级块中解析任何所需的元数据(这是存储有关文件系统本身的所有元数据的位置)。
- 创建超级块的内存中副本,并使用文件系统驱动程序和挂载命令提供的数据进行填充。这个数据结构是内核用来在内部引用文件系统的。对内核内文件系统的任何其他内部引用最终都指向这一点。
- 然后,内核使用对此内存中超级块的引用来更新其内部安装表。
现在,至于内核如何“跟踪内容”,要正确解释要复杂得多。简而言之,事实并非如此。每当您尝试访问设备上的文件时,内核都会从文件系统的根目录中查找它。虽然有一个缓存可以加快速度,但除了性能之外,它对其他方面并不重要。
答案2
它通过将内容存储在闪存驱动器中来跟踪闪存驱动器的内容。
它还有一个挂载表(在内核中)。它知道/dev/disk/by-label/home
(到真实设备的链接)已安装在 上/home
。它知道 USB 闪存已安装在/media/my-flash
当您将 dir 更改为这些目录时,它会遍历到其他设备。
使用mount
和df -h
查看当前安装状态。
答案3
现代 Linux 图形界面(例如 GNOME)通过向udisks
后台进程(“服务”)发送请求来挂载文件系统。当您插入驱动器时,它们往往会自动执行此操作。很难找到如何阻止他们这样做,让您mount
自己测试命令的效果。避免这种情况的一种简单方法是登录文本控制台。 (有关在文本控制台上登录的一些信息,请参阅这里)
您还可以使用一个命令将请求发送到udisks
.该命令的当前版本称为udisksctl
.
当您插入 USB 闪存驱动器时,(通常)USB 存储驱动程序会“绑定”到它,并创建一个块设备.[*] 在 Linux 上:请参阅lsblk
(列出块设备)。
同样,当您mount
使用块设备时,您正在将一些文件系统软件绑定到它。不同的文件系统格式有不同的软件。例如,FAT32 文件系统通常用于闪存驱动器; Linux 称此文件系统类型为vfat
。运行时mount
,必须包含两个参数:设备和要挂载文件系统的目录的名称。当您访问该目录名称(例如ls /mnt
)时,您将看到已安装的文件系统代替原始目录。
如果您mount
不带参数运行,它将列出您已安装的文件系统。然而,在 Linux 上,man mount
会告诉您最好使用findmnt
列出文件系统。 findmnt
有很好的输出,可以帮助组织您在 Linux 上安装的许多虚拟文件系统(尽管它不像 那样按字母顺序对它们进行排序ls
)。
df -h
也有很好的输出,因为它排除了 Linux 具有的许多虚拟文件系统,并显示每个文件系统上的可用空间。 (严格来说,一些复杂的 Linux 文件系统设置可能对可用空间的处理比所示的更复杂,例如,通过压缩文件数据,它们可能需要更少的空间)。
全部您可以访问的文件存储在某个已安装的文件系统上。请注意,它/
显示在已安装的文件系统列表中。 /
是“根”目录。 /
是任何文件的完整“路径”(位置)的第一部分。 (注意:文件的完整路径被描述为“绝对”路径)。
根文件系统有一个特殊之处:(umount
卸载)无法对其进行操作。根文件系统始终被视为正在使用。
系统关闭序列会将根文件系统重新挂载为只读 ( mount / -o remount,ro
)。以只读方式重新挂载文件系统是一种请求它将任何更改的文件写回(例如,写入硬盘的块设备)并为干净关闭做好准备的方法。从这个意义上说,它与卸载具有相同的目的。
一些低级Linux软件可以交换根文件系统与另一个已安装的文件系统;这就是所谓的pivot_root
。然后可以卸载旧的根文件系统。这样做需要一些特定的条件,我不会在这里尝试解释。该功能的创建是为了服务于通用 Linux 发行版的引导过程,其中基于 ram 的初始文件系统 (initramfs) 会挂载,然后转向真正的根文件系统。他们为什么这样做有一个解释,这里。
[*] 在 Linux 上,使用驱动程序的第一个设备sd
被分配名称sda
,依此类推。
USB 存储设备接受某种形式的 SCSI。所以usb存储驱动提供了一个scsi设备; (SCSI 磁盘)驱动sd
程序绑定到 scsi 设备并提供块设备。
sd
用于多种类型的块设备。哪些不一定是物理磁盘,而且硬件可能使用不同的命令,这些命令必须是翻译的来自 SCSI。计算机很奇怪;出现这种模式的原因可能取决于许多因素不一定相关的历史细节。