有时候为了了解磁盘分区知识、分析异常启动等问题,需要模拟一个块设备。loop device就应运而生。loop device使用文件作为后备,创建虚拟块设备。loop device的工具是losetup。
set up and control loop devices
查看
losetup [loopdev]
losetup -l [-a]
detach
losetup -d loopdev...
Set up a loop device:
losetup [-o offset] [--sizelimit size] [--sector-size size]
[-Pr] [--show] -f|loopdev file
下面的例子,创建了一个loop device,并进行分区,让内核识别到分区。
# dd if=/dev/zero ibs=4k count=8192 | tr "\000" "\377" > loop.img
8192+0 records in
65536+0 records out
33554432 bytes (34 MB, 32 MiB) copied, 0.0593922 s, 565 MB/s
# losetup -f loop.img
-f 选项表示自动选择一个空闲的device
使用losetup -l命令,查看刚创建的loop device是:/dev/loop17
# sfdisk /dev/loop17
Welcome to sfdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Checking that no-one is using this disk right now ... OK
Disk /dev/loop17: 32 MiB, 33554432 bytes, 65536 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
sfdisk is going to create a new 'dos' disk label.
Use 'label: <name>' before you define a first partition
to override the default.
Type 'help' to get more information.
>>> ,4M
Created a new DOS disklabel with disk identifier 0x0cfdb114.
Created a new partition 1 of type 'Linux' and of size 4 MiB.
/dev/loop17p1 : 2048 10239 (4M) Linux
/dev/loop17p2: ,8M
Created a new partition 2 of type 'Linux' and of size 8 MiB.
/dev/loop17p2 : 10240 26623 (8M) Linux
/dev/loop17p3: write
New situation:
Disklabel type: dos
Disk identifier: 0x0cfdb114
Device Boot Start End Sectors Size Id Type
/dev/loop17p1 2048 10239 8192 4M 83 Linux
/dev/loop17p2 10240 26623 16384 8M 83 Linux
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Invalid argument
The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).
Syncing disks.
上述标黑的是输入的命令,写入分区表后,sfdisk会调用re-read partition table ioctl,来让内核重新加载此设备的分区表。
但是在我的ubuntu上,这个命令失败了。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 4K 1 loop /snap/bare/5
。。。
loop17 7:17 0 32M 0 loop
。。。
sda 8:0 0 400G 0 disk
├─sda1 8:1 0 512M 0 part /boot/efi
└─sda2 8:2 0 399.5G 0 part /
sdb 8:16 0 256G 0 disk
└─sdb1 8:17 0 256G 0 part /work/disk1
sr0 11:0 1 1024M 0 rom
lsblk的显示结果,表示内核没有识别到两个子分区。
# partprobe /dev/loop17
此时在lsblk,可以看到子分区了。
# lsblk
loop17 7:17 0 32M 0 loop
├─loop17p1 259:0 0 4M 0 part
└─loop17p2 259:1 0 8M 0 part
对应的block device node,也创建了:
# ls /dev/loop17* -l
brw-rw---- 1 root disk 7, 17 Aug 16 14:13 /dev/loop17
brw-rw---- 1 root disk 259, 0 Aug 16 14:13 /dev/loop17p1
brw-rw---- 1 root disk 259, 1 Aug 16 14:13 /dev/loop17p2
后续就可以给/dev/loop17p1和/dev/loop17p2创建文件系统,并mount到文件系统了。
参考:
man losetup
man partprobe