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

J. *_*ord 9 partition kernel gpt disk

我有一个使用 GPT 分区的 3TB 驱动器:

$ 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
Run Code Online (Sandbox Code Playgroud)

但是,当我通过 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
Run Code Online (Sandbox Code Playgroud)

有什么方法可以强制 Linux 识别偏移量 512 处的 GPT?或者,有没有办法创建两个 GPT 标头,一个在 512,一个在 4096,或者它们会重叠吗?

编辑:我发现了一些解决方法,但都不是很好:

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

    $ losetup /dev/loop0 /dev/sdg
    
    Run Code Online (Sandbox Code Playgroud)

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

    $ losetup /dev/loop1 /dev/sdg -o $((10240*512)) --sizelimit $(((5860532216-10240)*512))
    
    Run Code Online (Sandbox Code Playgroud)

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

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

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

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

J. *_*ord 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
Run Code Online (Sandbox Code Playgroud)

这基本上完成了我在选项 1 中计划做的事情,但更加干净。