k47.cz
mastodon twitter RSS
bandcamp explorer
««« »»»

Ve střevech mrtvých NTFS disků

— k47

Jak jsem tady už psal, stal jsem se opatrovníkem a křísitelem jednoho mrtvého disku. Následující řádky představují detailní zápisky z pouti za obnovou dat.

Jako první krok jsem vytvořil obraz disku, protože snažit se obnovit data ze zařízení, které vám umírá pod rukama, je méně než ideální. Hlavní je z trosek zachránit co nejvíc bajtů a starou rotující rez nenamáhat víc, než je nutné. Jsou na to extra programy jako ddrescue, ale klasické dd if=/dev/sdf of=disk.img fungovalo na výbornou.

Co dál? Zkusil jsem obraz disku připojit, nic, nejde o validní souborový systém (FS). Vytvořil jsem dump celého disku ne jen NTFS oddílu a mount připojuje právě jen oddíly (V tom spočívá rozdíl mezi /dev/sdf/dev/sdf1). Hexeditorem jsem z GPT bloku vyčetl, že NTFS oddíl začíná na adrese 0x100000. Když jsem pak tuto hodnotu předal mountu, ten rozpoznal NTFS, jen hlásil že je poškozený a odmítal ho připojit. Následovala další důkladná várka googlení (tedy duckduckgoování), další programy, které by měly opravit FS do konzistentního stavu (testdisk), ale nic. Stále FS nelze připojit. Dostal jsem se tedy do stavu, kdy se mi disku válelo 300GB dat, jejichž formát byl dobře znám a zdokumentován, ale byly poškozené způsobem, který je znemožňoval jednoduše číst standardní cestou. Co dál?

Normální člověk by pokrčil rameny a prohlásil, že si neumí poradit, ale to není víc než poraženecké výmluvy. Nic pro mě. Já preferuji stupidní řešení, když to povede k dobré historce (a zápisu na k47čce, což je více méně jedno a to samé). Proto nastal čas na plán B, dramatický a radikální, přesně v duchu vzájemného pohybu hory a mohameda.

Protože jsem nenašel žádnou utilitu pro obnovu dat, jednoduše jsem si napsal vlastní. Nehledal jsem příliš důkladně a ani to nebylo úplně jednoduché2 , ale co, teď už je pozdě něco měnit. Výsledkem je program, který projde obsah disku, dekóduje ho, zjistí, kde se ve změti bytů nacházejí data souborů a zkopíruje je ven do čitelné podoby. Bylo k tomu třeba hodně duckduckgoování, dokumentace datových struktur NTFS, hodně pokusů a ještě více omylů, ale nakonec jsem uspěl.

NTFS je, pokud já i původní majitel(ka) disku ignorujeme všechny jeho pokročilé funkce, celkem jednoduchý. Všechny soubory jsou vyjmenované v tabulce MFT (master file table), každá položka má 1kB a začíná magickým stringem FILE0. Když zjistím, kde se MFT nachází, stačí číst 1kB bloky a dekódovat je. Jejich obsah je tvořený hlavičkou a seznamem atributů proměnné délky. Z hlavičky MFT záznamu zjistím adresu, kde atributy začínají a pak v nich musím najít dva: Jméno (identifikované prefixem 0x30) a obsah souboru (prefix 0x80). Není to zas tak jednoduché – atributy mohou být rezidentní (jsou přítomné v MFT záznamu, jen pokud se vejdou do 1kB prostoru) a nerezidentní (odkazují na bloky disku, kde leží jejich obsah). Jméno musí být rezidentní, ale obsah může mít obě podoby. Krátké soubory se tedy mohou celé nacházet v MFT záznamu, dlouhé jsou pak odkazované přes tzv. cluster chain – komprimovaný seznam dvojic číslo clusteru (FS je adresovaný v 4 kB clusterech, ne v 512B blocích) a počet zabraných clusterů. Je tedy nutné najít všechny tyto fragmenty a zkopírovat je ve správném pořadí.

