Linux Ext2fs Undeletion mini-HOWTO

Autor: Aaron Crane aaronc@poboc.com
v1.3, 2 lutego 1999
Wersja polska: Bartosz Sawicki sawickib@ee.pw.edu.pl
v1.0, 15 kwietnia 1999


Wyobraź sobie. Trzy ostatnie trzy dni spêdziłeś bez snu, jedzenia, a nawet bez prysznica. Właśnie ukoñczyłeś program, który przyniesie Ci światową sławê i uznanie. Musisz go jeszcze tylko starowaæ i umieściæ na Metalab-ie. No, i skasowaæ wszystkie kopie zapasowe tworzone przez Emacs-a. Piszesz wiêc rm * ~. Już za późno, zauważyłeś dodatkową spacjê w poleceniu. Właśnie skasowałeś całe swoje dzieło ! Nadchodzi pomoc. Dokument ten wyjaśnia jak odzyskiwaæ skasowane pliki w systemie plików Second Extended File System. Może uda Ci siê jednak opublikowaæ Twój genialny program. Dokument ten został napisany w standardzie ISO-8859-2. Oryginał tego dokumentu znajduje siê pod adresem http://pobox.com/~aaronc/.

1. Wstêp

To mini-Howto stara siê dostarczyæ porad jak odzyskiwaæ skasowane pliki w systemie plików ext2. Zawiera ono również dyskusjê, jak przede wszystkim, nie dopuściæ do skasowania ważnych plików.

Chciałbym, aby było ono przydatne dla ludzi, którym zdarzył siê mały wypadek z rm; jakkolwiek mam również nadziejê, że przeczytają je także inni. Nigdy nie wiadomo, pewnego dnia, któraś z zamieszczonych tu informacji z może uratowaæ Ci tyłek.

Tekst ten zakłada ogólną podstawową wiedzê o systemie plików UNIX-a. Mam jednak nadziejê, że bêdzie dostêpny dla wiêkszości użytkowników Linux-a. Jeśli jesteś całkowicie początkujący, obawiam siê, że odzyskiwanie plików wymaga ilości wiedzy technicznej, której nie posiadasz.

Nie bêdziesz mógł odtwarzaæ skasowanych plików z systemu plików ext2 bez praw odczytu do urządzenia, na którym były one przechowywane. Ogólnie oznacza to, że musisz byæ administatorem (root). Niektóre dystrybucje (takie jak Debian GNU/Linux) tworzą grupê disk, której członkowie mają dostêp do takich urządzeñ. Bêdziesz potrzebował także debugfs z pakietu e2fsprogs. Prawdopodobnie jest on już zainstalowany przez Twoją dystrybucjê.

Dlaczego to napisałem? Wynikło to głównie z moich własnych doświadczeñ ze zwykłą głupotą i katastrofą spowodowaną przez komendê rm -r wykonywaną z prawami administratora. Skasowałem 97 plików typu JPEG, których potrzebowałem i których prawie na pewno nie można było odzyskaæ z innych źrodeł. Z pomocą użytecznych wskazówek (patrz rozdział Wyrazy uznania i Bibliografia) i dużej wytrwałości, odzyskałem 91 nieuszkodzonych plików. Udało mi siê odtworzyæ czêściowo nastêpne piêæ (wystarczająco, aby zobaczyæ co było na tych obrazkach). Tylko jednego nie byłem w stanie obejrzeæ, ale nawet w tym przypadku, jestem prawie pewien, ze stracone zostały nie wiecej niż 1024 bajty (niefortunnie z samego poczatku pliku; uwzglêdniając to, że nic nie wiem o formacie JPG, zrobiłem wszystko co mogłem).

W dalszych rozważaniach bêdê chciał przedstawiæ jakiej wielkości współczynnika odtworzenia skasowanych plików możesz siê spodziewaæ.

1.1 Historia publikacji

Istnieją nastêpujące upublicznione wersje tego dokumentu (i daty ich publikacji):

Zmiany w wersji 1.1

Jakie zmiany zostały zrobione w tej wersji? Przede wszystkim, został poprawiony błąd w przykładowym odzyskiwaniu pliku. Dziêkujê wszystkim, którzy napisali, żeby wskazaæ mi ten błąd. Mam nadziejê, że nauczyłem siê byæ bardziej uważnym przy interakcyjnej pracy z programem.

Po drugie, rozważania o systemie plików w UNIX-ie zostały przerobione tak, aby uczyniæ je bardziej zrozumiałymi. Od początku nie byłem z tego zadowolony i dostałem komentarze, że nie było to napisane zbyt jasno.

Po trzecie, uuencode'owany gzip-owany tar-owany pakiet fsgrab ze środka pliku został usuniêty. Teraz program dostêpny jest na mojej stronie domowej i na Metalab-ie (i kopiach, w Polsce - Sunsite ).

Po czwarte, dokument ten został przetłumaczony na jêzyk składu SGML używany w Linux Documention Project. Ten jêzyk może byæ łatwo konwertowany do innych jêzyków składu (np. HTML-a i LaTeX-a) w celu dogodnego sposobu wyświetlania i drukowania. Jedną z korzyści z tego jest to, że ładny wygląd wersji papierowej jest łatwiejszy do osiągniecia. Inną jest to, że dokument zawiera wewnêtrzne i zewnêtrzne odnośniki, gdy oglądany jest przez WWW.

egil@kvaleberg.no, który wskazał na polecenie dump w debugfs. Jeszcze raz, dziêki Egil. Druga zmiana polegała na zaznaczeniu, że użycie chattr pomaga uniknąæ skasowania ważnych plików. Dziekujê Hermanowi Suijs H.P.M.Suijs@kub.nl za zauważenie tego. Streszczenie zostało uaktualnione. Zostały dodane URL-e do organizacji i oprogramowania. Wprowadzono wiele innych mniejszych zmian (literówki i tym podobne).

