Eida.cz - Když stroj času přece spadne ze stolu

Když stroj času přece spadne ze stolu

13. května 2013, 14:01 Eida

Už po čtvrté. A přitom stokrát jinak. Na konci února jsem si tu vesele pochvaloval pravděpodobně stabilní stroj času díky změně vnitřní databáze na paměťově dočasnou a odděleným časovým kapsám. Přesto jsem tuhle v neděli ráno nahodil Mac a místo čerstvých novinek na Twitteru mě přivítala ta ošklivá hláška o chybě během kontroly záloh ve stroji času.

Ukázalo se, že nastavení zálohování je sice stabilní, ale síť sama o sobě není stavěna na přežívání vyššího vypadávání kabelů a různých bludných impulzů a podobně a kapsa se poškodila stejným způsobem, jako když se během zápisu z USB natvrdo vytrhne flashka. Což je sice fajn vědět, ale nic to neměnilo na tom, že byla časová kapsa poškozená a vidina ztráty záloh od samotného začátku roku nebyla prostě a jednoduše přijatelná.

Zajímavé je, jak se po Internetu povaluje spoustu návodů, jak časovou kapsu ošetřit a někteří takoví se dokonce nestydí pod svůj návod napaštit Donate tlačítko z PayPalu, přestože píší o kravinách a nikomu jejich text nepomůže. Je to proto, že tomu prostě nerozumí a jen opisují postupy získané kdesi jinde a pokaždé k nim ještě přidají kousek mýtu, mysterie a tajemna, aby udělali chudáky z nebohých čtenářů s poškozenými kapsami.

Co si tedy správně počít? Základem je vniknout do nastavení stroje času a vypnout automatické zálohy. Pak bych z různých jiných důvodů doporučil restartovat netatalk, co kdyby náhodou někde zůstalo viset nějaké pochybné spojení. Po restartu stačí připojit share obsahující kapsu a můžeme začít chrlit.

Čili jako první ze sebe pro pohodlí uděláme roota a připravíme si kapsu. Je velmi pravděpodobné, že se kapsa zamknula a je potřeba ji odemknout. Je velmi nedoporučeno to dělat v GUI ve Finderu, protože Finder začně zapisovat svoje metadata přímo do kapsy a může se tím pádem stát, že se kapsa z databázových důvodů třeba zřítí znovu.

attach.txt 308 bajtů
$ sudo su
sh-3.2# cd /Volumes
sh-3.2# chflags -R nouchg <share>/<kapsa>.sparsebundle
sh-3.2# hdiutil attach -nomount -noverify -noautofsck <share>/<kapsa>.sparsebundle
/dev/diskX          	GUID_partition_scheme          	
/dev/diskXs1        	EFI                            	
/dev/diskXs2        	Apple_HFS 
Odblokování a připojení kapsy

A tady to začíná být zajímavé, protože dojde k jevu, o kterém se ve výše zmíněných pseudovědeckých článcích běžně nedá dočíst. Utilitka hdiutil sice dostala parametry noverify a noautofsck, ale jako z čistého nebe přesto začne kapsičku na pozadí kontrolovat. Takže když běžný smrtelník zkusí použít další zaručený postup pro kontrolu, vypadne na něj hlášení, že je zamčený žurnál a kapsa je jen pro čtení. Čemuž stejně asi nerozumí a jde brečet na diskusní fóra.

no_write.txt 160 bajtů
sh-3.2# fsck_hfs -drfy /dev/diskXs2
Unable to open block device /dev/diskXs2: Resource busyjournal_replay(/dev/diskXs2) returned 16
** /dev/rdiskXs2 (NO WRITE)
Zablokovaný žurnál

Není nic snazšího, než tuto kontrolu prostě a jednoduše sestřelit, stejně by neudělala žádný užitek a pravděpodobně by mohla napáchat i další škody.

kill.txt 25 bajtů
sh-3.2# killall fsck_hfs
Konec automatické kontroly

Pak tedy můžeme onen postup vyzkoušet znovu. Za následek má mít přebudování B-tree katalogu (-r = -Rc) a opravu všech chyb, na které narazí (-y). Háček je v tom, že by bylo potřeba přidat ještě kontrolu přetoků (-Re) a možná i ztracených atributů (-Ra), jinak většina pokusů stejně skončí s brutální chybou:

