Přeskočit na obsah
lurycz Blog programátora
Linux čtení 7 min

Velikost sektoru zamkl výrobce disku, ne značka na štítku

Osm SAS SSD z vyřazeného pole hlásí v Linuxu nulovou velikost. Rozebral jsem firmware, našel sedm bajtů, které za to můžou, a doportoval patch do jádra. Pak jsem pustil jednu nedestruktivní sondu a zjistil, že u jiného disku stačí jeden příkaz.

Osm SAS SSD z vyřazeného diskového pole, každé 1,6 TB, všechna zdravá. Nula vadných sektorů, opotřebení pod pět procent. A v Linuxu z nich neteče ani bajt, protože blokové zařízení má nulovou velikost.

Řešil jsem to od nesprávného konce. Rozebral jsem firmware, našel v něm sedm bajtů, které za to můžou, doportoval cizí patch do jádra a otestoval ho. Pak jsem spustil jednu nedestruktivní sondu na jiný disk z téže bedny a zjistil, že u něj stačí jeden příkaz. Rozhoduje totiž výrobce disku, ne značka na štítku.

Proč 528 bajtů

Disky z polí od IBM, EMC, NetApp a dalších bývají naformátované na sektor o velikosti 520 nebo 528 bajtů. Je to 512 bajtů dat plus 8 nebo 16 bajtů metadat, ze kterých si řadič pole počítá vlastní kontrolu integrity. Uvnitř pole to dává smysl a stojí to jen kus interní rezervy; kapacita na štítku zůstává celá.

Mimo pole je to problém. Blokové vrstvě Linuxu velikost bloku, která není mocninou dvou, neprojde: blk_validate_block_size() ji odmítne a disk zůstane s nulovou velikostí. Neuvidí ho LVM, ext4, XFS ani ZFS.

Není to chyba jádra a nemá cenu na ni čekat. Celá bloková vrstva počítá s tím, že se offset v bajtech dostane na číslo sektoru posunem. Kdo chce 528bajtový disk používat mimo pole, musí ho buď přeformátovat, nebo přepočítávat sám.

Co jsem zkusil a nefunguje

Tohle je asi nejužitečnější část textu, protože fóra na tuhle otázku odpovídají buď „nejde to“, nebo „zkus sg_format“. Všechno níž jsem zkoušel na živém disku a žádný z těch pokusů disk nepoškodil.

CestaVýsledek
sg_format --size=512, i s --sixInvalid field in parameter list, byte 13 bit 7
sg_raw MODE SELECT, krátký LBA, tři varianty počtu blokůtotéž
sg_raw MODE SELECT s LONGLBA, 24bajtový parametrtotéž; 528 projde, 512 ne
openSeaChest --setSectorSize 512„not supported on this device“
openSeaChest --formatUnit na 512, 520, 524 i 4096„Format Unit Failed!“
crossflash oficiálním firmwarem Seagatesense 0x05 po dvaadvaceti segmentech
sg_write_buffer, režim 5 i 7ASC 0x26 / ASCQ 0x99
TCG PSID revert, ruční stack nad sg_rawsession vrstva nereaguje
sedutil-cli„Invalid or unsupported disk“; umí SATA a NVMe, ne SAS

Ty tři nejzajímavější řádky stojí za rozvedení.

Blokovaná je změna, ne formátování. FORMAT UNIT na stávající velikost sektoru projde bez potíží. Jakmile v parametrech stojí jiné číslo než 528, disk vrátí vendor-specific kód ASC 0x26 s ASCQ 0x99. Týmž kódem mimochodem odmítá i pokus přepsat maximální rychlost linky ze 6 na 12 Gb/s. Je to jeden a týž zámek na dvě různé věci.

Crossflash disk poznal a odmítl vědomě. Nahrání pravého podepsaného firmwaru od Seagate skončilo po dvaadvaceti segmentech. Zajímavé je, že standardní varianta obrazu je odmítnutá okamžitě, kdežto SED varianta se dostane dál. Disk tedy typ souboru uznal a padlo to až na kontrole zákaznického stavu, o které mluví produktový manuál Seagate v oddílu o ověřovaném stahování firmwaru: obraz musí odpovídat modelu, revizi a customer status.

TCG vrstva odpovídá, ale nic nedělá. Level 0 Discovery funguje, jen je potřeba správné CDB, protože alokační délka se u něj udává v blocích, ne v bajtech. Disk vrátí Opal SSC 1.00 a hlásí zámky jako podporované a zapnuté. Skutečná session ale nefunguje: SECURITY PROTOCOL IN vrací pokaždé prázdný payload. Rozhodl to jeden test. Poslal jsem na ComID 512 bajtů čistého nesmyslu, samé 0xdeadbeef dokola, a disk odpověděl Good. Neplatný paket musí skončit chybou, takže je disk přijímá a zahazuje.

