跳过正文
  1. 笔记/
  2. 系统底层/

Linux 存储栈:从物理硬盘、文件系统到系统启动

·5921 字·12 分钟· loading · loading · · ·
ICE345
作者
ICE345
CS Student | System | Linux | OCaml
目录
这篇文章是一张 Linux 存储地图。它不替代具体的分区、LVM、GRUB 或性能测试手册,而是把这些概念放回同一条链路中:设备如何被识别、空间如何被组织、文件系统如何被挂载,以及系统如何从磁盘启动

1. 先看完整的存储链
#

Linux 里一个“文件”从磁盘到用户空间,通常要经过下面这些层:

物理介质
块设备节点:/dev/sda、/dev/nvme0n1
分区表:GPT 或 MBR
分区:/dev/sda1、/dev/sda2、/dev/sda3
  ↓(可选)
加密层:LUKS / device-mapper
  ↓(可选)
LVM:PV → VG → LV
文件系统:ext4、Btrfs、XFS、FAT32……
挂载点:/、/boot、/home、/mnt/data
目录、文件、inode、权限和时间戳

这里最重要的不是记住缩写,而是知道每一层解决什么问题:

它负责什么常见工具
物理介质真的保存磁性或闪存数据smartctl
块设备让内核按块读写设备lsblkudevadm
分区表描述分区的起止位置和类型fdiskgdiskparted
LVM把多个空间组织成可调整的存储池pvsvgslvs
文件系统把块组织成文件和目录mountfsck
挂载把文件系统接入目录树findmntumount
启动链找到并运行内核和用户空间UEFI、GRUB、initramfs

LVM 不是文件系统。 ext4Btrfs 负责组织文件;LVM 负责提供一个可以承载文件系统的块设备。

2. 块设备:为什么 /dev/sda 不能总是直接挂载
#

Linux 把硬盘、分区、LVM 逻辑卷都表示成块设备。SATA 或 USB 硬盘常见的名字是:

/dev/sda       整块硬盘
/dev/sda1      第一个分区
/dev/sda2      第二个分区
/dev/sda3      第三个分区

NVMe 设备的命名方式不同:

/dev/nvme0n1       整块 NVMe 设备
/dev/nvme0n1p1     第一个分区
/dev/nvme0n1p7     第七个分区

最基本的盘点命令是:

lsblk -o NAME,PATH,SIZE,TYPE,FSTYPE,FSVER,LABEL,UUID,MOUNTPOINTS,RO,RM
sudo blkid
sudo fdisk -l

lsblk 展示的是设备层级,blkid 更关注设备上的文件系统或存储签名,fdisk -l 主要展示分区表。三者回答的问题不同。

例如:

/dev/sda       disk
├─/dev/sda1    part  vfat
├─/dev/sda2    part  ext4
├─/dev/sda3    part  LVM2_member
└─/dev/sda4    part  BIOS boot

/dev/sda 最外层保存的是 GPT 分区表,不是文件系统,所以直接执行:

sudo mount /dev/sda /mnt

通常会失败。只有包含文件系统的设备,例如 /dev/sda2,才可以直接挂载。/dev/sda3 如果显示为 LVM2_member,则还需要先通过 LVM 找到里面的逻辑卷。

3. GPT、MBR 与文件系统签名不是一回事
#

3.1 分区表做什么
#

分区表记录的是:

  • 每个分区的起始和结束扇区;
  • 分区类型 GUID 或类型代码;
  • 分区 UUID;
  • 分区名称和属性。

当前主流的两种分区表是:

MBR / DOS partition table
GPT / GUID Partition Table

MBR 的传统布局受主分区数量和地址范围限制;GPT 通常提供更大的地址空间、更多分区条目、首尾备份表以及 CRC 校验。

但要注意:

GPT 分区类型:Linux filesystem
分区内部签名:LVM2_member

两者并不冲突。前者描述分区在 GPT 中的角色,后者描述这个分区内部实际交给了什么存储层。

3.2 MBR 和 GPT 的启动关联
#

分区方案和固件启动模式是两个维度:

固件启动模式常见分区方案主要启动位置
Legacy BIOSMBRMBR 中的启动代码
UEFIGPTFAT32 的 EFI System Partition(ESP)
Legacy BIOSGPT通常需要 BIOS Boot Partition
UEFIMBR某些环境可用,但取决于固件和安装工具

