Dobrý den.
Měl jsem btrfs raid1 na dvou discích, fungoval bez problémů. Teď, zpětně viděno, jen z hloupého rozmaru jsem si usmyslel vyměnit v něm disky za větší. Připojil jsem dva nové větší disky (pro informaci - poněkud pochybného původu) a udělal postupně btrfs replace obou stávajících disků na nové. Proběhlo v pořádku, žádné chyby. Následně jsem tedy ještě udělal už na těch nových discích btrfs filesystem resize abych využil to nové místo.
Celou dobu jsem si (naivně) myslel, že je to celkem bezpečná operace, protože mi pořád zůstávají v záloze ty původní dva disky, v případě problémů se k nim mohu vrátit a ztratím max. ty změny od začátku replace. V zápětí se ukázalo že ty nové disky (SSD) jsou opravdu pochybné, po pár hodinách používání prostě začaly "zapomínat" data na nich mizela a v btrfs device stats začaly přibývat corruption_errs.
Myslel jsem si, že možná bude stačit jen odpojit ty nové disky a restartovat, případně manuálně mountnout ty původní disky. Ale nic z toho se nedaří. Při restartu systém ty původní disky nenajde a pokus o ruční mount hlásí wrong fs type, bad option, bad superblock
On btrfs replace příkaz něco zapisuje na ty původní, zdrojové disky? Nebo je dokonce nějak přepisuje/nuluje? Existuje vůbec nějaká cesta zpět?
Díky
Jako úplně první krok teď doporučuji zaběhnout do důvěryhodného obchodu, koupit tam dostatečnou diskovou kapacitu a udělat bitovou kopii původních disků, než si do nich hrábneš ještě víc. A dál se hrabat v té kopii, nezkoušet rozchodit původní fyzické disky.
Z manuálu k btrfs replace:
After completion of the operation, the source device is removed from the filesystem.
Tady (https://superuser.com/questions/1281942/recover-data-from-replaced-btrfs-disk) to vypadá na trochu víc informací (přepíše se superblok) i s možností obnovy zápisem magických hodnot na konkrétní místo na disku.
dd z původních disků jinam bylo první co jsem udělal. Ten popis obnovy z odkazu vypadá hodně magicky. Zkusím nejdřív nastudovat a pochopit co vlastně dělá a odkud bere ta záhadná čísla.
Ale díky za odkaz, Google jsem samozřejmě zkoušel, asi jsem se ptal špatně.
Ve zkratce, na tom disku na přesně dané lokaci je informace "tohle je btrfs disk" (to je ta magická hodnota) a v rámci replace příkazu se tahle informace smaže. Pro obnovu je potřeba ji tam zase vrátit (zapsat na konkrétní adresu toho disku). Komplikované je to tím, že superblok, co tu magickou hodnotu obsahuje, se kvůli odolnosti zapisuje duplikovaně na víc záložních pozic v rámci disku, takže to tam dělá 3x.
Ale je to dva roky stará odpověď, nevím, jestli se něco změnilo v superbloku, a nezkoumal jsem, jestli se ty adresy záložních superbloků posunuly.
Jasně, když člověk ví co má hledat (_BHRfS_M) hned se ta informace hledá snadněji:
https://archive.kernel.org/oldwiki/btrfs.wiki.kernel.org/index.php/On-disk_Format.html#Superblock (https://archive.kernel.org/oldwiki/btrfs.wiki.kernel.org/index.php/On-disk_Format.html#Superblock)
O něco jsem se pohnul, teď už hlásí
[ 6224.497322] BTRFS: device fsid 2db8f54a-3a36-4e3c-8e1f-6ef781966d66 devid 0 transid 0 /dev/loop30 scanned by mount (7926)
[ 6224.497921] BTRFS info (device loop30): first mount of filesystem 2db8f54a-3a36-4e3c-8e1f-6ef781966d66
[ 6224.497939] BTRFS info (device loop30): using crc32c (crc32c-intel) checksum algorithm
[ 6224.497944] BTRFS error (device loop30): superblock checksum mismatch
[ 6224.497956] BTRFS error (device loop30): open_ctree failed
Nadějí mě naplňuje že to 2db8f54a-3a36-4e3c-8e1f-6ef781966d66 je opravdu UUID toho původního disku/raid1.
A co jsi to koupil za SSD a kde, ze odchazeji? Minimalne jako varovani pro ostatni, co chteji neco superlevne by to poslouzilo. Neni totiz typicke, ze budou odchazet dva nove disky zaroven. Podle popisu bych tipoval ze jde o fejky :D
Ano, nejspíš jde o fejky (napsáno je na nich Lenovo). Dostaly se ke mně podivnou cestou, ve které pravděpodobně figuroval nějaký čínský shop (ne že bych je tam kupoval), dostal jsem je jako bonus za nějakou protislužbu. Na nic důležitého bych je nepoužil. I tady jsem si to troufnul jen proto že jsem se (chybně) domníval, že jestli fakt chcípnou, tak se prostě jednoduše a snadno vrátím k původnímu páru.
No - chybama se člověk učí...
Teď jsem si to zkoušel v rychlosti nasimulovat. Byť bez RAID1 jen s jedním blok. zařízením (partišnou), co jsem pak vyměnil za jinou pomocí replace.
Podle všeho to opravdu odstraní jen magic (těch 8 bajtů), jakmile jsem v hex editoru zapsal zpátky řetězec "_BHRfS_M", co byl u mě na offsetu 0x10040 od začátku partišny (což odpovídá přesně tomu stack overflow), tak mi btrfs inspect-internal dump-super <device> hlásí i správný checksum superbloku. Připojení s -o ro,degraded pak jde a normálně si přečtu data.
Když jsem pak pustil btrfs inspect-internal dump-super -a <device>, tak mi vypsal i dekadický byte offset na začátek druhé kopie superbloku, v hexeditoru jsem poskočil dopředu o dalších 0x40, a opravil to také tam.
Normálně (bez -o degraded) se mi to připojovat nechtělo, ale v dmesg mi to napovědělo, že:
BTRFS warning (device nbd0p1): cannot mount because device replace operation is ongoing..
Tak jsem po připojení v degraded režimu zrušil replace (btrfs replace cancel <mountpoint>) a už se to připojuje standardně.
Snad se to povede i u vás. Tam mě jen trochu zaráží, že vám to pořád píše checksum failed.
Fakt moc oceňuji tu snahu pomoci. U mě je to nějaké složitější. BTRFS tvrdošíjně hlásí chybu superblock checksum a to na všech kopiích superblocku. Jsem si 100% jistý, že jsem na těch původních discích žádnou operaci nedělal, první operací poté co jsem zjistil že nejdou namountovat bylo dd do souboru na jiném disku a vše ostatní pak probíhalo až tam.
Že ale nějakou záchrannou operaci neudělal proaktivně za mými zády nějaký mountovací démon (Kubuntu), to už si tak úplně jistý nejsem...
Uvidím, celé to vlastně od začátku bylo myšleno jako trénink, rozšíření znalostí o BTRFS, to se tedy naplňuje měrou vrchovatou...
Jen update - as se někam blížím, jen tedy netuším kam. Zkusil jsem, ze zoufalství začít úplně odznovu, s novou bitovou kopií jednoho z těch původních disků (uloženou jako sda.img). Doběhl dd, pustil jsem na sda.img btrfs inspect-internal dump-super a dostal jsem:
btrfs inspect-internal dump-super --force --all sda.img
superblock: bytenr=65536, device=sda.img
---------------------------------------------------------
csum_type 0 (crc32c)
csum_size 4
csum 0x1d92253c [DON'T MATCH]
bytenr 65536
flags 0x1
( WRITTEN )
magic ........ [DON'T MATCH]
fsid 2db8f54a-3a36-4e3c-8e1f-6ef781966d66
metadata_uuid 00000000-0000-0000-0000-000000000000
label srv
generation 1598019
root 6673317888
sys_array_size 258
chunk_root_generation 1598019
root_level 1
chunk_root 67139272704
chunk_root_level 0
log_root 0
log_root_transid (deprecated) 0
log_root_level 0
total_bytes 246096592896
bytes_used 53234524160
sectorsize 4096
nodesize 16384
leafsize (deprecated) 16384
stripesize 4096
root_dir 6
num_devices 2
compat_flags 0x0
compat_ro_flags 0x0
incompat_flags 0x161
( MIXED_BACKREF |
BIG_METADATA |
EXTENDED_IREF |
SKINNY_METADATA )
cache_generation 1598019
uuid_tree_generation 1598019
dev_item.uuid f3793453-4d55-46eb-9388-e9e716178818
dev_item.fsid 2db8f54a-3a36-4e3c-8e1f-6ef781966d66 [match]
dev_item.type 0
dev_item.total_bytes 123048296448
dev_item.bytes_used 60196651008
dev_item.io_align 4096
dev_item.io_width 4096
dev_item.sector_size 4096
dev_item.devid 2
dev_item.dev_group 0
dev_item.seek_speed 0
dev_item.bandwidth 0
dev_item.generation 0
superblock: bytenr=67108864, device=sda.img
---------------------------------------------------------
csum_type 0 (crc32c)
csum_size 4
csum 0xbdf30df2 [DON'T MATCH]
bytenr 67108864
flags 0x1
( WRITTEN )
magic ........ [DON'T MATCH]
fsid 2db8f54a-3a36-4e3c-8e1f-6ef781966d66
metadata_uuid 00000000-0000-0000-0000-000000000000
label srv
generation 1598019
root 6673317888
sys_array_size 258
chunk_root_generation 1598019
root_level 1
chunk_root 67139272704
chunk_root_level 0
log_root 0
log_root_transid (deprecated) 0
log_root_level 0
total_bytes 246096592896
bytes_used 53234524160
sectorsize 4096
nodesize 16384
leafsize (deprecated) 16384
stripesize 4096
root_dir 6
num_devices 2
compat_flags 0x0
compat_ro_flags 0x0
incompat_flags 0x161
( MIXED_BACKREF |
BIG_METADATA |
EXTENDED_IREF |
SKINNY_METADATA )
cache_generation 1598019
uuid_tree_generation 1598019
dev_item.uuid f3793453-4d55-46eb-9388-e9e716178818
dev_item.fsid 2db8f54a-3a36-4e3c-8e1f-6ef781966d66 [match]
dev_item.type 0
dev_item.total_bytes 123048296448
dev_item.bytes_used 60196651008
dev_item.io_align 4096
dev_item.io_width 4096
dev_item.sector_size 4096
dev_item.devid 2
dev_item.dev_group 0
dev_item.seek_speed 0
dev_item.bandwidth 0
dev_item.generation 0
Jak já to čtu, tak tam našel 2 kopie superblocku (na třetí není místo, je to 128G disk), celkem smysluplně oba naplněné, nesouhasí
magic - očekávané a
csum - nevím ale to může být tím přepsaným magic. Celkem tedy docela nadějné.
Neudělám nic jiného než že přepíšu to
magic v obou superblocích:
echo "_BHRfS_M" | dd bs=1 count=8 of=sda.img seek=$((64*1024+64))
8+0 záznamů přečteno
8+0 záznamů zapsáno
8 bajtů zkopírováno, 0,000129285 s, 61,9 kB/s
echo "_BHRfS_M" | dd bs=1 count=8 of=sda.img seek=$((64*1024*1024+64))
8+0 záznamů přečteno
8+0 záznamů zapsáno
8 bajtů zkopírováno, 0,000323182 s, 24,8 kB/s
a dám znovu btrfs inspect-internal dump-super ať vidím, co jsem udělal. A co nevidím a svým očim nevěřím:
btrfs inspect-internal dump-super --force --all sda.img
superblock: bytenr=65536, device=sda.img
---------------------------------------------------------
csum_type 0 (crc32c)
csum_size 4
csum 0x1d92253c [DON'T MATCH]
bytenr 65536
flags 0x1
( WRITTEN )
magic _BHRfS_M [match]
fsid 2db8f54a-3a36-4e3c-8e1f-6ef781966d66
metadata_uuid 00000000-0000-0000-0000-000000000000
label
generation 0
root 0
sys_array_size 0
chunk_root_generation 0
root_level 0
chunk_root 0
chunk_root_level 0
log_root 0
log_root_transid (deprecated) 0
log_root_level 0
total_bytes 0
bytes_used 0
sectorsize 0
nodesize 0
leafsize (deprecated) 0
stripesize 0
root_dir 0
num_devices 0
compat_flags 0x0
compat_ro_flags 0x0
incompat_flags 0x0
cache_generation 0
uuid_tree_generation 0
dev_item.uuid 00000000-0000-0000-0000-000000000000
dev_item.fsid 00000000-0000-0000-0000-000000000000 [DON'T MATCH]
dev_item.type 0
dev_item.total_bytes 0
dev_item.bytes_used 0
dev_item.io_align 0
dev_item.io_width 0
dev_item.sector_size 0
dev_item.devid 0
dev_item.dev_group 0
dev_item.seek_speed 0
dev_item.bandwidth 0
dev_item.generation 0
ERROR: failed to read the superblock on sda.img at 67108864 read 72/4096 bytes
ERROR: error = 'Success', errno = 0
Tedy
magic v prvním superbloku už sedí, zato se z něj ztratila podstatná část dat, od
label dále. Druhý superblock zmizel úplně -
Citacefailed to read the superblock on sda.img at 67108864
Co to, sakra, je? dd dostal 8 znaků, tvrdí že zapsal 8 znaků, dokonce tam těch 8 znaků vidím na správném místě... Kam, sakra, zmizel ten zbytek superblocku a proč?
V tomto zápisu je něco prohnilého:
echo "_BHRfS_M" | dd bs=1 count=8 of=sda.img seek=$((64*1024+64))
Rychlý pokus:
dd bs=1 count=100000 if=/dev/zero of=sda.img
Velikost 100000B.
echo "_BHRfS_M" | dd bs=1 count=8 of=sda.img seek=$((64*1024+64))
Velikost 65608B ...
echo "_BHRfS_M" | dd bs=1 count=8 of=sda.img seek=$((64*1024+64)) conv=notrunc
Upřímně, při tom svém testu jsem to ani nezkoušel s dd. Skutečně to vypadá, že jste tam zapsal za magic i něco dalšího.
Mám normálně nainstalovaný program hexedit (https://rigaux.org/hexedit.html) bývá v balíčku skoro ve všech distribucích, ten jsem použil na úpravu toho magicu.
ctrl+g (goto na adresu, buď dekadicky, nebo hex s prefixem 0x), tab přepíná mezi editací hex a text (ascii), ctrl+x - save.
Pokud máte ještě původní data beze změny, tak bych se vrátil a zkusil upravit vyloženě těch 8 bajtů (offset 0x10040) jen na prvním superbloku, to by mělo stačit, aby se to připojilo v degraded režimu.
Jinak ještě k těmhle pokusům s nějaký opravami FS se hodí mít možnost se rychle vrátit a ideálně nezasahovat do původního disku. Není vždy praktické mít víc kopií celého disku v několika image souborech, zvlášť když to má třeba několik TB. Používám na to snapshoty device mapperu (udělá se virtuální zařízení a všechny změny jdou pak do samostatného souboru, který může být i sparse)
Viz:
https://unix.stackexchange.com/questions/67678/gnu-linux-overlay-block-device-stackable-block-device
Druhá možnost pro tohle je pak například používat qemu-nbd a image mít uložené jako qcow2 se snapshoty, což umožní větší flexibilitu, ale to je asi zbytečné rozjíždět, pokud s tím neděláte častěji.
Citace od: rmrf kdy 08. 11. 2024, 20:00:05
echo "_BHRfS_M" | dd bs=1 count=8 of=sda.img seek=$((64*1024+64)) conv=notrunc
conv=notrunc - no jasně, to je to co tomu chybělo! V tom původním návodu https://superuser.com/questions/1281942/recover-data-from-replaced-btrfs-disk (https://superuser.com/questions/1281942/recover-data-from-replaced-btrfs-disk) to nebylo a mě to netrklo.
Moc díky!
Finálně - původní disky vrácené, skříň zavřená a btrfs scrub spokojený.
Moc díky všem. Když si to projdu znovu od začátku je skvělé vidět kolik lidí se "seběhlo" aby mi pomohlo spravit rozbitý raid. Který jsem si navíc rozbil vlastní blbostí. Tak ještě jednou díky.
Pokud to čte někdo, kdo má podobný problém, tak nezapomeňte na
- Jestli chcete mít víc než jeden pokus, začněte tím, že si disk(y) někam zkopírujete
- Příkaz dd na přepsání magic string musí mít param conv=notrunc
- Až se vám to celé povede a disk se probudí, nezapomeňte na btrfs replace cancel <mountpoint> ;)
Jestli to dobře chápu, tak vlastně lepší by pro raid 1 mohlo být lepší ten disk prostě bez replace odpojit a pak vyřešit degraded stav, ne?
Ono asi device remove a device replace ve finále udělá na konec totéž. Leda to vzít opravdu doslova a prostě ho hw odpojit a btrfs nic neříkat, nechat ho ať si to přebere sám.
I když - tak jste to asi myslel.