Dobry administrator zawsze i dokładnie czyta logi, z akcentem na dokładnie :).
Kilka dni temu miałem dość ciekawy przypadek automatycznego restartu serwera na skutek wykonywania prostych poleceń, np. find lub locate.
Co ciekawsze, serwer „wywalał” się zawsze na tym samym katalogu. Z początku myślałem, że to wina usługi samba i udostępnionych plików/katalogów, jednak po wnikliwym wczytaniu się w logi systemowe, przekonałem się, że byłem w błędzie.
Błąd był widoczny już w samym dmesg (logi systemowe)
/dev/ad0s1: bad dir usr 25789343 AT OFFSET 1024: MANGLED ENTRY
panic: ufs_dirbad: bad dir
Z tego wynika, że mamy do czynienia z wadliwym katalogiem usr.
Niby prosta rzecz, wchodzimy do single user mode (wtedy dyski/partycje nie są zamontowane).
Sprawdzamy tzw. mount point poleceniem
cat /etc/fstab
i traktujemy zamontowaną etykietkę (label) jako katalog /usr poleceniem fsck
# fsck -y /dev/ad0s1f
(u mnie /usr jest zamontowany jako ad0s1f).
Na koniec skanowania powinno nam się wyświetlić
***** FILE SYSTEM MARKED CLEAN *****
Po ponownym uruchomieniu serwera sprawdzamy czy wszystko jest OK przykładowymi poleceniami
# find / -type d -exec ls -ld {} ;
# find / -type d -exec stat {} ;
# find / -type d -exec touch {}/mydummyfilenamewhichshouldnotexist ;
Najwyraźniej fsck nie poradziło sobie z tym dziwnym przypadkiem, ponieważ freeBSD nadal się restartuje (panic) podczas wykonywania powyższych testów.
Na szczęście jest sposób aby to naprawić, ale może wystąpić sytuacja, że z uszkodzonego katalogu nie odzyskamy danych, aczkolwiek bądźmy dobrej myśli i miejmy pewność, że mamy zrobioną wcześniej kopię zapasową tych danych. Istotą rozwiązania problemu jest naprawienie systemu plików i wyeliminowanie samoistnych restartów systemu freeBSD.
Będąc ponownie w trybie single user mode uruchamiamy narzędzie fsdb (FileSystem DeBugger)
# fsdb /dev/ad0s1f
** /dev/ad0s1f
Editing file system ‚/dev/ad0s1f’
Last mounted on /mnt/ad0s1f
(…)
fsdb (inum: 2)>
Teraz wpisujemy numer tzw. inode, który bierzemy z loga (u mnie był to numer 25789343)
fsdb (inum: 2)> inode 25789343
current inode: directory
I= 25789343 MODE=40777 SIZE=1024
BTIME=May 9 12:52:12 2008 [0 nsec]
MTIME=May 9 12:52:12 2008 [0 nsec]
CTIME=May 9 12:52:12 2008 [0 nsec]
ATIME=May 9 12:52:12 2008 [0 nsec]
OWNER=root GRP=WHEEL LINKCNT=2 FLAGS=0 BLKCNT=4 GEN=157338b7
fsdb (inum: 25789343)>
Nawet gdy stracimy dane, będziemy mieli pewność, że problem zostanie usunięty.
Poleceniem clri debugując inode’a oznaczamy go jako błędny
fsdb (inum: 25789343)> clri 25789343
Wychodzimy z narzędzia debugowania.
fsdb (inum: 25789343)> quit
**** FILE SYSTEM STILL DIRTY *****
*** FILE SYSTEM MARKED DIRTY
*** BE SURE TO RUN FSDK TO CLEAN UP ANY DAMAGE
*** IF IT WAS MOUNTED, RE-MOUNT WITH -u -o reload
Będąc nadal w single user mode uruchamiamy ponownie fsck
# fsck -y /dev/ad0s1f
** /dev/ad0s1f
** Last Mounted on /usr
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
UNALLOCATED I= 25789343 OWNER=root MODE=0
SIZE=1024 MTIME May 9 12:52:12 2008
NAME=/_new2????REMOVE=YES
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counters
(…)
Podczas skanowania pojawiały się jeszcze inne różne błędy, które naprawiały się automatycznie dzięki parametrowi -y, np.
LINK COUNT DIR I=2 OWNER=root MODE=40777
SIZE=1024MTIME=May 9 12:52:12 2008 COUNT 21 SHOULD BE 20
ADJUST? yes
(…)
FREE BLK COUNT(S) WRONG IN SUPERBLK
SALVAGE? yes
(…)
SUMMARY INFORMATION BAD
SAVLAGE? yes
(…)
BLK(S) MISSING IN BIT MAPS
SALVAGE? yes
Na końcu pojawił się komunikat
***** FILE SYSTEM MARKED CLEAN *****
***** FILE SYSTEM WAS MODIFIED *****
Ale czy to wszystko? Zdecydowanie tak.
W moim przypadku było dużo szczęścia i wszystkie dane były na swoim miejscu.
Po prostu fsck jakimś dziwnym trafem nie potrafił poradzić sobie z błędnym inode o numerze 25789343.
Oczywiście ponownie przetestowałem find’em czy przypadkiem coś jeszcze nie zostało do naprawienia. Tym razem wszystko było jak należy.
Jednak gdyby nadal były restarty typu panic: ufs_dirbad: bad dir, proponuję powyższe czynności powtórzyć dla każdego złego inode’a.
Pozdrawiam