现代 Linux 通常使用 UEFI + GPT,但不能把“GPT 等于 UEFI”当成定义。GPT 是磁盘布局,UEFI 是固件寻找并运行启动程序的方式。

3.3 ESP 和 BIOS Boot Partition
#

UEFI 通常需要一个 FAT32 的 ESP,里面保存 .efi 程序:

EFI/
├── BOOT/BOOTX64.EFI
├── ubuntu/shimx64.efi
└── Microsoft/Boot/bootmgfw.efi

如果使用 Legacy BIOS 从 GPT 磁盘启动,GRUB 通常需要一个不放文件系统的 BIOS Boot Partition,用来存放嵌入代码。它和 ESP 不是同一个东西:

ESP                  给 UEFI 读取,通常是 FAT32
BIOS Boot Partition  给 BIOS 模式 GRUB 使用,通常没有文件系统

4. 文件系统:块如何变成文件
#

没有文件系统时,磁盘只是一组可以编号的块。文件系统负责建立:

  • 文件和目录的名称关系;
  • inode 或类似的元数据结构;
  • 文件内容和空闲空间的管理;
  • 权限、所有者、时间戳;
  • 日志、校验和、快照或其他一致性机制。

4.1 ext4
#

ext4 是成熟的 Linux 文件系统,常见特性包括:

  • inode;
  • journal 日志;
  • extent 连续区间描述;
  • Unix 权限和所有权;
  • e2fsck 检查与修复工具。

如果根文件系统位于 LVM 逻辑卷上,典型链路是:

/dev/sda3
└─ LVM PV
   └─ ubuntu-vg
      └─ ubuntu-lv
         └─ ext4
            └─ /

4.2 Btrfs
#

Btrfs 是 Linux 中更现代的 Copy-on-Write 文件系统。它提供:

  • 子卷;
  • 快照;
  • 数据和元数据校验和;
  • 多设备管理;
  • 压缩;
  • scrub;
  • 在线扩缩容。

Btrfs 自身已经提供了不少卷管理能力,因此是否再套一层 LVM 要根据加密、部署和运维需求决定。

4.3 FAT32
#

FAT32 兼容性很好,因此 ESP 通常使用它。它没有 ext4 那样的 inode 和 journal,也不负责保存 Unix 权限。

FAT 文件系统内部还有自己的 boot sector 和 backup boot sector。它们与 GPT 的分区表、MBR 的启动代码、GRUB 的文件并不是同一个概念。

5. LVM:PV、VG、LV
#

传统分区直接承载文件系统:

分区 → ext4

LVM 在中间增加了可管理的空间层:

分区 → PV → VG → LV → ext4

5.1 PV:Physical Volume
#

PV 是交给 LVM 管理的物理空间,可以是一个分区、整块磁盘或其他块设备:

sudo pvcreate /dev/sda3
sudo pvs
sudo pvdisplay

“物理卷”不意味着它一定是一整块物理硬盘。

5.2 VG:Volume Group
#

VG 是由一个或多个 PV 组成的空间池:

sudo vgcreate ubuntu-vg /dev/sda3
sudo vgs
sudo vgdisplay

如果 VG 显示还有 free space,那只是还没有分配给 LV,不代表硬盘损坏或容量丢失。

5.3 LV:Logical Volume
#

LV 是从 VG 中切出的逻辑块设备。对文件系统来说,它和普通分区很相似:

sudo lvcreate -n data -L 100G ubuntu-vg
sudo lvs
sudo lvdisplay

同一个 LV 通常可以通过两种路径访问:

/dev/ubuntu-vg/ubuntu-lv
/dev/mapper/ubuntu--vg-ubuntu--lv

/dev/mapper 中的双连字符是名称转义规则:原名中的一个 - 会表示成两个 -

5.4 LVM 的 extent
#

LVM 不按任意字节分配空间,而是按 extent 管理:

Physical Extent(PE)
Logical Extent(LE)

创建、扩展或移动 LV,本质上是在重新分配这些小块。LVM 提供了灵活性,但也增加了救援时需要理解的层次。

5.5 激活和停用 VG
#

在救援环境中,PV 可能已经被识别,但 LV 还没有出现:

sudo vgscan
sudo vgchange -ay ubuntu-vg
lsblk

-a 表示 activation,-y 表示激活。停用时:

sudo umount /mnt
sudo vgchange -an ubuntu-vg

在把整块磁盘交给 QEMU 或其他系统之前,必须确认宿主机没有挂载其中的文件系统,也不要让两个操作系统同时写同一个文件系统。