Na výsledku by to stejně nic nezměnilo. Jiný člověk na fóru Serve The Home zkoušel PSID revert na disku, kde mu sedutil normálně funguje, a hlásí, že sg_format po čerstvém resetu skončí na téže chybě. Reset šifrovacího klíče velikost sektoru neodemyká.

Zámek je v datech, ne v kódu

Když softwarová cesta došla, sáhl jsem po obsahu SPI flash. Porovnáním dumpu ze zamčeného disku s dumpem z pravého disku Seagate se dá najít přesné místo, které o velikosti sektoru rozhoduje. Vyšlo z toho, že zámek není kus kódu, ale pojmenovaný konfigurační záznam v datech, a že jeho kontrolní součet umím dopočítat. Přepsat by se muselo sedm bajtů.

Rozepsal jsem to zvlášť v článku Zámek velikosti sektoru sedí v datovém záznamu. Zápis na hardware jsem neprovedl, chybí mi programátor.

Obchvat v ovladači

Druhá cesta zámek neřeší, jen ho obchází. Ovladač sd může číst a zapisovat celé 528bajtové sektory a hostu ukazovat prvních 512 bajtů z každého. Patch, který to umí, existuje, ale přišel bez autora a cílil na strom jádra, který v upstreamu nikdy nebyl. Doportoval jsem ho na 6.8 a otestoval proti fyzickému disku v QEMU, aniž bych restartoval hostitele. Funguje to včetně křížové validace, cena je 16 bajtů z každého sektoru.

Podrobně v článku Nový kernel jsem vyzkoušel proti fyzickému disku bez restartu serveru.

Sonda, kterou jsem měl spustit jako první

Do tohohle bodu jsem počítal s tím, že za vším stojí firmware od IBM. Pak mi do serveru přibyl další IBM disk, tentokrát 400GB kus, a chtěl jsem vědět, jestli se chová stejně, dřív než na něj pustím čtyřicetiminutový formát.

Existuje na to zkouška, která nic nezničí. MODE SELECT má v bajtu 1 příznak SP, který říká, jestli se má nastavení uložit natrvalo. S vypnutým SP disk parametry jen zkontroluje a zahodí, na medium nesahá:

printf '\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x02\x00' > /tmp/ms512.bin
sg_raw -s 16 -i /tmp/ms512.bin /dev/sdX 55 10 00 00 00 00 00 00 10 00

V CDB je 55 MODE SELECT(10) a bajt 0x10 znamená PF zapnuté, SP vypnuté. Šestnáct bajtů parametrů je osmibajtová hlavička a za ní block descriptor s délkou bloku 512. Disk buď řekne, že je to v pořádku, nebo odmítne. Trvá to zlomek vteřiny.

A výsledek byl jiný, než jsem čekal:

DiskKdo ho vyrobilOdpověď na sondu
IBM-SSG, 400 GBHGSTSCSI Status: Good
IBM-SSG, 1,6 TBSeagateIllegal Request, Invalid field in parameter list

Oba disky nesou stejnou značku, stejný prefix v identifikaci a oba pocházejí ze stejného pole. Jeden se přeformátovat dá a druhý ne. Kritérium tedy není IBM, ale výrobce, který ten disk pro IBM postavil, a poznáte ho z prvních tří bajtů adresy SAS.

Fóra na to mají tabulku, podle které jde reformátovat NetApp, EMC, Dell, Toshiba, HPE a Huawei, kdežto „IBM branded“ nejde. Podle mého měření je ta tabulka příliš hrubá. Nejde ta část disků IBM, kterou vyrobil Seagate.

Pak už jen jeden příkaz

U disku, který sondu projde, je zbytek nuda. sg_format --size=512 a čekání. U mě to trvalo 36 minut a postup byl po celou dobu lineární.

Průběh jde číst jedině přes sg_requests --progress, protože během formátu vrací sg_turssg_readcap jen „device not ready“ a jádro drží nulovou velikost. Odhad zbývajícího času má smysl dělat až po nějakých pěti minutách běhu: vzorek z prvních 150 vteřin mi vyšel na dvě hodiny, skutečnost byla 42 minut. Rozjezd není lineární, ustálený běh už ano.

Fast format z SBC-4 existuje a starší disk ho přijal, jenže nezachrání den. Bez něj šel formát tempem 2,35 % za minutu, s --ffmt=1 --dcrt 2,82 %. To je zrychlení kolem patnácti procent, ne řádové. Kvůli tomu nemá smysl přerušovat už běžící formát.

Přerušit ho jde mimochodem bezpečně, což jsem si ověřil. Po ukončení procesu a resetu zařízení hlásí disk Medium format corrupted, což vypadá hrozivě, ale je to očekávaný a vratný stav; stačí formát spustit znovu.

Hlavní obava byla, že s metadaty přijdu o tři procenta kapacity. Nepotvrdila se. Disk si po změně délky bloku přepočítal počet logických bloků z fyzické kapacity:

pred:  757 743 288 x 528 B = 400 088 456 064 B
po:    781 422 768 x 512 B = 400 088 457 216 B

Rozdíl 1 152 bajtů, tedy nic. Zápis přes oflag=direct dává 392 MB/s a testy integrity na zarovnaném, nezarovnaném i koncovém offsetu prošly.

Tři cesty a kdy kterou

CestaFunguje naZtráta kapacityCo je potřeba
sg_format --size=512disky bez zámkužádnánic, kolem 40 minut času
patch do jádra, emulacei na zamčené16 B ze sektoru, 1,55 TB z 1,60nestandardní jádro
přepis SPI flashi na zamčenéžádnáprogramátor, rozebrat disk

Pořadí je dané tou sondou. Když projde, jde se cestou první a nic dalšího se neřeší. Když neprojde, přichází na řadu volba mezi tichým ukusováním kapacity a pájkou. A pořád existuje čtvrtá možnost, kterou jsem si dlouho odmítal připustit: nasadit ty disky tam, kde je 528 bajtů nativní hodnota, nebo je prodat někomu, kdo takové pole provozuje. Pro něj to není vada.

Co si z toho beru

Nejlevnější diagnostika patří na začátek, ne na konec. Ta sonda trvá zlomek vteřiny, nic nezničí a rozhoduje o tom, jestli má cenu dělat všechno ostatní. Kdybych ji spustil první den, ušetřil bych si většinu předchozí práce, protože bych rovnou věděl, které disky jsou ztracený případ a které se srovnají do oběda.

Vzniklo to z předpokladu, který jsem si nikdy nezkusil ověřit. Značka na štítku byla IBM, fóra o IBM discích píšou, že nejdou, takže jsem hledal zámek od IBM. Byl to zámek od Seagate a poznalo se to na jiném disku téže značky. Rozborem firmwaru se přitom to rozlišovací kritérium najít nedalo, protože jsem měl dumpy jen z disků od jednoho výrobce.

Co zůstalo nedodělané, přiznávám rovnou. Zamčené disky odemčené nejsou. Vím, kterých sedm bajtů by se mělo přepsat, ale zápis do flash jsem neprovedl. Emulace v jádře běží a prošla křížovou validací, ostrá data na ní ale nemám a mít nebudu, dokud neproběhne dlouhý test s verifikací. A rychlost linky zůstává na 6 Gb/s, protože ten limit sedí ve firmwaru disku a žádná z těch tří cest na něj nedosáhne.

Kód a podklady

Všechno, na čem tenhle text stojí, je ve veřejném repozitáři st1600fm0013-528b-sectors – skripty, zálohy firmwaru i rozbory, které se do článku nevešly.

Zdroje

Dál k tématu

  • Linux

    Nový kernel jsem vyzkoušel proti fyzickému disku bez restartu serveru

    Cizí patch do ovladače sd bez hlavičky a bez stopy na internetu cílil na jádro, které nikdy neexistovalo. Popisuju, jak jsem ho posoudil, doportoval na 6.8 a vyzkoušel proti fyzickému disku v QEMU, aniž bych restartoval server.

  • Linux

    Zámek velikosti sektoru sedí v datovém záznamu, ne v kódu firmwaru

    Osm SAS SSD z vyřazeného pole hlásí v Linuxu nulovou velikost. Než jsem začal obcházet firmware v ovladači, rozebral jsem tři dumpy SPI flash a našel místo, které o velikosti sektoru rozhoduje. Je to datový záznam, ne kus kódu.

  • Linux

    Linux load average – Chápeme hodnoty příkazu uptime

    Řešili jste někdy co vlastně znamenají 3 čísla na konci příkazu uptime ? load average: 0,10, 0,09, 0,11 Tato čísla obecně vyjadřují průměrné zatížení linuxového systému za období 1, 5 a 15 minut a nezahrnují žádné procesy, čekající doby i/o wait na discích nebo síti.…

  • Linux

    Test rychlosti internetu (speedtest) z linuxového bashe

    Řešili jste někdy otázku, jak změřit rychlost na linuxovém serveru bez GUI ? Dříve jsem to řešil stahováním 1GB souboru , ale to se pro větší rychlosti nehodí hlavně kvůli nedostatečné šířce pásma cílového serveru, tudíž přesné změření rychlosti nepřipadá v úvahu. Proto jsem…

Diskuse

Zatím tu nikdo nediskutuje.

Napsat příspěvek

Diskutovat můžete i bez účtu. S registrací se ale příspěvek zveřejní hned a nemusíte pokaždé vyplňovat jméno. Účet už máte? Přihlaste se.

Nezveřejňuje se, slouží jen k ověření.

Podporuje zápis Texy: **tučně**, *kurzíva*, odrážky, odkazy.