Zmiany w wersji 1.3

Pomimo, że jest to pierwsza wersja od 17 miesiêcy, jest tutaj mało nowego. W wersji tej poprawione są drobniejsze błêdy (literówki, puste URL-e, tego typu rzeczy -- szczególnie nie związane z Open Group), uaktualniono kilka czêści tekstu, które uległy przeterminowaniu, takich jak partie dotyczące wersji jądra i lde. No i zmieniłem `Sunsite' na `Metalab'.

To wydanie jest przewidywane jako ostatnie przed wersją 2.0, która, mam nadziejê, bêdzie pełnym Howto. Pracujê nad istotnymi zmianami, które spowodują zwiêkszenie głównego numeru wersji.

1.2 Inne lokalizacje tego dokumentu

Najnowsza publiczna wersja tego dokumentu powinna byæ zawsze dostêpna na Linux Documentation Project site (i kopiach, w Polsce - Sunsite ).

Najbardziej aktualna wersja jest również przechowywana na mojej stronie domowej w kilku formatach:

2. Jak nie skasowaæ plików

Trzeba pamiêtaæ, że Linux różni siê od MS-DOS jeśli chodzi o kasowanie plików. W MS-DOS (jak i w Windows 95), dosyæ łatwo jest odzyskaæ skasowane pliki - `system operacyjny' (używam tego terminu dosyæ swobodnie) dostarcza nawet narzêdzi, które automatyzują ten proces. W Linux-ie jest inaczej.

Reguła numer jeden (podstawowa wskazówka) brzmi:

RÓB KOPIE ZAPASOWE

bez wzglêdu na wszystko. Pomyśl o wszystkich swoich danych. Byæ może, jak ja, trzymasz kilkuletni zbiór listów, kontaktów, programów, dokumentów na swoim komputerze. Pomyśl co by siê stało z Twoim życiem, gdyby Twój dysk uległ katastrofalnemu uszkodzeniu, lub gdyby -- o wielkie nieba ! -- złośliwy craker wyczyścił Twój dysk. To nie jest niemożliwe; korespondowałem z wieloma ludźmi w takiej sytuacji. Myślê, że teraz wszyscy rozsądnie myślący użytkownicy Linux-a wyjdą, kupią urządzenie do robienia kopii zapasowych, opracują kalendarz archiwizacji i bêdą siê jego trzymaæ. Ja używam wolnego dysku twardego w innym komputerze i okresowo kopiujê tam przez sieæ ethernet mój katalog domowy. Wiêcej informacji o planowaniu kalendarza archiwizacji znajdziesz u Frischa (1995) (patrz rozdział Bibliografia i Wyrazy Uznania).

Co wtedy, gdy nie ma kopii zapasowej? (lub nawet przy istnieniu kopii zapasowej: żadne środki bezpieczeñstwa nie są złym rozwiązaniem w miejscu gdzie przechowywane są ważne dane).

Spróbuj ustawiæ prawa dostêpu do ważnych plików na 440 (lub mniej): odebranie sobie samemu praw zapisu oznacza, że rm bêdzie wymagał potwierdzenia przed skasowaniem. (Zauważyłem, że jeśli rekursywnie kasujê katalog rm -r, prośba potwierdzenia pojawi siê przy pierwszym i drugim pliku, potem program zachowuje siê jak rm -rf).

Niezłą sztuczką dla wybranych plików jest utworzenie w ukrytym katalogu twardych dowiązañ do nich. Kiedyś usłyszałem historiê o administatorze, który przez pomyłkê skasował /etc/passwd (nieomal w ten sposób niszcząc system). Jednym z rozwiązañ takiego kłopotu jest zrobienie czegoś nastêpującego (jako root):

# mkdir /.backup
# ln /etc/passwd /.backup

Teraz skasowanie pliku wymaga wiêkszego wysiłku: gdy napiszesz tylko

# rm /etc/passwd

wtedy

# ln /.backup/passwd /etc

odtworzy Twój plik. Oczywiście, to rozwiązanie nie pomoże jeśli nadpiszesz plik, wiêc nie zapomninaj o kopii zapasowej.

W systemie plików ext2 jest możliwe użycie atrybutów ext2, aby ochraniaæ pliki. Atrybuty te mogą byæ zmieniane za pomocą komendy chattr. Istnieje atrybut `append-only`: plik z tym atrybutem może byæ tylko powiêkszany, nie może byæ skasowany i istniejąca zawartośæ nie może byæ nadpisana. Jeśli atrybut ten ma katalog, każdy plik czy katalog w nim leżący może byæ normalnie modyfikowany, ale żaden z plików nie może zostaæ skasowany. Atrybut `append-only' ustawia siê poleceniem

$ chattr +a FILE...

Istnieje również atrybut `immutable', który może byæ zapalany lub gaszony tylko przez administratora. Pliku lub katalogu z tym atrybutem nie można zmienieniæ, skasowaæ, zmieniæ jego nazwy, czy utworzyæ do niego twardego dowiązania. Można go ustawiæ w nastêpujący sposób:

# chattr +i FILE...

Ext2fs dostarcza również atrybutu `undeletable' (+u in chattr). Założenie było takie, że plik z tym atrybutem po skasowaniu zostaje przeniesiony w bezpieczne miejsce `safe location', aby rzeczywiste skasowanie przesunąæ w czasie. Niestety funkcja ta nie jest jeszcze zaimplementowana w jądrze. Myślałem, że bêdzie wiêksze zainteresowanie nią i stanie siê to szybko, ale nie jest ona dostêpna (według mojej wiedzy) w żadnej aktualnej wersji jądra.