Do hry ještě vstupují podivnosti Windows a vychytávky NTFS. Soubor nemá jen jedno jméno, ale dvě—dlouhé jméno a krátké 8.3 (data jsou uloženy jako litle-endian a texty jsou v LE UTF-16). Navíc soubory můžou mít několik streamů, kdy jedno jméno odkazuje na několik souborů, z nichž jeden je ten hlavní a ostatní jsou skryté, obvykle neviditelné. Tato funkcionalita se používá jen okrajově (soubory stažené z internetu jsou tímto způsobem označené a windows varují při jejich spuštění), ale je třeba z nimi počítat při záchraně dat.3

Při obnově jsem zjistil, že se z neznámého důvodu určité soubory vyskytovaly v MFT několikrát. Možná že šlo o přesunuté (nebo zkopírované a pak smazané soubory), kdy původní záznam zůstal a přibyl nový. Možná, nezjišťoval jsem to. Data jsem vykopíroval ven, pak je deduplikoval a vyházel soubory plné nul. Někdy jen díky těmto záhadným duplikátům soubor přežil apokalypsu. Už tak jsem na akci obnovy strávil víc času, než by bylo rozumné a nechtěl jsem studovat každý detail a zapeklitost souborového systému z roku 1993 (který se microsoft víc než jednou snažil nahradit něčím novějším).

Ale i tak jsem se toho dozvěděl víc, než jsem kdy doufal, že se dozvím a jedno je jisté – souborové systémy jsou velice zajímavé. Jde o kritickou komponentu. Když se něco pokazí v ovladači grafiky, restartujte počítač a všechno je zapomenuto, ale FS musí fungovat, protože jinak dojde ke ztrátě dat. A co víc, musí fungovat za všech okolností, když vypadne elektřina, havaruje systém, dojde ke spontánnímu přehození bitu nebo k chybám v umírajícím hardware. Do toho musíte započítat zpětnou i dopřednou kompatibilitu a s tím související rozšiřitelnost a další požadavky na moderní FS jako jsou kontrolní součty, zabudovaný RAID, snapshoty, komprese, šifrování, deduplikace a nároky na vysokou efektivitu na mnoha kategoriích disků a máte před sebou kyklopský projekt. Ne nadarmo se říká, že k vývoji FS je třeba 100 člověkolet, než dosáhne použitelného stavu.

Abych to zkrátil: Operace proběhla úspěšně. Po několika dnech hackování se mi podařilo obnovit víc jak 50% disku, zbytek byl nečitelný a/nebo plný nul. Hlavní však byla cesta, která za tím výsledkem vedla a všechno to, co jsem se naučil.

Navíc jsem získal jednu zadluženou duši. Můžu se u ní ukázat ve tři ráno a požadovat spolupráci při likvidaci mrtvoly. Dávám tomu tak 30%, že toho v příštím roce využiji.


  1. Po incidentu jsem se začal zajímat, jak jsou organizované další souborové systémy a podíval se na vnitřnosti ext4. Ten také není příliš komplikovaný a bylo by snadné napsat utilitu, která z něj vytahá data. Ale protože jde o linuxovou stálici a jeden z prvních souborových systémů na této platformě (jako ext v roce 1992), dovolil bych si tipovat, že tyto již existují, jsou efektivní a připraveny k použití v repozitářích. Z dokumentace jde také jasně vidět, jak se byl v průběhu let postupně vylepšován a funkce se vršily jedna na druhou při zachování zpětné kompatibility formátu dat. Například kontrolní součty jsou podivně rozdělené. Na začátku inode se nachází prvních 16 bitů a někdy později dalších 16 bitů, tato nespojitost je očividně důsledek historického vývoje.
  2. Kdyby Java umožňovala mmap souboru většího než 2GB, bylo by to o něco jednodušší.
  3. Nedávno jsem se dozvěděl, že je to běžné i v unixovém světě jako rozšířené atributy.
píše k47, ascii@k47.cz