尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

kpartx实战:轻松挂载磁盘镜像中的分区表

kpartx实战:轻松挂载磁盘镜像中的分区表 1. 为什么会有 kpartx分区表、设备映射器与 loop 设备的三角关系1.1 拿到一个磁盘镜像第一时间却 mount 不上问题出在哪做运维的兄弟应该都有过这种经历从测试环境拷回来一个 dd 出来的整盘镜像或者从网上下了一个树莓派系统镜像兴冲冲地执行mount -o loop image.img /mnt结果系统给你一句 mount: /mnt: wrong fs type, bad option, bad superblock on /dev/loop0。这时候大多数人第一反应是镜像坏了其实多半不是。问题出在文件系统和分区表是两码事。mount -o loop只能把一个没有分区表的原始文件系统镜像挂载上来比如mkfs.ext4直接格式化出来的裸文件系统。但真实磁盘的镜像不一样它开头有 MBR 或 GPT 分区表数据全部分区里。你用 loop 方式挂载等于把一个整块磁盘当成文件系统去读内核当然不认。这正是 kpartx 存在的理由。它读取磁盘镜像或块设备上的分区表然后通过内核的 device mapper 机制为每个分区生成一个独立可访问的设备节点。有了这些节点分区才能被正常挂载、检查和修改。换句话说mount -o loop是直接开卷读取kpartx 是先把磁盘拆成一个个分区再让你读。1.2 设备映射器机制kpartx 的核心工作原理要理解 kpartx 的工作方式得先聊一聊 Linux 内核里的 device mapper设备映射器。这个机制可以理解成在物理块设备和用户之间加了一层虚拟化调度层它允许你定义虚拟块设备和底层真实存储之间的映射关系。kpartx 做的事情很简单把磁盘镜像挂成 loop 设备比如/dev/loop0然后解析这个设备的 MBR 或 GPT 分区表。假设分区表里有两个分区第一个分区从扇区 2048 开始长度 100MBkpartx 就会生成一个映射关系创建一个名为/dev/mapper/loop0p1的虚拟设备这个设备在逻辑上只对应底层/dev/loop0上那 100MB 的区域。对外表现就是一个独立的分区设备和一块真实的/dev/sda1没有任何使用上的区别。这种设计非常优雅。它不需要修改原始镜像文件只是建立映射关系删除映射后原始文件原封不动。同时 device mapper 是内核标准组件LVM、dm-crypt 加密、软 RAID 全都跑在它上面稳定性和性能都有保障。1.3 kpartx 和 fdisk、parted、losetup 的区别很多新手会把 kpartx 和 fdisk、losetup 混在一起其实它们定位完全不同工具作用是否创建可用块设备fdisk / parted查看和编辑分区表否losetup把镜像文件挂载为 loop 设备是但只能得到整块设备kpartx根据分区表为每个分区创建映射设备是得到的是分区设备partprobe通知内核重新读取分区表否只是触发内核更新实际使用中它们经常配合出现。losetup 把文件变成块设备kpartx 把块设备拆成分区fdisk 则负责查看分区布局是否正常。搞清了三角关系后面所有操作就顺理成章了。2. 安装与准备各发行版差异和最容易漏掉的内核支持2.1 各发行版的安装命令kpartx 在主流发行版软件源里都有安装没什么难度但包名和依赖关系需要注意。Debian / Ubuntu 系比较直接sudo apt update sudo apt install kpartxRHEL / CentOS 7 时代稍麻烦一点kpartx 可能是单独包也可能被打进multipath-tools里sudo yum install kpartx # CentOS 7 / RHEL 7 sudo dnf install kpartx # Fedora / CentOS Stream / RHEL 8Arch Linux 用户执行sudo pacman -S multipath-tools因为 Kpartx 是作为 multipath-tools 的子组件发布的。装完之后先验证一下版本和环境是否正常kpartx -v如果提示找不到命令大概率是软件源没更新或者系统架构不匹配。如果提示/dev/mapper目录不存在先手动创建并加载内核模块sudo mkdir -p /dev/mapper sudo modprobe dm_mod2.2 内核设备映射器支持检查这一步是绝大多数教程忽略的。kpartx 依赖 device mapper内核里必须有dm_mod模块有些精简内核、容器宿主机或定制内核镜像会把它编译成模块但不自动加载。检查方法ls /sys/module/dm_mod如果不输出任何内容说明模块没加载手动加载后重新验证sudo modprobe dm_mod ls /sys/module/dm_mod还可以用dmsetup version查看 device mapper 用户空间工具是否可用dmsetup version正常情况下会输出类似Library version: 1.02.xxx和Driver version: 4.x.x的字样。如果这里报错说明 LVM 基础组件有问题kpartx 就算装上也没法工作。2.3 需要特别注意的版本差异kpartx 在不同发行版里的行为略有差异主要体现在输出格式和设备命名上。Ubuntu 20.04 之后的版本如果分区表是 GPTkpartx 默认会正确识别并命名。老版本对 GPT 支持有些问题遇到 partition table invalid 之类的报错优先考虑升级 kpartx 而不是怀疑镜像。另外kpartx 在 RHEL/CentOS 系是从multipath-tools分离出来的命令行为基本一致但某些参数比如-g只在较新版本里才有。跨发行版使用时先用man kpartx确认一下参数列表更稳妥。3. 命令行全景从 -l 到 -d 的每一个参数3.1 最常用的三个操作-l、-a、-dkpartx 参数不多最核心的就三个列出、添加、删除。列出分区映射-lsudo kpartx -l disk.img这个参数不会真正创建映射只是读取分区表并打印将要生成的映射关系。输出结果类似loop0p1 : 0 2097152 /dev/loop0 2048 loop0p2 : 0 40894464 /dev/loop0 2099200每行第一部分是映射名称后面是扇区数和设备路径。执行-l是安全的不会改动任何状态所以排查问题第一步永远是用它确认分区表是不是被正确识别。添加映射-asudo kpartx -a disk.img真正创建映射生成/dev/mapper/loop0p1、/dev/mapper/loop0p2。注意这里 kpartx 会自己寻找空闲的 loop 设备并挂载镜像。如果你想明确指定用哪个 loop 设备可以配合-n参数或先用losetup手工建立关联。删除映射-dsudo kpartx -d disk.img删除所有与这个镜像关联的分区映射。前提是这个映射没有被使用否则会报 device is busy。删除后 loop 设备如果确认没有其他作用可以再用losetup -d释放。3.2 会话相关参数-n、-p、-f、-v细看 kpartx 的 man 手册会看到几个容易被忽略的参数用好了效率翻倍。-p参数可以自定义分区设备名前缀。默认命名规则是loop0p1也就是 loop 设备名加一个小写 p 再加分区号。在部分老版本里可能生成loop0-part1之类的风格如果脚本里写死了设备名就需要用-p统一sudo kpartx -a -p -part disk.img执行后设备名会变成/dev/mapper/loop0-part1。-n参数指定要使用的 loop 设备号。常见场景是脚本里已经用 losetup 手工挂载好了/dev/loop3此时sudo kpartx -a -n 3 disk.imgkpartx 就不会再去找空闲 loop 设备直接使用/dev/loop3解析分区。-f参数用在删除时强制清理。有时候 udev 或者进程占用导致kpartx -d删不掉加-f强制删除sudo kpartx -d -f disk.img-v打开 verbose 模式执行时输出详细信息排错时建议加上。3.3 组合参数的实际用法实际工作中很少单独用一个参数我常用的组合是sudo kpartx -av disk.img-a -v组合会在创建映射同时打印每个分区的映射表一眼就能看出哪些分区被识别了。删除时用-dv配合。注意-l一般不和其他操作参数混用它只是只读预览。还有个冷门的-g参数只打印映射名称不创建设备适合脚本提取分区名。比如想拿到第二分区的设备名用于后续格式化part2$(sudo kpartx -g disk.img | sed -n 2p | awk {print $1})不过这个参数不同版本行为差异较大遇到就多试几次结合-l的输出来调整 sed/awk 逻辑。4. 实战一挂载含分区表的磁盘镜像文件最典型的场景4.1 创建 loop 设备并映射分区现在进入正题。假设有一个sdcard.img是某嵌入式设备的整卡备份里面有两个分区一个 FAT 一个 ext4。直接 mount 肯定失败完整的正确流程是sudo losetup -f先看哪个 loop 设备空闲。losetup -f会输出一个空闲的 loop 设备名比如/dev/loop0。然后把它和镜像关联sudo losetup /dev/loop0 sdcard.img sudo kpartx -av /dev/loop0注意这里 kpartx 参数不再是镜像文件名而是 loop 设备路径。执行后输出add map loop0p1 (252:0): 0 204800 /dev/loop0 2048 add map loop0p2 (252:1): 0 1024000 /dev/loop0 206848到这一步/dev/mapper/loop0p1和/dev/mapper/loop0p2就已经可用了。为什么不直接kpartx -a sdcard.img虽然它也能工作但 kpartx 自动寻找 loop 设备之后你并不知道它用了哪个后续删除和核对不好对应。手工关联 loop 设备后路径全程可控排查更清晰。个人习惯是主流程全部手控。4.2 挂载分区、读取数据与安全卸载映射创建后分区设备就能当作普通块设备操作了sudo mkdir -p /media/img_p1 sudo mount /dev/mapper/loop0p1 /media/img_p1如果分区是 FATmount 时需要指定文件系统类型sudo mount -t vfat /dev/mapper/loop0p1 /media/img_p1ext4 分区一般自动识别不需要额外参数。挂载之后正常读写文件即可。操作完成卸载的顺序很重要一定先 umount 分区再删除映射再释放 loop 设备sudo umount /media/img_p1 sudo umount /media/img_p2 sudo kpartx -d /dev/loop0 sudo losetup -d /dev/loop0这个顺序颠倒的话会频繁遇到 target is busy。尤其是umount之后工作目录必须离开挂载点否则 shell 的当前目录占用也会导致卸载失败。4.3 一个完整的修改分区内容并验证的示例以修改树莓派镜像里的cmdline.txt为例完整走一遍# 1. 关联镜像到 loop 设备 sudo losetup /dev/loop0 raspi.img # 2. 创建分区映射 sudo kpartx -av /dev/loop0 # 3. 查看映射列表确认分区 ls -l /dev/mapper/loop0p* # 4. 挂载 boot 分区FAT32 sudo mkdir -p /mnt/raspi_boot sudo mount -t vfat /dev/mapper/loop0p1 /mnt/raspi_boot # 5. 修改参数在 cmdline.txt 末尾加一个串口参数对应树莓派 UART 调试 sudo sed -i s/$/ consolettyAMA0,115200/ /mnt/raspi_boot/cmdline.txt # 6. 同步并卸载 sync sudo umount /mnt/raspi_boot # 7. 清理映射和 loop 设备 sudo kpartx -d /dev/loop0 sudo losetup -d /dev/loop0 # 8. 验证镜像文件有没有被写入 sudo fdisk -l raspi.img验证镜像文件尺寸有没有变化时注意默认 kpartx 创建映射后对分区写入是直接写回底层文件对应的偏移位置所以镜像文件大小不会变但内容已经变了。这对后续直接 dd 到 SD 卡使用至关重要。4.4 封装一个可直接复用的挂载-卸载脚本实际操作中这套流程每次都要敲五六条命令我习惯封装成两个极简脚本。挂载脚本#!/bin/bash # usage: img-mount.sh image_file set -e IMG$1 LOOP$(sudo losetup -f) sudo losetup $LOOP $IMG sudo kpartx -a $LOOP ls -l /dev/mapper/$(basename $LOOP)p* echo Mapped devices under /dev/mapper: ls /dev/mapper/$(basename $LOOP)p*卸载脚本#!/bin/bash # usage: img-umount.sh loop_device set -e LOOP$1 # 先找到所有挂载在这个 loop 分区映射上的目录 MOUNTS$(mount | grep $LOOP | awk {print $1}) for m in $MOUNTS; do echo Unmounting $m sudo umount $m done sudo kpartx -d $LOOP sudo losetup -d $LOOP一套流程从两条命令变成各一条命令磁盘镜像排错效率能提升不少。脚本里用了set -e任何一步失败立即退出避免在错误状态下继续执行。5. 实战二虚拟机磁盘、树莓派镜像和其他特殊镜像的处理5.1 KVM/QEMU 的 qcow2 镜像qcow2 格式的磁盘镜像是虚拟化环境最常见的存储格式之一。kpartx 不能直接读取 qcow2因为它是 QEMU 的私有格式需要先把 qcow2 暴露成块设备。推荐用qemu-nbd工具挂载这是 QEMU 自带的 Network Block Device 客户端sudo modprobe nbd max_part8 sudo qemu-nbd -c /dev/nbd0 /var/lib/libvirt/images/vm01.qcow2 sudo partprobe /dev/nbd0 ls /dev/nbd0p*如果内核配置了 nbd 的 max_part 并执行了 partprobe通常会自动生成/dev/nbd0p1等分区设备不需要 kpartx 出场。但有些精简内核不会自动生成分区设备此时 kpartx 就该上了sudo kpartx -av /dev/nbd0这样就会生成/dev/mapper/nbd0p1等设备。这种场景下 qemu-nbd 和 kpartx 是互补关系qemu-nbd 解决格式转换kpartx 解决分区表解析。停止使用时的顺序是sudo kpartx -d /dev/nbd0 sudo qemu-nbd -d /dev/nbd0注意不能用 kpartx 替代 qemu-nbd 的断开操作否则内核会残留一个半挂状态的 nbd 设备。5.2 树莓派等 ARM 开发板镜像的双分区处理树莓派官方镜像的分区结构几乎是模板第一个分区是 FAT32 的 boot 分区存放固件和内核第二个分区是 ext4 的 root 分区。kpartx 对这种结构处理得非常好。完整流程# 1. 关联镜像 sudo losetup /dev/loop0 raspios.img # 2. 创建映射 sudo kpartx -av /dev/loop0 # 3. 挂载 boot 分区 sudo mkdir -p /mnt/rpi_boot sudo mount -t vfat /dev/mapper/loop0p1 /mnt/rpi_boot # 4. 挂载 root 分区 sudo mkdir -p /mnt/rpi_root sudo mount -t ext4 /dev/mapper/loop0p2 /mnt/rpi_root # 5. 查看 root 分区是否有完整系统 ls /mnt/rpi_root/home ls /mnt/rpi_root/etc很多人在第 5 步发现 root 分区里没有/etc只有一个lostfound这不一定是镜像问题而是系统为了挂载使用把 root 文件系统当成空分区了。需要先用fsck检查文件系统是否有异常sudo e2fsck -f /dev/mapper/loop0p2如果显示 Filesystem has unsupported feature(s)说明镜像里的 ext4 文件系统使用了宿主系统内核不支持的 feature。这常见于新版本树莓派系统的 ext4 元数据校验和特性开启但宿主系统内核较老的情况。解决思路是升级宿主系统内核而不是强行挂载。5.3 raw 格式 dd 备份的系统盘处理dd备份的 raw 格式镜像是最常见的情况因为它本身就是一块完整磁盘的扇区级拷贝kpartx 处理起来毫无压力。不过 dd 镜像有个特点即使原盘只有 5GB 数据备份文件也可能是 32GB 的完整磁盘大小。大量空白扇区白白占地方。处理这种镜像前最好先用qemu-img瘦身qemu-img convert -O raw disk.img disk_small.img或者直接转换成 qcow2 减少空间占用qemu-img convert -O qcow2 disk.img disk_small.qcow2转换完再按常规流程挂载。如果原始镜像太大kpartx 的-a阶段会花不少时间读分区表但通常几十秒内能完成。读取期间不要按 CtrlC 中断否则可能产生一个半成品的 device mapper 映射下次处理时设备名冲突。6. 实战三LVM、多路径与整盘备份中的 kpartx6.1 镜像里包含 LVM 物理卷时怎么处理服务器磁盘用 LVM 管理在线上很常见备份出来的镜像里分区类型不是 ext4/xfs而是 Linux LVM。这时候即使 kpartx 成功创建映射直接 mount 分区设备依然会失败。假设镜像内有三个分区/boot、LVM 物理卷、swap。kpartx 创建映射后LVM 物理卷会在/dev/mapper/loop0p2上。接下来需要让 LVM 工具去扫描这个物理卷sudo vgscan sudo vgchange -ayvgscan扫描系统所有块设备寻找 LVM 元数据包括新创建的映射设备。vgchange -ay激活找到的卷组。激活后逻辑卷设备会出现在/dev/mapper/下命名通常是vgname-lvname可以用lvscan查看sudo lvscan然后正常挂载逻辑卷sudo mount /dev/mapper/vgdata-root /mnt/data这个流程有三个容易踩的坑。第一个坑是 kpartx 映射的 loop0p2 上如果已经有一个同名卷组比如原来机器上就叫vg00本机的 vgscan 会因为卷组名冲突而拒绝激活。解决方法是激活前临时重命名sudo vgrename vg00 vg00_backup第二个坑是不要在宿主机运行 LVM 服务如lvmetad时贸然插入含 LVM 的镜像设备守护进程可能自动激活卷组并导致环境混乱。稳妥做法是在容器或隔离环境里操作。第三个坑是清理时要确保逻辑卷全部 deactivate否则kpartx -d会提示设备忙sudo vgchange -an vgname sudo kpartx -d /dev/loop06.2 多路径存储环境中的 kpartx 应用SAN 存储环境里一台主机可能通过多条 HBA 卡连接同一个 LUN内核会把每条路径都识别成一个独立块设备比如/dev/sdb和/dev/sdc如果直接分区会造成冲突。多路径软件DM Multipath会把所有路径合并成一个虚拟设备/dev/mapper/mpatha。多路径设备本身没有分区时操作系统在multipath -ll后能看到mpatha但如果 LUN 上有分区表就需要 kpartx 为它创建分区映射sudo multipath -ll sudo kpartx -a /dev/mapper/mpatha ls /dev/mapper/mpathap1创建完成后/dev/mapper/mpathap1就是对应多路径设备的第一个分区。挂载、使用、删除流程和 loop 场景一致但需要注意删除时是kpartx -d /dev/mapper/mpatha而不是某个路径。对于密集型数据库或虚拟化存储环境kpartx -a后最好确认一下映射的 ownership 和权限多路径设备默认权限可能不允许普通账户访问。6.3 用 kpartx 配合 dd 做整盘克隆与备份恢复kpartx 不只用来挂载看内容还能在整盘备份恢复流程中发挥作用。一个实际场景生产机器系统盘故障之前有 dd 备份好的镜像。要恢复到一块新硬盘# 1. 把备份镜像写入新硬盘 sudo dd ifbackup.img of/dev/sdb bs4M statusprogress convfsync # 2. 因为备份镜像和物理盘存在几何差异用 kpartx 清理旧分区映射并重建 sudo partprobe /dev/sdb sudo kpartx -a /dev/sdb # 3. 如果系统里有 LVM重新激活卷组 sudo vgscan sudo vgchange -ay这里 kpartx 的作用不是挂载而是确保系统能识别新盘上的完整分区布局。恢复过程中最怕的是备份镜像比物理盘大或小kpartx 会直接从分区表读取分区位置所以它对设备字节数不敏感只要物理盘能够容纳各分区偏移即可。另一个场景是镜像挂载后做局部恢复比如用户误删了一个数据库表想直接从备份文件里提取。这时 kpartx 挂载后可以用dd按偏移精确恢复某个区块不需要等整个镜像恢复完再抢救数据。7. 踩坑记录设备忙、映射残留和 udev 的干扰7.1 device is busy 完整排查链路kpartx 最让人恼火的报错就是device is busy。这个报错出现时说明有进程、挂载点或者其他内核对象正在引用目标设备。排查链路我一般从最简单的开始# 1. 确认分区映射是否被 mount mount | grep loop0 # 2. 确认是否有进程占用挂载目录 lsof /dev/mapper/loop0p1 fuser -v /dev/mapper/loop0p1 # 3. 检查当前 shell 工作目录 pwd有一种藏得很深的情况你已经 umount 了设备但某个进程比如后台脚本、数据库进程还保持文件句柄。此时 lsof 会明确列出进程 PIDkill 它或者等待它正常退出后再试。如果lsof /dev/mapper/loop0p1没输出但 umount 仍失败就要检查是不是 swap 或者 LVM 缓存引用了它swapon -s sudo dmsetup info /dev/mapper/loop0p1dmsetup info会显示引用计数和其他内核状态Open count大于 0 就说明有内核路径还在使用它。7.2 映射残留导致的找不到分区问题有时候kpartx -a报错说找不到分区但fdisk -l明明能看到完整分区表。这种大概率是前一轮操作留下了残留映射。排查命令sudo dmsetup table sudo dmsetup ls如果发现/dev/mapper/loop0p1已经存在但对应的底层 loop 设备已经不是当前镜像了因为 kpartx -d 没删干净或者 loop 设备被复用会导致新的kpartx -a失败。解决办法是先清理残留映射sudo dmsetup remove loop0p1 sudo dmsetup remove loop0p2 sudo losetup -d /dev/loop0清理后再从头执行挂载流程。为了防止这种情况反复出现我在脚本里通常会在挂载前主动执行一次kpartx -d容错sudo kpartx -d /dev/loop0 2/dev/null || true sudo losetup -d /dev/loop0 2/dev/null || true|| true保证清理命令失败不会中断脚本执行因为第一次运行时这些设备本来就不存在报错是预期内的。7.3 udev 自动映射导致映射反复出现有些系统装上了多路径软件后udev 规则会自动对特定类型的块设备执行 kpartx 映射。这会造成一种奇怪现象你kpartx -d删除了映射几秒后/dev/mapper/下又出现新设备。这通常是 udev 规则里配置了自动分区扫描。查找相关规则grep -r kpartx /lib/udev/rules.d/ /etc/udev/rules.d/常见的是60-persistent-storage.rules或 multipath 相关的规则文件。有些系统在插拔磁盘时会对/dev/sd*设备自动运行 kpartx目的是让多路径分区立即可用。这在服务器场景是方便的但在脚本处理镜像时非常恼人。如果你只是临时处理镜像建议在删除映射前先让 udev 不要干涉sudo udevadm control --stop-exec-queue sudo kpartx -d /dev/loop0 sudo udevadm control --start-exec-queue这相当于暂时冻结 udev 事件队列删除操作不会触发新的自动映射。7.4 kpartx 对 GPT 和混合分区表的支持情况kpartx 已经比较完善地支持 MBR 和 GPT。处理 GPT 时有几个细节值得注意GPT 分区表有主表和备份表两份备份表在磁盘末尾。如果镜像被截断过比如某些工具裁剪了尾部GPT 备份表位置可能失效kpartx 会认为分区表无效。此时可以用gdisk修补sudo gdisk /dev/loop0在交互界面里用w写回并重建备份表。带保护性 MBR 的 GPT 磁盘也就是同时存在 GPT 和 PMBRkpartx 能正常处理不需要额外操作。混合 GPTMBR老式 BIOS 启动方案支持取决于版本如果遇到解析异常优先用gdisk -l确认分区表状态。用kpartx -l预览时如果输出只有loop0p1但gdisk -l能显示好几个分区检查一下是不是存在 unallocated 分区或逻辑分区嵌套这两种情况会干扰映射生成。8. 我平时用的几个效率小技巧8.1 用 kpartx -av 的完整输出判断分区类型kpartx -av输出的每行前面是分区名后面是该分区的长度扇区数和起始偏移。扇区数乘以 512 就是字节数可以用来快速判断分区文件系统类型。比如一个分区长度 104857600 扇区乘以 512 等于 50GB这通常是数据盘。而一个分区只有 204800 扇区100MB大概率是/boot分区。不需要先挂载就能对镜像内部布局有个基本认知。8.2 在容器和脚本中规避交互式确认kpartx 本身没有交互式确认流程所以它很适合嵌入自动化流水线。但 shell 脚本里变量传递需要小心尤其是设备名。推荐用set -euo pipefail统一错误处理#!/bin/bash set -euo pipefail IMG$1 LOOP$(sudo losetup -f) cleanup() { sudo kpartx -d $LOOP || true sudo losetup -d $LOOP || true } trap cleanup EXIT sudo losetup $LOOP $IMG sudo kpartx -a $LOOP # 后续挂载或操作trap cleanup EXIT保证脚本中途出错时也能自动清理设备和映射这是我在生产环境脚本里的标配写法。8.3 组合 fdisk -l、partprobe 和 kpartx 的排错流程线上排查镜像问题时我有一套固定套路推荐给大家# 第一步看分区表 sudo fdisk -l disk.img # 第二步关联 loop 设备但不映射 sudo losetup /dev/loop0 disk.img # 第三步尝试触发内核重读分区表 sudo partprobe /dev/loop0 ls /dev/loop0p* 2/dev/null # 第四步如果第三步没产出分区设备再上 kpartx sudo kpartx -a -v /dev/loop0这套流程的好处是每步操作都能定位问题层面。fdisk 失败说明镜像文件本身有问题fdisk 正常但 partprobe 没生成分区设备说明内核或者 udev 层面拦截了partprobe 正常但 kpartx 失败大概率是 kpartx 版本或者 device mapper 环境问题。按照这个方法排查过不下几十次基本能覆盖 90% 的异常场景。最后多说一句kpartx 不是解密或格式转换工具遇到加密镜像比如 LUKS先用cryptsetup luksOpen解密再执行 kpartx 映射否则只会得到一堆乱码分区表。这个顺序搞反了你会浪费大量时间在根本不必要的排错上。
返回列表