fsck.txt 5.71 KiB
sh-3.2# fsck_hfs -drfy /dev/diskXs2
journal_replay(/dev/diskXs2) returned 0
** /dev/rdiskXs2
	Using cacheBlockSize=32K cacheTotalBlock=32768 cacheSize=1048576K.
   Executing fsck_hfs (version diskdev_cmds-557~393).
** Checking Journaled HFS Plus volume.
** Detected a case-sensitive volume.
   The volume name is Time Machine Backups
** Checking extents overflow file.
** Checking catalog file.
** Rebuilding catalog B-tree.
Extent records for rebuilt file 4:
	[ 24196, 4096 ]
	[ 458116, 293888 ]
	[ 26998827, 5096 ]
	[ 27030077, 6144 ]
	[ 1159799, 19848 ]
	[ 27135864, 128400 ]
	[ 0, 0 ]
	[ 0, 0 ]
hfs_UNswap_BTNode: invalid node height (1)
btree file 4:  1000 records
btree file 4:  2000 records
btree file 4:  3000 records
btree file 4:  4000 records
btree file 4:  5000 records
btree file 4:  6000 records
btree file 4:  7000 records
btree file 4:  8000 records
btree file 4:  9000 records
btree file 4:  10000 records
btree file 4:  11000 records
btree file 4:  12000 records
btree file 4:  13000 records
btree file 4:  14000 records
btree file 4:  15000 records
btree file 4:  16000 records
btree file 4:  17000 records
btree file 4:  18000 records
btree file 4:  19000 records
btree file 4:  20000 records
btree file 4:  21000 records
btree file 4:  22000 records
btree file 4:  23000 records
btree file 4:  24000 records
btree file 4:  25000 records
btree file 4:  26000 records
btree file 4:  27000 records
btree file 4:  28000 records
btree file 4:  29000 records
btree file 4:  30000 records
btree file 4:  31000 records
btree file 4:  32000 records
btree file 4:  33000 records
btree file 4:  34000 records
btree file 4:  35000 records
btree file 4:  36000 records
btree file 4:  37000 records
btree file 4:  38000 records
btree file 4:  39000 records
btree file 4:  40000 records
btree file 4:  41000 records
btree file 4:  42000 records
btree file 4:  43000 records
btree file 4:  44000 records
btree file 4:  45000 records
btree file 4:  46000 records
btree file 4:  47000 records
btree file 4:  48000 records
btree file 4:  49000 records
btree file 4:  50000 records
btree file 4:  51000 records
btree file 4:  52000 records
btree file 4:  53000 records
btree file 4:  54000 records
btree file 4:  55000 records
btree file 4:  56000 records
btree file 4:  57000 records
btree file 4:  58000 records
btree file 4:  59000 records
btree file 4:  60000 records
btree file 4:  61000 records
btree file 4:  62000 records
btree file 4:  63000 records
btree file 4:  64000 records
btree file 4:  65000 records
btree file 4:  66000 records
btree file 4:  67000 records
btree file 4:  68000 records
btree file 4:  69000 records
btree file 4:  70000 records
btree file 4:  71000 records
btree file 4:  72000 records
btree file 4:  73000 records
btree file 4:  74000 records
btree file 4:  75000 records
btree file 4:  76000 records
btree file 4:  77000 records
btree file 4:  78000 records
btree file 4:  79000 records
btree file 4:  80000 records
btree file 4:  81000 records
btree file 4:  82000 records
btree file 4:  83000 records
btree file 4:  84000 records
btree file 4:  85000 records
btree file 4:  86000 records
btree file 4:  87000 records
btree file 4:  88000 records
btree file 4:  89000 records
btree file 4:  90000 records
btree file 4:  91000 records
btree file 4:  92000 records
btree file 4:  93000 records
btree file 4:  94000 records
btree file 4:  95000 records
btree file 4:  96000 records
btree file 4:  97000 records
btree file 4:  98000 records
btree file 4:  99000 records
btree file 4:  100000 records
btree file 4:  101000 records
btree file 4:  102000 records
btree file 4:  103000 records
btree file 4:  104000 records
btree file 4:  105000 records
btree file 4:  106000 records
btree file 4:  107000 records
btree file 4:  108000 records
btree file 4:  109000 records
btree file 4:  110000 records
btree file 4:  111000 records
btree file 4:  112000 records
RebuildBTree - InsertBTreeRecord failed with err 5 0x05 
RebuildBTree - numRecords = 112569
RebuildBTree - record 15 in node 2454 is not recoverable. 

 xxxxxxxx BTreeKey (length 58) xxxxxxxx 