Niektórzy radzą, aby zrobiæ alias lub funkcjê w powłoce rm, która wykonywałaby rm -i (bêdziesz musiał potwierdziæ skasowanie każdego pliku). Dystrubucja Red Hat robi to domyślnie dla wszystkich użytkowników, w tym i dla root-a. Ja osobiście nie lubiê oprogramowania, które nie może działaæ bez mojej pomocy, dlatego nie używam tego sposobu. Wcześniej, czy później może pojawiæ siê kolejny problem: kiedy bêdziesz pracował w trybie singe-user, lub bêdziesz używał innej powłoki lub nawet innej maszyny, gdzie Twoja funkcja rm nie istnieje. Jeśli bêdziesz spodziewał siê, że każde skasowanie wymaga potwierdzenia, dosyæ łatwo jest nie przewidzieæ tego, że kazałeś skasowaæ zbyt wiele plików. Również skrypty i programy, które podmieniają rm mogą byæ bardzo niebezpieczne.

Trochê lepszym rozwiązaniem jest użycie pakietu, który umożliwia `odtwarzalne' kasowanie poprzez specjalną komendê zastêpująca rm. Szczegóły znajdziesz u Peeka (1993) (patrz rozdział Bibliografia i Wyrazy Uznania). Jednak w ten sposób przyzwyczajamy użytkownika do pewniej nonszalancji przy kasowaniu plików. Nie jest to najlepsze, bowiem system typu Unix wymaga jednak uważnego działania.

3. Jakiego współczynnika odzyskania skasowanych plików mogê siê spodziewaæ ?

To zależy. Problem wynika z tego, że w systemie operacyjnym wysokiej jakości, wielozadaniowym, wieloużytkownikowym, takim jak Linux, nie możesz przewidzieæ kiedy ktoś zechce zapisaæ coś na dysk. Po chwili, w której kazałeś systemowi skasowaæ jakiś plik, bloki przez niego zajête mogą zostaæ użyte, gdy system bêdzie chciał zapisaæ coś nowego. (Jest to jeden przykład ogólnej zasady systemów typu Unix: jądro i związane z nim programy zakładają, że użytkownicy nie są idiotami). Ogólnie rzecz biorąc, im bardziej obciążona jest Twoja maszyna, tym mniej prawdopodobne jest odzyskanie plików.

Znaczenie może mieæ również fragmentacja dysku. Jeśli partycja, na której był skasowany plik jest bardzo pofragmentowana, masz małe szanse na odczytanie całej jego treści.

Jeśli Twój komputer, tak jak mój, realnie jest maszyną jednoużytkownikową i nie robiłeś niczego co intensywnie korzystało z dysku w tragicznej chwili skasowania pliku, możesz siê spodziewaæ współczynnika odzysku zbliżonego do tego wymienionego niżej. Ja odzyskałem prawie 94% plików (były to pliki binarne) w stanie nieuszkodzonym. Jeżeli otrzymasz 80% lub wiêcej, myślê, że bêdziesz z siebie zadowolony.

4. Jak odzyskaæ skasowane pliki ?

Operacja ta polega głównie na znalezieniu danych na urządzeniu partycji i uczynieniu ich ponownie widocznymi dla systemu operacyjnego. Są dwa sposoby, żeby to zrobiæ: pierwszy polega na takiej zmianie systemu plików, żeby usunąæ znacznik `deleted' ze skasowanych iwêzłów z nadzieją, że pliki nagle pojawią siê na swoim miejscu. Inną metodą, bezpieczniejszą, ale wolniejszą jest znalezienie położenia interesujących danych na partycji i zapisaniu ich jako nowy plik w innym systemie plików.

Przed odtwarzeniem danych musisz zrobiæ kilka rzeczy; patrz rozdziały Odmontowanie systemu plików, Przygotowanie do bezpośrednich zmian w iwêzłach i Przygotowanie do zapisania danych w innym miejscu. Informacjê jak odzyskiwaæ pliki znajdziesz w rozdziałach Szukanie skasowanych iwêzłów, Uzyskiwanie szczegółowych informacji o iwêzłach, Odzyskiwanie bloków danych i Bezpośrednie modyfikacje iwêzłów.

5. Odmontowanie systemu plików

Niezależnie od metody jaką wybrałeś, pierwszym krokiem jest odmontowanie systemu plików zawierającego skasowane pliki. Zdecydowanie nie polecam żadnych działañ na zamontowanym systemie plików. Krok ten powinien byæ wykonany najszybciej jak to bêdzie możliwe od momentu, gdy zauważyłeś, że pomyłkowo skasowałeś pliki. Im szybciej odmontujesz system plików, tym wiêksza bêdzie szansa, że Twoje dane nie zostaną nadpisane (zamazane).

Najprostszą metodą, aby to zrobiæ jest: zakładając, że skasowane pliki były systemie plików /usr,

# umount /usr

Jeśli chcesz możesz również utrzymaæ widocznośæ katalogu /usr. Zamontuj go w trybie tylko-do-odczytu:

# mount -o ro,remount /usr

W przypadku, gdy skasowane pliki były na głównej partycji musisz dodaæ opcjê -n, aby zabroniæ programowi mount na próby zapisu do /etc/mtab:

# mount -n -o ro,remount /

