识别使用不同逻辑扇区大小创建的GPT分区表


9

我有一个3TB驱动器,已使用GPT对其进行了分区:

$ sudo sgdisk -p /dev/sdg
Disk /dev/sdg: 5860533168 sectors, 2.7 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): 2BC92531-AFE3-407F-AC81-ACB0CDF41295
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 5860533134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2932 sectors (1.4 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048           10239   4.0 MiB     8300
   2           10240      5860532216   2.7 TiB     8300

但是,当我通过USB适配器连接它时,它报告的逻辑扇区大小为4096,并且内核不再识别分区表(因为它正在扇区1上查找GPT,现在该扇区的偏移量为4096,而不是512):

$ sudo sgdisk -p /dev/sdg
Creating new GPT entries.
Disk /dev/sdg: 732566646 sectors, 2.7 TiB
Logical sector size: 4096 bytes
Disk identifier (GUID): 2DE535B3-96B0-4BE0-879C-F0E353341DF7
Partition table holds up to 128 entries
First usable sector is 6, last usable sector is 732566640
Partitions will be aligned on 256-sector boundaries
Total free space is 732566635 sectors (2.7 TiB)

Number  Start (sector)    End (sector)  Size       Code  Name

有什么方法可以强迫Linux在偏移512处识别GPT?或者,是否可以创建两个GPT标头,一个在512,另一个在4096,或者它们会重叠?

编辑:我发现了一些变通办法,没有一个是非常好的:

  1. 我可以使用回送设备对磁盘进行分区:

    $ losetup /dev/loop0 /dev/sdg
    

    回送设备的扇区大小始终为512,因此这使我可以根据需要对设备进行分区。但是,内核无法识别回送设备上的分区表,因此我必须创建另一个回送设备并手动指定分区大小和偏移量:

    $ losetup /dev/loop1 /dev/sdg -o $((10240*512)) --sizelimit $(((5860532216-10240)*512))
    

    我可以编写一个脚本来自动执行此操作,但是能够自动执行该操作会很好。

  2. 我可以运行nbd-server和nbd-client;NBD设备默认情况下具有512字节的扇区,并且NBD设备是可分区的。但是,NBD文档警告不要在同一系统上运行nbd服务器和客户端。测试时,内核nbd客户端挂起,我不得不杀死服务器。

  3. 我可以使用相同的设置运行istgt(用户空间iSCSI目标)。这向系统提供另一个具有512字节扇区的SCSI设备。但是,在测试时,此操作失败并导致ext4代码中的内核NULL指针取消引用。

  4. 我还没有研究过devmapper,但是它可能有用。


1
看到这个博客文章:goughlui.com/2013/10/02/…–
fpmurphy

Answers:


3

我找到了一个解决方案:一个名为kpartx的程序,这是一个用户空间程序,它使用devmapper从环回设备创建分区,效果很好:

$ loop_device=`losetup --show -f /dev/sdg`
$ kpartx -a $loop_device
$ ls /dev/mapper
total 0
crw------- 1 root root  10, 236 Mar  2 17:59 control
brw-rw---- 1 root disk 252,   0 Mar  2 18:30 loop0p1
brw-rw---- 1 root disk 252,   1 Mar  2 18:30 loop0p2
$
$ # delete device
$ kpartx -d $loop_device
$ losetup -d $loop_device

这基本上可以完成我计划在选项1中执行的操作,但是更加简洁。


2

在Linux上,如果设置max_partloop内核模块的参数,则循环设备是可分区的。如果loop是内置的(不是模块),则可以传递loop.max_part=31内核命令行参数。

因此,在配置loop驱动程序以获取可分区的块设备之后,应该要做的就是:

losetup --show -f /dev/sda

为了得到一些/dev/loopXp1/dev/loopXp2...设备为每个分区。

自从您发布问题以来,内核在这方面发生了一些变化:

  • 从4.14开始,还可以为循环设备指定除512之外的逻辑块大小losetup -b 4096。创建循环设备后,还可以更改其块大小。

  • 从4.11开始,将nbd设备的逻辑块大小设置为传递给nbd-client(-b选项)的块大小。由于默认块大小为(过去是)1024,因此nbd设备现在获得的默认逻辑扇区大小为1024,而不是之前的512(从向后兼容性的角度来看,这是非常糟糕的)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.