Klasszikus rendszermentés unix sztori

2021-04-11

Elolvasni kb. 21 perc, de ez emberfüggő is.

Aktuális témáink:

Ez egy klasszikus történet Mario Wolczkotól, a Useneten először 1986-ban jelent meg, angolul elérhető pl. itt.

Előfordult már, hogy otthagytad lezáratlanul, bejelentkezve a terminálod, és arra tértél vissza, hogy egy barátod begépelte az rm -rf ~/ parancsot, és ott lebegtette a mutatóujját az ENTER felett, fenyegetőzve: „jobb ha kölcsönadsz egy ötezrest fizetésig, vagy…” Természetesen nem merné megnyomni, hisz miért is okozna ekkora traumát neked, csak viccelődne. Vagyis valószínűleg sosem voltál részese a legrosszabbnak ami történhet…

Egy csendes szerda délután történt – október elsején, 15:15-kor a brit nyári idő szerint, hogy pontosak legyünk –, hogy Peter, a munkatársam a idehajolt a termináljától, és azt mondta: „Mario, mintha gond lenne a mail-küldéssel.” Mivel tudtam, hogy a msg parancs könnyedén összezavarta még a hozzáértőket is, átsétáltam a termináljához hogy megnézzem mi a probléma. Egy furcsa hibaüzenetet láttam (a pontos szövegre nem emkékszem): „a /foo/bar nem elérhető a 147-s felhasználónak” ("cannot access /foo/bar for userid 147"). Az első gondolatom az volt: ki az a 147s felhasználó? A küldő? A címzett? Vagy ki? A másik, szintén bejelentkezett terminálhoz léptem, és beírtam:

grep 147 /etc/passwd

… hogy ezt a választ kapjam:

/etc/passwd: No such file or directory.

Azonnal arra gyanakodtam, hogy valami valóban nem stimmel, amit az is megerősített, hogy a

ls /etc

… kiadása után ezt a választ kaptam:

ls: not found.

Azt javasoltam Peternek, hogy jobb, ha most egy darabig semmivel sem próbálkozik, és elmentem megkeresni a menedzserünket.

Amikor az irodájához értem, az ajtaja nyitva volt, és tíz másodpercen belül rájöttem a probléma okára. Ott ült James, a managerünk, tenyerébe temetve az arcát, összegörnyedve, mint aki már csak a világ végére vár. A frissen kinevezett rendszer programozónk Neil állt mellete, a termináljára bámulva. A kijelző tetején pedig a következő sorok látszottak:

# cd
# rm -rf * 

A francba, ez sok mindent megmagyaráz” – gondoltam.

Már nem emlékszem, mi történt a következő néhány percben pontosan, egy kicsit homályosak a dolgok. Próbáltkoztam az lssel (újra), ps-vel, who-val, és még néhány más paranccsal, de sikertelenül. A következő amire emlékszem, hogy újra a saját terminálomnál ülök (egy több ablakos grafikus terminálnál), és begépelem:

cd /
echo * 

Elképesztően hálásak lehetünk David Korn-nak, hogy az echo beépített parancs a shell-jében, hisz a /bin a /bin/echo-val együtt hiányzott a törlés után. A következő néhány percben kiderült, hogy emellett hiányzott a teljes /dev, /etc és /lib könyvtár is, Neil körülbelül a /news és a /tmp törlése közben szakította félbe a törlést, így a /usr és a /users könyvtárak érintetlenek voltak.

Ezalatt James elért a szalagos mentéseinket tároló szekrényhez, és már hozta is a négy héttel korábbi teljes mentést. A kérdés már csak az volt: „Hogyan töltsük vissza a szalag tartalmát?” Hisz nem csak az /etc/restore veszett el, de az összes eszköz leíró is a /dev könyvtárban, ami a szalagos meghajtó kezeléséhez kell. És hol volt a mknod? Talált, süllyedt, az /etc alatt. Persze megpróbálhatnánl egy mentés-visszaállítást Ethernet hálózaton át egy másik működő VAX-ról … Azt leszámítva, hogy hiányzik a /bin/tar, és persze a Berkley rendszermérnökei az rcp-t is a /bin-ben tárolták a 4.3-s verzióban. Természetesen a hálózati elérés sem működne az /etc/hosts nélkül. Az /usr/local alatt találtunk egy cpio verziót, de a szalagos meghajtó nélkül nem sokra mennénk vele.

Megpróbálhatnánk a boot mentéssel újraépíteni a teljes root fájlrendszert, de sem James, sem Neil nem csinált még ilyent, és nem voltunk biztosak benne, hogy ez nem formázná újra a teljes lemezt, és így a még meglévő felhasználói fájlokat is elveszítenénk. (A felhasználók fájljairól csütörtökönként készült biztonsági mentés, Murphy törvénye miatt a katasztrófa természetesen szerdán történt.) Kivehetnénk egy másik VAX merevlemezét, bootolhatnánk arról, és rendet rakhatnánk, de ahhoz ki kellene hívni a DEC mérnökeit. Jó néhány felhasználónk épp a PhD-jét írja, és egy heti munkájuk elvesztése (nem is beszélve a kiesett gép-időről) elfogadhatatlan lett volna.