Poza tym wszystkim, możliwe jest również, że jakiś inny proces używa interesującego nas systemu plików (spowoduje to błąd typu `Resource busy' przy próbie odmontowania). fuser jest programem, który wyśle sygnał do każdego procesu używającego wskazanego pliku lub punktu montowania. Spróbuj tego dla partycji /usr:

# fuser -v -m /usr

W ten sposób uzyskasz listê przeszkadzających Ci procesów. Zakładając, że żaden z nich nie jest niezbêdny, możesz napisaæ

# fuser -k -v -m /usr

aby wysłaæ sygnał SIGKILL do każdego z nich ( gwarantuje to ich zabicie), albo

# fuser -k -TERM -v -m /usr

aby przekazaæ każdemu sygnał SIGTERM (spowoduje to normalne zakoñczenie pracy procesów).

6. Przygotowanie do bezpośrednich zmian iwêzłów

Moja rada? Nie używaj tej metody. Nie uważam, żeby dobrym pomysłem była zabawa na niskim poziomie w systemie plików. Metoda ta stwarza również problemy jeśli chcesz odtworzyæ pliki wiêksze niż 12 bloków. W celu odzyskania dużych plików, tak czy owak, bêdziesz musiał użyæ innej metody. (Chociaż patrz rozdział Czy bêdzie to kiedyś łatwiejsze? w celu dodatkowych informacji.)

Jeżeli jednak chcesz koniecznie użyæ tego sposobu, lepiej skopiuj bezpośrednio obraz partycji na inną partycjê, a później zamontuj ją używając pêtli zwrotnej (loopback):

# cp /dev/hda5 /root/working
# mount -t ext2 -o loop /root/working /mnt

(Niektóre wersje mount nie potrafią tego zrobiæ. Jeśli Twój mount nie działa poprawnie, zalecam użycie najnowszej wersji, conajmniej 2.7. Dużo starsze wersje mają problemy z utrzymaniem bezpieczeñstwa danych.)

Używając pêtli zwrotnej, nawet jeśli całkowicie zniszczysz system plików, możesz ponownie skopiowaæ partycjê i zacząæ próby od nowa.

7. Przygotowanie do zapisu danych w innym miejscu

Jeżeli wybierzesz tê drogê działania, musisz znaleźæ partycjê ratunkową -- miejsce, gdzie zapiszesz nowe kopie odzyskanych plików. Na całe szczêście, twój system zawiera kilka partycji: prawdopodobnie partycjê główną, /usr i /home. Wybierz jedną z nich i utwórz na niej nowy katalog.

Jeśli masz tylko partycjê główną i wszystko przechowujesz na niej, rozwiązanie troszkê siê skomplikuje. Może masz partycje MS-DOS lub Windows, której bedziesz mógł użyæ ? Albo masz sterownik do ramdisk-u w swoim jądrze, albo w module ? W celu użycia ramdisk-u (zakładając, że jądro jest nowsze od 1.3.48), napisz:

# dd if=/dev/zero of=/dev/ram0 bs=1k count=2048
# mke2fs -v -m 0 /dev/ram0 2048
# mount -t ext2 /dev/ram0 /mnt

W ten sposób stworzyłeś 2MB wolumen ramdisk-u i zamontowałeś do w /mnt.

Krótkie ostrzeżenie: jeżeli używasz kerneld (lub zastêpującego go kmod w jądrach 2.2.x i późnych 2.1.x) w celu automatycznego ładowania i odładowywania modułów, nie odmontowuj ramdisk-u dopóki nie skopiujesz wszystkich plików na bardziej trwały nośnik. W chwili, gdy go odmontujesz, kerneld zakłada, że może odładowaæ moduł (zwykle jednak czeka pewien okres). Gdy to już siê stanie, pamiêæ zostanie użyta przez inne czêści jądra i stracisz wszystkie godziny spêdzone na odzyskiwaniu danych.

Jeżeli masz napêd Zip, Jaz, LS-120 lub coś podobnego, może on spełniaæ z powodzeniem rolê partycji ratunkowej. W pozostałych przypadkach, użyj po prostu napêdu stacji dyskietek.

Bêdziesz jeszcze potrzebował programu, który potrafi czytaæ dane ze środka partycji. Właściwie może to zrobiæ dd, ale aby przeczytaæ dane leżące od 600 MB do 800 MB, dd musi przeczytaæ i zignorowaæ pierwsze 600 MB. Zajmuje to dosyæ dużo czasu, nawet na szybkich dyskach. Moim sposobem na obejście tego problemu było napisanie programu, który przeskakuje w środek partycji. Nazywa siê on fsgrab; pakiet ze źródłem możesz znaleźæ na mojej stronie domowej lub na Metalab-ie (i kopiach, w Polsce - Sunsite ). Jeśli bêdziesz chciał stosowaæ tê metodê, w dalszej czêści tego mini-JTZ zakładam, że masz fsgrab.

Nie potrzebujesz fsgrab-a, jeżeli żaden z plików, które starasz siê odzyskaæ, nie zajmuje wiêcej niż 12 bloków (przeważnie blok ma rozmiar jednego kilobajta).

Jeżeli musisz użyæ fsgrab-a, ale nie chce Ci siê go ściągaæ i kompilowaæ, jest też prosta droga na przetłumaczenie polecenia dla fsgrab na polecenie dla dd. Mając

fsgrab -c count -s skip device

możesz użyæ komendy dd (przeważnie jest to dużo wolniejsze)

dd bs=1k if=device count=count skip=skip

Muszê Ciê ostrzec, że chociaż dla mnie fsgrab działa doskonale, nie mogê braæ odpowiedzialności za jego funkcjonowanie. Pisałem go dosyś szybko i niestarannie, po prostu, aby działał poprawnie. Wiêcej szczegółów o gwarancji znajdziesz w rozdziale `No Warranty' w pliku COPYING dołaczonym do pakietu (the GNU General Public Licence).

8. Szukanie skasowanych iwêzłów

Nastêpnym krokiem jest odnalezienie w systemie plików tych iwêzłów, które zostały ostanio uwolnione. Do tego zadania użyjemy programu debugfs. Uruchom debugfs z nazwą urządzenia, na którym przechowywany jest system plików:

# debugfs /dev/hda5

Jeżeli chcesz bezpośrednio wprowadzaæ zmiany do iwêzłów, dodaj opcjê -w, aby umożliwiæ zapisywanie do systemu plików:

# debugfs -w /dev/hda5

lsdel jest poleceniem debugfs, które wyszukuje skasowane iwêzły. Po zachêcie programu, napisz wiêc:

debugfs:  lsdel

Po chwili świergotania dysku, długa lista zostanie przekierowana do Twojego ulubionego łamacza na strony (ang. pager) (wartośæ zmiennej $PAGER). Powinienneś zachowaæ gdzieś kopiê tej listy. Jeżeli używasz less, możesz po prostu napisaæ -o i nazwê pliku wyjściowego. W innym razie, bêdziesz musiał przesłaæ wyniki do pliku w inny sposób. Spróbuj czegoś takiego:

debugfs:  quit
# echo lsdel | debugfs /dev/hda5 > lsdel.out

Teraz, tylko na podstawie czasu skasowania, rozmiaru, praw własności i właściciela musisz określiæ, które iwêzły należały do skasowanych plików. Bêdzie to prawdopodobnie proste zadanie jeśli wypadek przydarzył siê 5 minut temu, jeśli nie, przeszukaj listê bardzo uważnie.

Polecam wydrukowanie sobie listy iwêzłów, które chcesz odzyskaæ. Ułatwi Ci to dalszą pracê.

9. Uzyskiwanie szczegółowych informacji o iwêzłach

debugfs dysponuje poleceniem stat, które wyświetla szczegółowe informacje o iwêźle. Wykonaj tê komendê dla wszystkich iwêzłów, które chcesz odzyskaæ. Na przykład, jeżeli interesuje Ciê iwêzeł o numerze 148003, napisz tak:

debugfs:  stat <148003>
Inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
User:   503   Group:   100   Size: 6065
File ACL: 0    Directory ACL: 0
Links: 0   Blockcount: 12
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
594810 594811 594814 594815 594816 594817
TOTAL: 6

Gdy chcesz odzyskaæ wiele plików, dobrze bêdzie jak zautomatyzujesz ten proces. Przy założeniu, że Twoja lsdel lista interesujących iwêzłów znajduje siê w pliku lsdel.out, napisz coś takiego:

# cut -c1-6 lsdel.out | grep "[0-9]" | tr -d " " > inodes

Nowy plik inodes zawiera tylko numery iwêzłówm, które chcesz odzyskaæ, po jednym w jednej linii. Zapisaliśmy to, bowiem później bardzo nam siê przyda. Potem piszesz po prostu:

# sed 's/^.*$/stat <\0>/' inodes | debugfs /dev/hda5 > stats

i plik stats zawiera wyniki wszystkich poleceñ stat.

10. Odzyskiwanie bloków danych

Ta czêśæ jest albo bardzo łatwa, albo trudna, w zależności od tego, czy plik który chcesz odzyskaæ zajmował wiêcej niż 12 bloków.

10.1 Małe pliki

Jeżeli plik ma mniej niż 12 bloków, numery wszystkich bloków, które on zajmuje zapisane są w jednym iwêźle. Możesz odczytaæ je po wykonaniu polecenie stat dla tego iwêzła. Ponadto, w debugfs jest polecenie, które automatycznie odzyskuje taki plik. Weźmy ten sam przykład co poprzednio:

debugfs:  stat <148003>
Inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
User:   503   Group:   100   Size: 6065
File ACL: 0    Directory ACL: 0
Links: 0   Blockcount: 12
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
594810 594811 594814 594815 594816 594817
TOTAL: 6

Plik ten zajmuje sześæ bloków. Ponieważ jest to mniej niż 12, możemy użyæ debugfs, aby zapisaæ plik w nowym miejscu, na przykład /mnt/recovered.000:

debugfs:  dump <148003> /mnt/recovered.000

Oczywiście można to zrobiæ również, posługując siê fsgrab. Pokażê jak wygląda takie przykładowe wywołanie:

# fsgrab -c 2 -s 594810 /dev/hda5 > /mnt/recovered.000
# fsgrab -c 4 -s 594814 /dev/hda5 >> /mnt/recovered.000

Zarówno przy korzystaniu z debugfs jak i fsgrab, na koñcu pliku /mnt/recovered.000 pozostaną śmieci. Nie ma to wiêkszego znaczenia. Łatwo można siê ich pozbyæ. Najprostszą metodą jest odczytanie pola Size w iwêźle i wpisanie tej wartości za opcją bs komendy dd:

# dd count=1 if=/mnt/recovered.000 of=/mnt/resized.000 bs=6065

Może siê okazaæ, że jeden lub wiêcej z bloków zostało straconych, bowiem zostały już nadpisane. Jeżeli tak bêdzie, po prostu nie miałeś szczêścia: bloki te odeszły już na zawsze. (Wybraź sobie, że odmontowałeś je wcześniej!)

10.2 Wiêksze pliki

Problem pojawia siê, gdy plik zajmuje wiêcej niż 12 bloków danych. Przypadek ten wymaga pewnej wiedzy o tym jak zbudowany jest system plików UNIX-a. Dane pliku przechowywane są w jednostkach zwanych `blokami'. Bloki te są numerowane sekwencyjnie. Każdy plik ma również `iwêzeł', w którym przechowywane są informacje typu: właściciel, prawa dostêpu i typ. Podobnie jak bloki, iwêzły są numerowane sekwencyjnie, chociaż mają one różne numeracje. Pozycja w katalogu odpowiadająca plikowi składa siê z jego nazwy i numeru iwêzła.

Jednak na postawie tych informacji jądro nie jest jeszcze w stanie odnaleźæ na partycji danych odpowiadających jednej z pozycji w katalogu. Żeby to umożliwiæ, iwêzeł przechowuje położenia bloków danych zajmowanych przez plik. Zorganizowane jest to w nastêpujący sposób:

Przeczytaj to jeszcze raz: wiem, że to jest skomplikowane, ale bardzo ważne.

Niestety wszystkie implementacje jądra, aż do wersji 2.0.36 podczas kasowania pliku zerują bloki pośrednie (podwójnie pośrednie, itd.). Jeśli Twój plik jest wiêkszy niż 12 bloków, nie masz gawarancji, że bêdzie możliwe odnalezienie numerów wszystkich jego bloków, nie mówiąc już nic o ich zawartości.

Jedyną metodą jaką udało mi siê znaleźæ, jest oparcie siê na założeniu, że plik nie był pofragmentowany. Jeżeli był, masz poważny problem. Zakładając, że plik nie był pofragmentowany, istnieje kilka sekcji bloków danych, w zależności od tego ile bloków danych zajmuje plik:

0 do 12

Numery bloków przechowywane są w iwêźle, jak to było opisane wcześniej.

13 to 268

Po blokach bezpośrednich, odlicz jeden na blok pośredni, dalej znajduje siê 256 bloków danych.

269 do 65804

Tak jak poprzednio jest: 12 bezpośrednich bloków, (nieprzydatny) blok pośredni i 256 bloków. Po tym wszystkim nastêpuje (nieprzydatny) podwójnie pośredni blok oraz 256 powtórzeñ jednego (nieprzydatnego) bloku pośredniego i 256 bloków danych.

65805 lub wiêcej

Położenie piewszych 65804 bloków jak wyżej. Potem potrójnie pośredni blok i 256 powtórzeñ `sekwecji podwójnie pośredniej'. Każda podwójnie pośrednia sekwencja zawiera (nieprzydatny) podwójnie pośredni blok, po którym nastêpuje 256 powtórzeñ jednego (nieprzydatnego) bloku pośredniego i 256 bloków danych.

Oczywiście, nawet jeśli numery bloków, które przyjêliśmy, są poprawne, nie ma żadnych gwarancji, że dane są w nich są nienaruszone. Dodatkowo, im dłuższy był plik, tym mniejsze szanse, że system operacyjny zapisał go bez żadnej fragmentacji (za wyjątkiem wyjątkowych sytuacji).

Założyłem, że rozmiar Twoich bloków wynosi 1024 bajty, tyle ile wartośæ standardowa. Jeśli Twój blok jest wiêkszy, niektóre z liczb podanych wyżej zmienią siê. Sprecyzujmy: dopóki numer każdego bloku ma długośæ 4 bajtów, rozmiarbloku/4 jest liczbą numerów bloków, które mogą byæ przechowane w każdym bloku pośrednim. Każde wystąpienie liczby 256 we wcześniejszym opisie, zastąp na rozmiarbloku/4. Zmianie ulegną również ograniczenia na ilośæ wymaganych bloków.

Popatrz na przykładowe odzyskiwanie dużego pliku.

debugfs:  stat <1387>
Inode: 148004   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
User:   503   Group:   100   Size: 1851347
File ACL: 0    Directory ACL: 0
Links: 0   Blockcount: 3616
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8583
TOTAL: 14

Wydaje siê, że mamy pewne szanse, że plik nie jest pofragmentowany. Pewne jest tylko, że pierwsze 12 bloków, których numery są zawarte w iwêźle, jest `po kolei'. Możemy wiêc odtworzyæ te bloki:

# fsgrab -c 12 -s 8314 /dev/hda5 > /mnt/recovered.001

Nastêpny blok, wymieniony w iwêźle, 8326, jest blokiem pośrednim, który ignorujemy. Mamy jednak nadziejê, że nastepne 256 bloków jest naszymi blokami danych (numery 8327 do 8582).

# fsgrab -c 256 -s 8327 /dev/hda5 >> /mnt/recovered.001

Ostatnim blokiem wymienionym w iwêźle jest 8583. Nadal zakładamy, że istnieje ciągłośæ w blokach. Jest to jednak uzasadnione bowiem: ostatnim blokiem danych był blok o numerze 8582 (8327 + 255). Blok 8583 jest podwójnie pośredni i może byæ zignorowany. Teraz może nastąpiæ do 256 powtórzeñ bloku pośredniego (który można pominąæ) i 256 bloków danych. Trochê arytmetyki i już można pisaæ kolejne polecenie. Zauważ, że pominêliśmy podwójnie pośredni blok 8583 oraz pośredni blok 8584 i rozpoczêliśmy czytaæ dane od bloku numer 8585.

# fsgrab -c 256 -s 8585 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 8842 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9099 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9356 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9613 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9870 /dev/hda5 >> /mnt/recovered.001

Dodajmy to wszystko, zapisaliśmy do tej pory 12 + (7 * 256) bloków, co daje 1804. Wyniki polecenia `stat' dla iwêzła dały nam `blockcount' (liczba bloków) równe 3616. Niestety są to bloki o rozmiarze 512 bajtów (zaszłośæ z UNIX-a), na prawdê potrzebujemy wiêc 3616/2 = 1808 bloków o rozmiarze 1024 bajty. Oznacza to, że musimy jeszcze odnaleźæ cztery bloki. Ostatni przeczytany blok danych miał numer 10125. Tak jak to robiliśmy do tej pory, pomijamy blok pośredni (numer 10126) i możemy już zapisaæ ostatnie cztery bloki.

# fsgrab -c 4 -s 10127 /dev/hda5 >> /mnt/recovered.001

Przy pewnym szczêściu udało nam siê odzyskaæ cały plik.

11. Bezpośrednie modyfikacje iwêzłów

Metoda ta jest dużo prostsza. Jednak, tak jak wspomniałem wcześniej, nie może byæ jeszcze stosowana do plików wiêkszych niż 12 bloków.

W każdym iwêźle, który chcesz odzyskaæ musisz ustawiæ licznik podłączeñ (linkcount) na jeden i czas skasowania (deletion time) na zero. Robi siê to za pomocą polecenia mi (modify inode) w debugfs. Przykładowe wywołanie, modyfikacja iwêzła 148003 (tego co wcześniej):

debugfs:  mi <148003>
                          Mode    [0100644]
                       User ID    [503]
                      Group ID    [100]
                          Size    [6065]
                 Creation time    [833201524]
             Modification time    [832708049]
                   Access time    [826012887]
                 Deletion time    [833201524] 0
                    Link count    [0] 1
                   Block count    [12]
                    File flags    [0x0]
                     Reserved1    [0]
                      File acl    [0]
                 Directory acl    [0]
              Fragment address    [0]
               Fragment number    [0]
                 Fragment size    [0]
               Direct Block #0    [594810]
               Direct Block #1    [594811]
               Direct Block #2    [594814]
               Direct Block #3    [594815]
               Direct Block #4    [594816]
               Direct Block #5    [594817]
               Direct Block #6    [0]
               Direct Block #7    [0]
               Direct Block #8    [0]
               Direct Block #9    [0]
              Direct Block #10    [0]
              Direct Block #11    [0]
                Indirect Block    [0]
         Double Indirect Block    [0]
         Triple Indirect Block    [0]

Ustawiłem czas skasowania na 0, licznik podłączeñ na 1 i nacisnąłem Enter dla wszystkich innych pól. Jest to pewną niedogodnością, jeżeli masz wiele plików do odzyskania. Myślê jednak, że można z tym żyæ. Jeśli oczekujesz wygody, lepiej zacznij używaæ graficznego `systemu operacyjnego' ze ślicznym `Koszem na śmieci'.

Przy okazji: polecenie mi pokazuje `Czas stworzenia' (Creation time) w iwêźle. To kłamstwo ! (lub, jak kto woli, pomyłka.) Prawda jest taka, że nie można w systemie plików UNIX-a stwierdziæ kiedy dany plik został utworzony. Pole st_ctime w struct stat zawiera `czas zmiany iwêzła', czyli czas ostaniej zmiany, któregoś z parametrów iwêzła. To tyle z dzisiejszej lekcji.

Nowsze wersje debugfs niż moja, prawdopodobnie nie wyświetalają niektórych pól w iwêźle (szczególnie, Reserved1 i Fragment).

Po zmianie w iwêzłach, możesz wyjśæ z debugfs i napisaæ:

# e2fsck -f /dev/hda5

Pomysł polega na tym, że każdy ze skasowanych plików został odkasowany, ale nie pojawił siê w żadnym katalogu. Program e2fsck umie to wykryæ i doda pozycjê dla każdego z nich w katalogu /lost+found systemu plików. (Jeżeli partycja była zamontowana w /usr, pliki pojawią siê w /usr/lost+found, gdy ją zamontujesz.) Pracą, którą musisz jeszcze zrobiæ, to nadanie plikom nazw i umieszczenie ich we właściwym miejscu drzewa plików.

Po uruchomieniu e2fsck, wyświetli Ci on trochê informacji, ale zada również pytania, które zniszczenia naprawiaæ. Odpowiadaj `yes' (tak) na wszystko co dotyczy `summary information' lub iwêzłów, które zmieniałeś. Resztê pozostawiam do Twojej decyzji, pamiêtaj, że nie jest najlepszą metodą odpowiadanie `tak' na wszystkie pytania. Po skoñczeniu pracy przez e2fsck, możesz ponownie zamontowaæ system plików.

Istnieje alternatywne rozwiązanie do pozwolenia, aby e2fsck utworzył pliki w /lost+found. Możesz użyæ debugfs i stworzyæ w systemie plików dołączenie (link) do iwêzła. Służy do tego polecenie link w debugfs, po zmianach w samym iwêźle:

debugfs:  link <148003> foo.txt

W ten sposób powstanie w bieżącym katalogu plik o nazwie foo.txt; foo.txt bêdzie Twoim odzyskanym plikiem. Nadal musisz jednak uruchomiæ e2fsck, aby uaktualniæ informacje ogólne, liczniki bloków itp. itd.

12. Czy bêdzie to kiedyś łatwiejsze?

Tak. Właściwie, mam nadziejê, że tak. Chociaż, gdy to piszê, aktualna, stabilna wersja jądra (seria 2.0.x) zeruje bloki pośrednie. Wersje serii rozwojowej 2.1.x i stabilnej 2.2.x nie mają tej wady. Dzisiaj, 2 lutego 1999 minêło dopiero kilka dni od wydania jądra 2.2.1; prawdopodobnie pojawi siê ono w dystrybucjach za jeden, dwa miesiące.

Kiedy wersje jądra rozwiążą problem zerowania bloków pośrednich, wiele moich rêcznych technik modyfikacji iwêzłów nie bêdzie już potrzebnych. W tym samym czasie stanie siê możliwe użycie polecenia dump w debugfs dla dużych plików i innych programów narzêdziowych do odzyskiwania plików.

13. Czy są jakieś programy automatyzujące ten proces?

Pewnie, że są. Niestety cierpią one na te same problemy co rêczna technika zmian w iwêzłach: bloki pośrednie są nieodzyskiwalne. Warto im siê przyjrzeæ, bowiem wydaje siê, że ograniczenie to wkrótce zniknie.

Napisałem program e2recover, który jest właściwie tylko Perl-ową otoczką dookoła fsgrab. Stara siê on poradziæ sobie z wyzerowanymi blokami pośrednimi i wydaje sie, że działa całkiem nieźle dla dużych plików, które nie uległy fragmentacji. Ustawia poprawne prawa dostêpu (i właściciela, gdy to jest możliwe). Upewnia siê również, że odzyskiwany plik ma poprawny rozmiar.

Program e2recover był planowany jako czêśæ poważnych zmian w tym Howto; oznacza to niestety, że wiêcej użytecznej dokumentacji do e2recover bêdzie zamieszczone dopiero w nowej wersji tego dokumentu. Jednak i teraz może on siê komuś przydaæ; można go ściągnąæ z mojej strony domowej, i wkrótce z Metalab-a (jest już w Polsce - Sunsite).

Scott D. Heavner jest autorem programu lde, the Linux Disk Editor. Może on byæ używany zarówno jako binarny edytor dysku i jako odpowiednik debugfs dla systemów plików ext2 i minix, a nawet dla systemu plików xia (chociaż wsparcie dla xia przestało byæ dostêpne w jądrach 2.1.x i 2.2.x). Zawarto w nim kilka pomysłów wspomagających odzyskiwanie skasowanych plików: śledzenie listy bloków tworzących plik i wyszukiwanie danych na dysku. Zawiera on także całkiem użyteczną dokumentacjê o podstawach systemu plików oraz jak go używaæ do odzyskiwania plików skasowanych. Wersja 2.4 lde jest dostêpna na Metalab-ie (i kopiach, w Polsce - Sunsite), lub na stronie domowej autora.

Inne możliwości oferowane są przez GNU Midnight Commander, mc. Jest to pełnoekranowe narzêdzie do zarządzania plikami, oparte na znanym w środowisku MS-DOS programie o nazwie `NC'. mc obsługuje mysz zarówno na konsoli, jak i w oknie xterm-a, dostarcza mechanizm wirtualnych systemów plików, co umożliwia triki takie jak cd do archiwum tar. Odzyskiwanie plików obsługiwane jest przez jeden z takich wirtualnych systemów plików. Wszystko to brzmi bardzo zachêcająco, ale muszê przyznaæ, że nie używam tego programu -- wolê staromodne polecenia powłoki.

Aby używaæ możliwości odzyskiwania skasowanych plików, musisz skonfigurowaæ program z opcją --with-ext2undel; bêdziesz również potrzebował bibliotek w wersji rozwojowej i niektórych plików zawartych w pakiecie e2fsprogs. W ten sposób zbudowana jest wersja dostarczana w Debian GNU/Linux; tak samo może byæ w innych dystrybucjach. Teraz możesz po prostu kazaæ mu cd undel:/dev/hda5, i otrzymasz `zawartośæ katalogu' ze skasowanymi plikami. Jak wiele innych i ten program bardzo źle radzi sobie z zerowaniem bloków pośrednich -- przeważnie odtwarza tylko pierwsze 12k wiêkszych plików.

Aktualną wersjê można ściągnąæ z serwera ftp the Midnight Commander.

14. Kolofon

Mam zamiar regularnie uaktualniaæ ten dokument tak długo jak bêdê miał wystarczająco dużo czasu i coś ciekawego do powiedzenia. Oznacza to, że bardzo mi zależy na komentarzach od czytelników. Czy moje pisanie może byæ bardziej zrozumiałe? Czy myślicie o czymś, co uczyniłoby problem prostszym? Jest jakiś program, który robi to wszystko automatycznie? Jeżeli masz coś do powiedzenia o tym dokumencie, albo o fsgrab, albo o e2recover, napisz do mnie aaronc@pobox.com.

15. Wyrazy uznania i bibliografia

`Jeżeli widzê dalej od innych, to dlatego, że stojê na ramionach olbrzymów.' (Isaac Newton)

To mini-Howto wywodzi siê z listu zamieszczonego w grupie comp.os.linux.misc przez Robina Glovera swrglovr@met.rdg.ac.uk. Chciałbym podziekowaæ Robinowi za wspaniałomyślne pozwolenie na przetworzenie jego pomysłów w to mini-Howto.

Korzystając z okazji, chciałbym jeszcze raz podziêkowaæ wszystkim, którzy napisali do mnie o tym Howto. Otrzymywanie wyrazów wdzieczności czyni pracê wartą wysiłku.

Niektóre odnośniki bibliograficzne:

16. Formalności

Wszystkie znaki towarowe są własnością ich prawowitych właścicieli. Konkretnie:

Prawa autorskie do tego dokumentu 1997, 1999 posiada Aaron Crane aaronc@pobox.com. Może on byæ darmowo rozpowszechniany w całości, łącznie z tą notą autorską. Nie może byæ zmieniany bez zgody autora lub koordynatora Linux Documentation Project HOWTO. Nie dotyczy to tylko kopiowania jego czêści w celu przeglądania lub cytowania; w takim przypadku, czêści te muszą byæ poprawnymi cytatami i nie muszą zawieraæ noty o prawach autorskich.

Autor oczekuje, ale nie wymaga, że ten kto bêdzie chciał sprzedawaæ kopie tego dokumentu, niezależnie od tego, czy na nośniku elektronicznym, czy papierowym, poinformuje jego lub koordynatora projektu Linux HOWTO o swoich zamiarach.

Koordynatorem projektu Linux HOWTO jest aktulanie Tim Bynum linux-howto@sunsite.unc.edu.

17. Od tłumacza

Starałem siê, aby tłumaczenie było najwierniejsze z możliwych. Dlatego nie ma żadnych zmian w stosunku do orginału, za wyjątkiem odnośników do polskiej kopii serwera Metalab na Sunsite.icm.edu.pl.

Czekam na komentarze pod adresem: Bartosz Sawicki sawickib@ee.pw.edu.pl.