6. 挂载、UUID 和 /etc/fstab
#

Linux 只有一棵目录树,没有 Windows 那种固定的 C:D: 盘符。挂载就是把某个文件系统接到这棵树上:

sudo mkdir -p /mnt/data
sudo mount /dev/ubuntu-vg/data /mnt/data
findmnt /mnt/data
sudo umount /mnt/data

之后访问 /mnt/data/file.txt,就是在访问那个文件系统中的文件。

设备名可能因插拔顺序变化:

/dev/sda2  可能变成 /dev/sdb2

因此系统通常使用 UUID 写入 /etc/fstab

UUID=ca53b6c9-3366-4bbd-a909-d10b89ed7a18  /boot  ext4  defaults  0  2

查看 UUID:

lsblk -f
sudo blkid

修改 fstab 后,不要直接重启验证,先执行:

sudo findmnt --verify
sudo mount -a

这样可以尽早发现路径、UUID、文件系统类型或选项写错的问题。

7. 一套安全的磁盘排障流程
#

排障时应从低风险、只读的信息开始,不要一上来运行格式化或修复命令。

第一步:识别设备和挂载状态
#

lsblk -e7 -o NAME,PATH,SIZE,TYPE,FSTYPE,FSVER,LABEL,UUID,MOUNTPOINTS,RO,RM
sudo blkid
findmnt

要回答:

  • 设备是否被内核识别;
  • 是整盘、分区还是 LVM;
  • 文件系统签名是什么;
  • 是否已经挂载;
  • 是否被标记为只读或可移除。

第二步:检查分区表
#

sudo fdisk -l /dev/sda
sudo gdisk -l /dev/sda

重点看分区边界、分区类型、GPT 是否有校验错误。不要把 Linux filesystem 分区类型直接当成“里面一定是 ext4”。

第三步:检查 LVM 层
#

sudo pvs
sudo vgs
sudo lvs -a -o +devices

如果只能看到 PV,看不到 LV,再考虑扫描和激活:

sudo vgscan
sudo vgchange -ay

第四步:在未挂载状态检查文件系统
#

ext4:

sudo e2fsck -f -n /dev/ubuntu-vg/ubuntu-lv

其中 -n 表示不写入修复,适合初步诊断。e2fsck 的五个阶段大致检查 inode、目录结构、目录连通性、引用计数和块组摘要。

FAT32:

sudo fsck.fat -n /dev/sda1

Dirty bit is set 通常表示上次没有正常卸载,可能来自断电、崩溃或直接拔盘,不等于硬盘出现坏道。使用 -n 时,工具可能会报告“可以清除”,但不会真正修改设备。

Btrfs:

sudo btrfs filesystem show
sudo btrfs filesystem usage /mountpoint
sudo btrfs scrub start -Bd /mountpoint

不要在没有理解后果的情况下对已挂载文件系统执行破坏性检查或修复。文件系统检查命令必须先确认目标没有被正常系统使用。

第五步:检查硬盘健康
#

sudo smartctl -x /dev/sda
sudo smartctl -t short /dev/sda
sudo smartctl -l selftest /dev/sda

如果要执行长测试:

sudo smartctl -t long /dev/sda

先备份,再测试。SMART 是风险提示工具,不是“明天一定不会坏”的保证书。

第六步:检查启动状态
#

test -d /sys/firmware/efi && echo UEFI || echo Legacy-BIOS
cat /proc/cmdline
ls -l /boot
sudo efibootmgr -v
journalctl -b -p warning

这些命令分别帮助确认当前固件模式、内核命令行、内核和 initramfs 是否存在、UEFI 启动项以及本次启动的警告。

8. fsck 输出应该怎样理解
#

以 ext4 为例,下面这些信息经常让初学者误以为磁盘马上坏了:

Inode ... extent tree could be shorter.

它通常表示 extent 索引可以更紧凑,是优化提示,不等于文件内容损坏。

Warning: skipping journal recovery because doing a read-only filesystem check.

这是因为 -n 禁止写入,所以工具不会回放 journal,也不代表 journal 损坏。

1.4% non-contiguous

这是文件碎片或非连续分配信息,不是错误代码。是否需要处理要结合文件系统、工作负载和实际性能,而不是看到百分比就运行整理工具。

inode 使用量和磁盘空间是两种不同的限制:磁盘仍有空间时,inode 也可能先耗尽,尤其是在保存大量小文件的场景。

