Kernel
辨識使用不同邏輯扇區大小創建的 GPT 分區表
我有一個使用 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
但是,當我通過 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,或者它們會重疊嗎?
編輯:我找到了一些解決方法,但都不是很好:
- 我可以使用環回設備對磁碟進行分區:
$ 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,但它可能會起作用。
我找到了一個解決方案:一個名為 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 中計劃做的事情,但更乾淨。