为什么多分区 USB 闪存驱动器报告的大小不正确?

为什么多分区 USB 闪存驱动器报告的大小不正确?

我正在创建一个自定义 Linux 安装程序,它使用 4GB USB 闪存驱动器上的两个分区:一个用于启动的 EFI 分区和一个用于安装程序文件的数据分区。

报告的大小df是意外的。

parted --script /dev/sdb -- \
    mklabel gpt \
    mkpart primary fat32 2048s 200M \
    name 1 EFI \
    set 1 boot on \
    set 1 esp on \
    mkpart primary fat32 200M 100% \
    name 2 MYDATA


# Format second partition
mkfs.vfat -F 32 -n DATA /dev/sdb2

# parted /dev/sdb p
Model: SanDisk Cruzer (scsi)
Disk /dev/sdb: 4005MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name    Flags
 1      1049kB  200MB   199MB   fat32        EFI     boot, esp
 2      200MB   4003MB  3803MB  fat32        MYDATA

到目前为止一切顺利。现在尝试安装sdb2

# mount /dev/sdb2 /mnt/usb
# df -h
Filesystem                                      Size  Used Avail Use% Mounted on
/dev/loop0                                      1.8G  4.0K  1.8G   1% /mnt/usb

df报告大小只有 1.8G。此外,它还说挂载点是/dev/loop0。为什么?

尝试使用精确的分区偏移量进行挂载会产生不同的结果:

# parted /dev/sdb
GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit b
(parted) p
Model: SanDisk Cruzer (scsi)
Disk /dev/sdb: 4004511744B
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start       End          Size         File system  Name    Flags
 1      1048576B    200278015B   199229440B   fat32        EFI     boot, esp
 2      200278016B  4003463167B  3803185152B  fat32        TORQUE  msftdata

# mount /dev/sdb /mnt/usb -o offset=200278016
# df -h
Filesystem                                      Size  Used Avail Use% Mounted on
/dev/loop0                                      3.6G  4.0K  3.6G   1% /mnt/usb

为什么大小不同?为什么loop0?如果驱动器只有一个分区,则df显示/dev/sdb1为挂载点,而不是loop0

編輯

卡米尔的尝试的建议ls -l /dev/sdb*很好。不知何故/dev/sdb2被替换为文件,可能是脚本错误。这解释了报告的大小,df并解释了为什么mount显示loop0为源而不是/dev/sdb2

$ ls -l /dev/sdb*
brw-rw---- 1 root disk      8, 16 Mar  3 08:48 /dev/sdb
brw-rw---- 1 root disk      8, 17 Mar  3 08:48 /dev/sdb1
-rw-r--r-- 1 root root 1912131584 Mar  2 21:37 /dev/sdb2

删除文件后/dev/sdb2 mount即可df正常工作。

答案1

初始答案:

  • /dev/loop0不是挂载点。/mnt/usb挂载点是文件系统附加的位置。第一列是“源”。

  • 可以将多个文件系统挂载到同一位置(同一挂载点)。它们堆叠在一起,而不是互相替换。实际上,只有最新的挂载(堆栈顶部)才可访问,但所有“底层”挂载仍保留在原位,并继续在findmnt类似文件中可见。

  • 在某些版本中,systemd 管理器会悄悄地自动卸载与 /etc/fstab 条目不对应的文件系统。例如,如果您的 /etc/fstab 表示设备 A 应挂载在 /mnt/foo 上,但您尝试在同一路径上挂载设备 B,挂载将成功,但下一秒就会迅速卸载。这是 systemd 中的一个设计问题,我思考已在当前版本中修复,但该问题持续时间较长。

    也就是说,即使 mount 命令成功执行,它的效果仍有可能被立即撤销,而你正在看到的不是和你刚才做的一样。

所以我目前的猜测是:

  1. 您已将 /dev/loop0 (squashfs 映像?) 安装在 /mnt/usb 上。
  2. 然后,您手动将 /dev/sdb1 挂载到同一个 /mnt/usb 上。这只会堆叠在现有挂载上,而不会将其删除。
  3. 由于上述错误,Systemd 立即卸载 /mnt/usb。这将删除最顶层的挂载,并显示位于最底层的 /dev/loop0 的原始挂载。
  4. 您的df命令现在可以看到步骤 0 中的原始挂载。文件系统大小的差异没有意义,因为整个设备并不相同。

用于findmnt --poll验证这一点。让它在一个终端上运行(也可能journalctl -f在另一个终端上运行),然后重试 mount 命令。

相关内容