9. SMART、性能测试和备份是三件事
#

不要把下面三个问题混在一起:

SMART       硬盘有没有健康风险
benchmark   硬盘在某种负载下有多快
backup      数据损坏后能否恢复

SMART 中常见的重点属性:

属性关注点
Reallocated_Sector_Ct已经被替换的坏扇区数量
Current_Pending_Sector当前无法稳定读取、等待进一步确认的扇区
Offline_Uncorrectable离线检查中无法纠正的扇区
UDMA_CRC_Error_CountSATA 或 USB 链路传输错误
Power_On_Hours累计通电时间
Load_Cycle_Count磁头装载和停泊次数

UDMA_CRC_Error_Count 更偏向线材、接口、转接器或供电问题,不应直接当成盘片坏道。判断 SMART 要看当前值、历史最差值、阈值、RAW_VALUE 和变化趋势。

机械硬盘还要关注温度、启停次数和磁头停泊次数。SMART 显示 PASSED 只代表属性没有跨过厂商阈值,并不意味着所有突然故障都能被预测。

10. 存储性能:吞吐、延迟、IOPS 和缓存
#

10.1 Throughput
#

Throughput(吞吐量)通常用 MB/s 或 MiB/s 表示,适合描述连续读取大文件、视频流或备份任务。

注意单位:

MB = 10^6 bytes
MiB = 2^20 bytes
Gbps = gigabits per second
GB/s = gigabytes per second

GbpsGB/s 不仅大小写不同,单位含义也不同,换算时还要除以 8。

10.2 Latency
#

Latency(延迟)是一次请求从发出到完成需要等待多久。机械硬盘的寻道和旋转等待会让随机小块访问的延迟远高于 SSD。

10.3 IOPS
#

IOPS(每秒 I/O 次数)适合描述大量小块请求。4 KiB random I/O 的 IOPS 和延迟,往往比一个顺序读写的 MB/s 更能解释系统为什么“打开很多小文件很慢”。

10.4 Cache
#

缓存可能来自操作系统 page cache、SSD 的 SLC/MLC 写缓存、硬盘缓存或 USB 转接器。一次短测试跑出很高的数字,不一定代表长时间持续写入也能保持这个速度。

fio 是适合建模不同负载的工具。你可以阅读仓库中的 How fast are your disks? 了解 fio、4 KiB random、并发、队列深度和结果解释。

安全的原则是:对测试文件做测试,不要把测试写入未知的原始设备。例如在确认目标目录有足够空间后:

mkdir -p /tmp/fio-test
cd /tmp/fio-test
fio --name=read-test \
  --filename=./fio-testfile \
  --size=1G \
  --rw=randread \
  --bs=4k \
  --iodepth=1 \
  --numjobs=1 \
  --runtime=30 \
  --time_based \
  --direct=1

这个例子仍然会消耗目标文件系统的空间和 I/O 资源。真正测试前要根据目标介质、文件系统和数据安全要求调整参数。

11. 启动链:从固件到 systemd
#

一次典型 Linux 启动可以抽象为:

主板上电
CPU 复位并执行固件
BIOS 或 UEFI 选择启动项
GRUB 或其他 bootloader
Linux kernel + initramfs
识别设备、解密、激活 LVM、挂载根文件系统
切换到真正的根目录
systemd 和其他用户空间服务

11.1 UEFI 路径
#

UEFI
→ ESP 中的 .efi 程序
→ shim 或 GRUB
→ kernel 和 initramfs
→ 根文件系统

11.2 Legacy BIOS 路径
#

BIOS
→ 磁盘第一个扇区的启动代码
→ GRUB 的嵌入代码或 core.img
→ /boot/grub 中的模块和配置
→ kernel 和 initramfs

GRUB 教程中的 Stage 1、Stage 1.5、Stage 2 是有帮助的历史解释,但不要把它们理解成所有 GRUB 2 安装都存在的三个固定文件。UEFI 模式下的 GRUB 通常直接作为 EFI 程序加载。

11.3 initramfs 为什么需要 LVM 工具
#

如果根目录位于:

/dev/sda3 → PV → ubuntu-vg → ubuntu-lv → ext4 → /

内核刚启动时还没有完整的用户空间,因此 initramfs 必须包含磁盘驱动、udev、LVM 工具和文件系统模块,完成:

发现硬盘
→ 扫描 PV
→ 激活 VG
→ 找到 LV
→ 挂载真正的 /

