ILD

use loop device emulate block device
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2023-8-16 站点:Inside Linux Development

        有时候为了了解磁盘分区知识、分析异常启动等问题,需要模拟一个块设备。loop device就应运而生。loop device使用文件作为后备,创建虚拟块设备。loop device的工具是losetup。

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,并进行分区

下面的例子,创建了一个loop device,并进行分区,让内核识别到分区。

1 创建一个全f的32M文件

# 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


2 创建loop device

# losetup -f loop.img

-f 选项表示自动选择一个空闲的device


使用losetup -l命令,查看刚创建的loop device是:/dev/loop17


3 使用sfdisk命令创建两个分区

# 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的显示结果,表示内核没有识别到两个子分区。


4 使用partprobe命令加载分区

 # 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


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.