38 00 18 DD 00 00 19 00 64 00 61 00 74 00 61 00   8.......d.a.t.a.
6D 00 61 00 6E 00 61 00 67 00 65 00 6D 00 65 00   m.a.n.a.g.e.m.e.
6E 00 74 00 2E 00 70 00 72 00 6F 00 70 00 65 00   n.t...p.r.o.p.e.
72 00 74 00 69 00 65 00 73 00                     r.t.i.e.s.

 xxxxxxxx BTreeData (length 248) xxxxxxxx 
02 00 8E 00 00 00 00 00 19 DD 00 00 D9 C7 88 CB   ................
29 51 37 CC BB 48 13 CD BB 48 13 CD 00 00 00 00   )Q7..H...H......
00 00 00 00 50 00 00 00 00 00 A4 81 01 00 00 00   ....P...........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 50 ED 98 3B 00 00 00 00 00 00 00 00   ....P..;........
00 00 00 00 00 00 00 00 8B 00 00 00 00 00 00 00   ................
00 00 00 00 01 00 00 00 C9 9B 2B 00 01 00 00 00   ..........+.....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00   
** The volume Time Machine Backups could not be repaired.
	volume type is pure HFS+ 
	primary MDB is at block 0 0x00 
	alternate MDB is at block 0 0x00 
	primary VHB is at block 2 0x02 
	alternate VHB is at block 1535795198 0x5b8a5ffe 
	sector size = 512 0x200 
	VolumeObject flags = 0x07 
	total sectors for volume = 1535795200 0x5b8a6000 
	total sectors for embedded volume = 0 0x00 
CheckHFS returned 8, fsmodified = 1
Typická kontrola se selháním

Je to sice osvědčená magie, ale nechápu, proč se všude říká, že by se neměla pouštět grafická Disk Utility, která tohle umí na jedno kliknutí udělat sama a především to udělá víceprůchodově, což by v CLI sice vypadalo krutopřísně a hackersky, ale vzhledem k tomu, že tenhle proces klidně zabere hodiny (a ukousne si celé gigabajty paměti), je lepší to nechat přechroupat automaticky. Jedinou podmínkou je ovšem nemít kapsu přimountovanou.

Ať už se v kapse stalo cokoliv, Disk Utiliy pravděpodobně chyby našla a napravila, takže kapsu můžeme odpojit, zavřít spojení se serverem a pro další stupeň jistoty úplně zastavit netatalk a jít udělat poslední zbývající změny, které se týkají vnitřního uspořádání stavu kapsy v kořenu jejího .sparsebundle.

plist.txt 208 bajtů
# com.apple.TimeMachine.MachineID.plist

# smazat
<key>RecoveryBackupDeclinedDate</key>
<date>2013-01-02T03:04:05Z</date>

<key>VerificationState</key>
# a VerificationState upravit na 1
<integer>1</integer>
Modifikace vnitřního stavu kapsy

Otázkou je, co udělat s přeskočením verifikace, ale ono je prostě možná lepší nechat to zkontrolovat vícekrát, než aby se někde stala další fatální chyba. Po opětovném nahození serveru a zapnutí automatických záloh lze případnou dlouhotrvající verifikaci beztak zrušit.

Pokud z tohoto plyne nějaké poučení, pak je to zjištění, že sebelépe nastavevené kapsy, i kdyby plavaly na ZFS, nemohou odolat úplně všem síťovým chybám a masivnímu rušení. A taky to, že lidi stejně nečtou a pokud tomu nerozumí, tak asi dobře jim tak.

Eida
Tento článek přečetlo již 364 čtenářů (0 dnes).

Komentáře

Nový komentář