完成后,系统才会交给真正根文件系统里的 systemd。

12. 用 QEMU 读取真实系统盘排障
#

当旧电脑的屏幕、内存或主板出现问题时,可以把硬盘接到另一台 Linux 机器上,用 QEMU 做“系统盘能否启动”的隔离实验。

典型命令类似:

qemu-system-x86_64 \
  -name disk-inspection \
  -machine pc \
  -accel kvm \
  -cpu host \
  -m 2048 \
  -smp 2 \
  -drive file=/dev/sda,format=raw,if=ide \
  -snapshot \
  -boot menu=on \
  -vga std \
  -nic none \
  -display gtk \
  -no-reboot

关键参数:

  • file=/dev/sda:把整块真实硬盘作为客户机磁盘;
  • format=raw:说明没有 qcow2 容器;
  • -snapshot:客户机写入临时覆盖层,不写回真实盘;
  • -nic none:测试时不自动联网;
  • -accel kvm:使用硬件虚拟化加速客户机 CPU。

这不是“把硬盘复制到虚拟机”,而是让 QEMU 读取原盘上的 GPT、GRUB、/boot、内核、initramfs、LVM 和根文件系统。

12.1 访问权限和图形界面
#

不要为了访问 /dev/sda 直接使用 sudo qemu-system-x86_64 -display gtk。这样 QEMU 进程变成 root,反而可能因为 Wayland/X11 图形会话权限而启动失败。

更合理的思路是:

  1. 确认宿主机没有挂载原盘中的文件系统;
  2. 让普通用户临时获得设备读取权限,或使用合适的设备组和 udev 规则;
  3. 用普通用户运行 QEMU;
  4. 优先使用 -snapshot,并禁止网络。

ACL 直接加在 /dev/sda 上通常不会跨越拔盘重插永久保存,因为设备节点是由 udev 动态创建的。

12.2 QEMU 能证明什么
#

如果 QEMU 成功进入原系统,通常可以证明:

  • GPT 或 MBR 可以被读取;
  • GRUB 可以运行;
  • /boot、内核和 initramfs 可以读取;
  • LVM 可以被扫描和激活;
  • 根文件系统可以挂载;
  • systemd 和用户空间能够启动。

但这不能证明原电脑的 LCD、屏幕排线、内存插槽、主板显示输出和供电都正常。比如原电脑白屏,而原盘在 QEMU 中能启动,排查重点就应转向显示链路和硬件,而不是继续反复修复系统盘。

13. 一张可复用的排障清单
#

1. lsblk / blkid:设备是否被识别?
2. fdisk / gdisk:分区表和分区边界是否合理?
3. pvs / vgs / lvs:LVM 层是否完整?
4. findmnt / fstab:文件系统实际挂载到哪里?
5. fsck:在未挂载状态检查文件系统一致性
6. smartctl:检查硬盘健康迹象和错误趋势
7. fio:只对测试文件进行受控性能测试
8. efibootmgr / journalctl:检查启动模式和启动错误
9. QEMU:隔离“系统盘启动问题”和“原机器硬件问题”
10. 备份:任何修复或长测试前,先保护重要数据

这套顺序体现的是分层排除法:先确认设备存在,再确认结构,再确认文件系统,再确认硬盘健康,最后确认启动链和外部硬件。不要因为 SMART PASSED 就跳过备份,也不要因为一次 fsck 警告就直接格式化磁盘。

14. 最后总结每一层
#

/dev/sda        整块硬盘
GPT / MBR       分区布局
/dev/sda3       一个分区
PV              交给 LVM 的物理空间
VG              LVM 的空间池
LV              从空间池切出的逻辑块设备
ext4 / Btrfs    组织文件和目录的文件系统
mount           把文件系统接入 Linux 目录树
UUID / fstab    稳定识别并自动挂载
fsck            检查文件系统的一致性
SMART           观察硬盘内部健康迹象
fio             按工作负载测试性能
GRUB            选择并加载启动程序或内核
initramfs       启动早期激活 LVM 并挂载根目录
QEMU            用虚拟硬件隔离测试真实系统盘
KVM             加速虚拟 CPU

如果只记住一句话,可以记住:

分区表决定“空间怎么切”,LVM 决定“块设备怎么组合”,文件系统决定“文件怎么组织”,挂载决定“目录树怎么接入”,启动链决定“系统怎么把这些层逐个接起来”。

相关专题:

相关文章


评论