Szóval mit tehetünk? A következő ötlet az volt, hogy írjunk egy programot, ami létrehozza a szalagos-meghajtó eszközleíróját, de mind tudtok, hol található a cc, as és ld. Vagy létrehozhatnánk egy kezdetleges /etc/passwd-t, /etc/hosts-t és így tovább, amíg nem működne a /usr/bin/ftp. Szerencsénkre még mindig futott egy gnuemacs példány az egyik nyitott ablakomban, amiben létrehozhatjuk a fájlokat, de az első probléma az volt, hogy nem léteztek a könyvtárak amibe le kellene menteni őket: természetesen az mkdir is a /bin-nel együtt tünt el, akárcsak az mv, szóval mégcsak átnevezni sem tudtuk a /tmp-t /etc-re. Mindezek ellenére már közelebb voltunk a megoldáshoz.

Ekkora már csatlakozott hozzánk Alasdair, a helyi UNIX guru, aki – szerencsénkre – a VAX assemblerhez is értett. A tervünk ez volt: írjunk egy programot assemblerben egy másik VAXon, ami vagy át tudja nevezni a /tmp-t /etc-re vagy létrehozza az etc könyvtárat. A másik VAXon megírt program UUENCODE-lt verzióját begépeljük az emacsban, dekódoljuk (szerencsére egy ragyogó elme az uudecode bináris helyét az /usr/bin-be tervezte), lefuttatjuk és onnét már csak apróságok vannak hátra. Szerencsénkre a terminál, ahonnan a katasztrófa útjára indult, még mindig rootként volt bejelentkezve (hisz a su is elveszett a /bin-nel) így volt esélyünk rá, hogy működni fog!

Körülbelül egy órával később készen állt a pár tucat soros assembler ami létrehozza az /etc-t! A „lecsupaszított” bináris csak 76 byte volt, így hexadecimálásra konvertáltuk (könnyebben is olvasható mint az uuencode), és begépeltük a szövegszerkesztőmben. Ha valaha szükség lenne rá:

070100002c000000000000000000000000000000000000000000000000000000
0000dd8fff010000dd8f27000000fb02ef07000000fb01ef070000000000bc8f
8800040000bc012f65746300 

Persze volt kéznél egy ügyes kis programom (kinek ne lenne), hogy az ASCII hexadecimálist binárissá konverteljuk, és szerencsére a /usr/bin/sum szerint is egyeztek a fájlok. De várjunk csak… hogyan teszel egy fájlt végrehajthatóvá a /bin/chmod nélkül? Pár perc gondolkodás után arra jutottunk, hogy egyszerűen felül kell írnunk egy futtatható fájlt aminek én vagyok a tulajdonosa – és már mehettünk is a root terminálhoz. Beállítottuk az umask-t 0-ra, hogy én is létrehozhassak fájlokat, és lefuttattuk a programot. Most már volt /etc-nk, amit bárki írhatott. Már csak néhány lépés, és létrehoztuk a passwd-t, hosts-t, services-t, protocols-t és más szükséges fájlokat, és működött az ftp! Visszaállítottuk a /bin tartalmát a hálózaton keresztül – hihetetlen mennyire tud hiányozni az ls pár óra után –, és további fájlokat az /etc-ben. A legfontosabb persze az /etc/rrestore volt, aminek segítségével újra létrehoztuk a /dev-t a szalagos mentésről, a többi pedig már történelem…

Most persze megkérdezhetitek magatoktól (ahogy én is tettem), hogy mi a tanulság? Nos, először is, mindig jusson eszedbe ez az örök tanács: NE PÁNIKOLJ. Az első ötletünk a gép újraindítása volt, hogy mindent egy-felhasználós üzemmódban próbáljunk meg visszaállítani, de szinte biztos, hogy ez nem működött voltna az /etc/init és a /bin/sh nélkül – még szerencse, hogy átgondoltuk.

A következő, ami mindig jusson eszetekbe: a UNIXos eszközeket szokatlan dolgokra is lehet használni. Még gnuemacs nélkül is megoldhattuk voltna, mondjuk a /usr/bin/grep-t használva /bin/cat helyett.

És végül, elképesztő, hogy a rendszer milyen nagy része törölhető, anélkül, hogy teljesen szétesne. Azt leszámítva, hogy új felhasználó nem tudott bejelentkezni (hisz hiányzott a /bin/login), és hogy hiányzott néhány nagyon hasznos parancs, minden más normálisnak tünt. Persze néhány program nem működik /etc/termcap, /dev/kmem, vagy /etc/utmp nélkül, de a legtöbb igen!

Végül pedig egy kérdés: ha te lettél volna a helyünkben, az okos gondolataiddal, meg tudtad volna oldani egyszerűbben? Bátran küld el a válaszod:

Mario Wolczko
------------------------------------------------------------------------
Dept. of Computer Science       ARPA:   miw%uk.ac.man.cs.ux@cs.ucl.ac.uk
The University                  USENET: mcvax!ukc!man.cs.ux!miw
Manchester M13 9PL              JANET:  miw@uk.ac.man.cs.ux
U.K.                            061-273 7121 x 5699
------------------------------------------------------------------------

Hacker’s Wisdom: Unix Recovery Legend Last modified: Thu Mar 7 13:47:40 EST 1996