1. 创建镜像文件
1.1 loop存储适用场景
把普通文件当成 /dev/loopN 块设备来用,读写走块设备接口,backing file 仍是宿主机上的一个文件
- 挂载 ISO 与磁盘镜像
- 本地练手与压测
- 加密卷与密文镜像
- 模拟云盘或 CSI 块卷
- 只读暴露文件
- 临时挂载
和真实磁盘相比,loop 设备性能受 backing file 所在文件系统影响,关联默认不持久化,重启后一般要重新 losetup 或写进 /etc/fstab。
1.2 创建镜像
在宿主机上准备 backing file
1
| truncate -s 10G /data/tmp/disk.img
|
1
| dd if=/dev/zero of=/data/tmp/disk.img bs=1M count=10240
|
1
| fallocate -l 10G /data/tmp/disk.img
|
1
| dd if=/dev/zero of=/data/tmp/disk.img bs=4k count=2621440
|
2. 关联 loop 设备
把镜像文件挂到 /dev/loopN
1
| losetup -f --show /data/tmp/disk.img
|
1
| losetup /dev/loop0 /data/tmp/disk.img
|
1
2
3
| losetup /dev/loop0 /data/tmp/disk.img \
--sector-size 4096 \
--read-only
|
1
| losetup -j /data/tmp/disk.img
|
1
| losetup -O NAME,BACK-FILE,STATE,MAJ:MIN /dev/loop0
|
3. 分区与格式化
在 loop 设备上建分区表或直接格式化
1
2
| parted -s /dev/loop0 mklabel gpt
parted -s /dev/loop0 mkpart primary 0% 100%
|
会生成 /dev/mapper/loop0p1,避免分区设备未自动创建。
1
2
3
| mkfs.xfs /dev/loop0
mkfs.ext4 /dev/loop0
mkfs.btrfs /dev/loop0
|
1
| mkfs.xfs /dev/mapper/loop0p1
|
1
| xfs_repair -n /dev/loop0
|
4. 挂载与使用
挂载 loop 设备或镜像文件
1
| mount /dev/loop0 /mnt/looptest
|
1
| mount -o ro /dev/loop0 /mnt/looptest
|
1
| mount -t xfs /dev/loop0 /mnt/looptest
|
1
| mount /dev/mapper/loop0p1 /mnt/looptest
|
1
| mount -o loop /data/tmp/disk.img /mnt/looptest
|
mount 会自动寻找空闲 loop 设备。
1
2
| findmnt /mnt/looptest
mount | grep loop0
|
5. 扩容
镜像扩容后需同步更新 loop 设备与文件系统
1
| fallocate -l 20G /data/tmp/disk.img
|
1
| truncate -s 20G /data/tmp/disk.img
|
1
| xfs_growfs /mnt/looptest
|
1
| resize2fs /dev/loop0 20G
|
6. 卸载与解除关联
按挂载 → 分区映射 → loop 关联的顺序释放
1
| umount -l /mnt/looptest
|
1
| fuser -km /mnt/looptest
|
慎用,会影响所有 loop 设备。
7. 清理
删除镜像并确认无残留设备
1
| rm -f /data/tmp/disk.img
|
1
2
| losetup -a
ls /dev/loop* 2>/dev/null
|
8. 批量生命周期示例
循环创建与批量清理
1
2
3
4
5
6
7
8
9
10
| for i in $(seq 0 4); do
IMG=/data/tmp/disk_${i}.img
MNT=/mnt/loop_${i}
truncate -s 5G $IMG
LOOP=$(losetup -f --show $IMG)
mkfs.xfs -f $LOOP
mkdir -p $MNT
mount $LOOP $MNT
echo "$LOOP -> $MNT ($IMG)"
done
|
1
2
3
4
5
6
7
8
9
10
11
| for i in $(seq 0 4); do
MNT=/mnt/loop_${i}
IMG=/data/tmp/disk_${i}.img
LOOP=$(losetup -j $IMG | awk -F: '{print $1}')
[ -n "$LOOP" ] && {
umount $MNT 2>/dev/null
losetup -d $LOOP
}
rm -f $IMG
rmdir $MNT 2>/dev/null
done
|
9. 状态查看速查
loop 设备与内核模块排查
1
| losetup -j /data/tmp/disk.img
|
1
2
| lsmod | grep loop
modinfo loop
|
1
| cat /sys/module/loop/parameters/max_loop
|
1
| modprobe loop max_loop=32
|
重启后失效。
1
| echo "options loop max_loop=32" > /etc/modprobe.d/loop.conf
|
10. 常见问题
losetup: /dev/loop0: Device or resource busy:先查占用再释放
1
2
3
| losetup -a
lsof /dev/loop0
fuser -m /mnt/xxx
|
losetup -f 找不到空闲设备:检查并调大 max_loop
1
2
| cat /sys/module/loop/parameters/max_loop
modprobe loop max_loop=32
|
mount: /dev/loop0 is already in use:先解除关联再重建
1
2
| losetup -a
losetup -d /dev/loop0
|
- 分区设备
/dev/loop0p1 未生成:用 kpartx 创建 mapper
- 扩容后文件系统未识别新大小:先重读 loop 容量再扩文件系统
1
2
3
| losetup -c /dev/loop0
xfs_growfs /mnt/looptest
resize2fs /dev/loop0
|
losetup -c 报错:先 umount,再 losetup -c,再重新 mount
1
2
3
| umount /mnt/looptest
losetup -c /dev/loop0
mount /dev/loop0 /mnt/looptest
|
1
| dd if=/dev/zero of=/data/tmp/disk.img bs=1M count=10240
|