kpartx作用和partprobe区别

在 Linux 中,kpartx 是一个用于处理设备映射(device-mapper)的工具,尤其在需要通知内核重新识别分区表时非常有用。它主要用于映射分区到设备文件(例如 /dev/mapper/),常用于处理多路径设备、LVM、或直接操作磁盘镜像。与 partprobe 类似,kpartx 可以帮助内核感知分区表的更改,但它的功能和使用场景有所不同。


1. kpartx 的作用

kpartxmultipath-tools 包的一部分,主要功能是:

  • 从块设备(如 /dev/sda)或磁盘镜像文件中读取分区表。
  • 将分区映射到 /dev/mapper/ 目录下的设备节点。
  • 通知内核更新分区信息,无需重启系统。

相比 partprobekpartx 更适合处理复杂场景,例如:

  • 操作磁盘镜像文件(.img 文件)。
  • 处理 LVM、分区表嵌套或多路径设备。

当你使用 fdisk 修改分区表并保存后,内核可能不会立即识别新分区,kpartx 可以强制更新映射。


2. 使用 kpartx 的步骤

假设你已经用 fdisk 修改了 /dev/sda 的分区表,以下是使用 kpartx 通知内核的步骤:

前提条件

  • 确保安装了 kpartx
    1
    2
    sudo apt install multipath-tools  # Debian/Ubuntu
    sudo yum install device-mapper-multipath # CentOS/RHEL
[root@vgt-rocky9-60 ~]# kpartx
multipath-tools v0.8.7 (09/08, 2021)
Usage:
  kpartx [-a|-d|-u|-l] [-r] [-p] [-f] [-g] [-s|-n] [-v] wholedisk
    -a add partition devmappings
    -r devmappings will be readonly
    -d del partition devmappings
    -u update partition devmappings
    -l list partitions devmappings that would be added by -a
    -p set device name-partition number delimiter
    -g force GUID partition table (GPT)
    -f force devmap create
    -v verbose
    -n nosync mode. Return before the partitions are created
    -s sync mode (Default). Don't return until the partitions are created

查看磁盘分区信息

[root@vgt-rocky9-60 ~]# kpartx -l /
invalid device: /
[root@vgt-rocky9-60 ~]# kpartx -l /dev/sda
sda1 : 0 204800 /dev/sda 2048
sda2 : 0 2048000 /dev/sda 206848
sda3 : 0 8192 /dev/sda 2254848
sda4 : 0 2048 /dev/sda 2263040
sda5 : 0 102592479 /dev/sda 2265088

[root@vgt-rocky9-60 ~]# blkid
/dev/sda4: PARTUUID="2b7cfd28-bc7a-4d99-a502-709208f92df6"
/dev/sda2: LABEL="boot" UUID="3b416790-bfac-46da-bf20-fc31ccfcd5b7" TYPE="xfs" PARTUUID="1d80fc5b-ea5c-4f00-b194-a8498d8c84d8"
/dev/sda5: UUID="c89ff149-cdfc-4ddf-8108-c73942ac9c62" TYPE="xfs" PARTUUID="6441f2b8-0d8d-0644-869d-32d8074539be"
/dev/sda3: PARTUUID="b79be209-06e9-455f-a040-2552930778a5"
/dev/sda1: SEC_TYPE="msdos" UUID="35D1-4A7F" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="66fe1d43-2adf-44f0-9219-0c666d0a3a55"

[root@vgt-rocky9-60 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda      8:0    0   50G  0 disk 
├─sda1   8:1    0  100M  0 part /boot/efi
├─sda2   8:2    0 1000M  0 part /boot
├─sda3   8:3    0    4M  0 part 
├─sda4   8:4    0    1M  0 part 
└─sda5   8:5    0 48.9G  0 part /

操作步骤

  1. 检查当前分区状态

    1
    lsblk

    如果修改了分区表但 lsblk 未显示新分区,说明内核尚未更新。

  2. 使用 kpartx 更新分区映射

    1
    sudo kpartx -a /dev/sda
    • -a:添加分区映射,将分区表中的分区映射到 /dev/mapper/
    • /dev/sda:目标块设备。
  3. 验证映射结果

    1
    ls /dev/mapper/

    你可能会看到类似 /dev/mapper/sda1/dev/mapper/sda2 等设备节点,表示分区已成功映射。

  4. 同步内核分区表(可选)
    如果需要进一步确认,可以结合 partprobe

    1
    sudo partprobe /dev/sda
  5. 检查更新后的分区

    1
    lsblk

    新分区应该已经出现在列表中。

删除映射(清理)

如果不再需要分区映射,可以移除:

1
sudo kpartx -d /dev/sda
  • -d:删除分区映射。

3. 与根分区的关系

如果修改的是根分区所在磁盘(如 /dev/sda),需要格外小心:

  • 根分区正在使用:内核可能拒绝直接更新根分区映射,因为它当前被挂载。
  • 解决方法
    • 单用户模式或救援模式下操作。
    • 如果是扩展根分区,修改分区表后可能需要重启系统以完全应用更改。
    • 如果不重启,可以尝试重新挂载根文件系统(需确保新分区包含原有数据)。

例如:

1
sudo mount -o remount /

4. kpartx 和 partprobe 的区别

  • **partprobe**:

    • 直接通知内核重新读取分区表,适用于物理磁盘。
    • 不创建额外的设备映射。
    • 简单直接,但不支持磁盘镜像文件。
  • **kpartx**:

    • 创建 /dev/mapper/ 下的设备节点,适合复杂设备或镜像文件。
    • 更灵活,但操作稍复杂。
    • 需要手动管理映射。

如果目标是普通物理磁盘,partprobe 通常足够;如果涉及镜像文件或嵌套分区,kpartx 是更好的选择。


5. 示例:处理磁盘镜像

假设有一个磁盘镜像文件 disk.img,你用 fdisk 修改了其中的分区表:

  1. 挂载镜像:
    1
    sudo losetup /dev/loop0 disk.img
  2. 更新分区映射:
    1
    sudo kpartx -a /dev/loop0
  3. 检查映射:
    1
    ls /dev/mapper/loop0p*
    输出可能为 /dev/mapper/loop0p1 等。
  4. 使用完成后清理:
    1
    2
    sudo kpartx -d /dev/loop0
    sudo losetup -d /dev/loop0

6. 注意事项

  • 权限:需要 root 或 sudo 权限运行 kpartx
  • 正在使用的分区:如果分区已被挂载,直接更新映射可能失败,需先卸载(umount)。
  • 重启风险:如果分区表配置错误(例如删除了根分区的起始扇区),系统重启后可能无法启动,建议提前备份。
  • 日志检查:如果遇到问题,查看 dmesg/var/log/kern.log 获取错误信息。

总结

kpartx 通过创建设备映射并通知内核更新分区表,能够在不重启的情况下让系统识别新分区。针对根分区,操作时需确保数据一致性(例如保持起始扇区不变),并根据情况选择重启或重新挂载。对于物理磁盘,kpartx -a /dev/sdX 是通知内核的有效方法;对于镜像文件,它更是不可或缺的工具。