2010年2月28日 星期日

硬盤ext2/3文件系統superblock損壞修復試驗 (轉載)

 之前 Linux 的 PC 掛點,發現是 Partition 的 SuperBlock 損毀,可能是損毀的太嚴重,救不回來,但在救系統中,發現這篇文章寫的還不錯,也試過上面部份指令蠻有用的,所以稍加整理保留進來。

首先大家可能遇到過這樣的情況:
[root@dhcp-0-142 ~]# mount /dev/sdb1 /mnt/sdb1
mount: wrong fs type, bad option, bad superblock on /dev/sdb1,
missing codepage or other error
In some cases useful info is found in syslog - try
dmesg | tail or so


[root@dhcp-0-142 ~]# 


這種情況一般為 superblock 損壞的概率很大。 


superblock 是什麼? 
分區的第一塊 superblock 位於分區的第二塊 block。 
如果分區的 blocksize 是1024,則 superblock 位於[1024, 2048)之間。 


ext2 文件系統的結構請參考這個網站,寫的非常清楚: 
http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm


這個是 superblock 的結構,摘自: 
http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm





繼續剛才的話題。我/dev/sdb1掛載不上了。


所以我做了如下操作:


[root@dhcp-0-142 ~]# dumpe2fs /dev/sdb1
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: c3800df3-5c34-4b53-8144-94029b5736d8
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal resize_inode dir_index filetype sparse_super
Default mount options: (none)
Filesystem state: clean with errors
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 0
Block count: 0
Reserved block count: 0
Free blocks: 20926971
Free inodes: 4705752
First block: 1
Block size: 1024
Fragment size: 1024
Reserved GDT blocks: 256
Blocks per group: 8192
Fragments per group: 8192
Inodes per group: 2008
Inode blocks per group: 251
Filesystem created: Tue Oct 7 19:18:08 2008
Last mount time: n/a
Last write time: Tue Oct 7 19:29:39 2008
Mount count: 0
Maximum mount count: 20
Last checked: Tue Oct 7 19:18:08 2008
Check interval: 15552000 (6 months)
Next check after: Sun Apr 5 19:18:08 2009
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 128
Journal inode: 8
Default directory hash: tea
Directory Hash Seed: 7f7e1c41-5cae-4f23-9873-877991751ccb
Journal backup: inode blocks
dumpe2fs: Illegal inode number while reading journal inode


[root@dhcp-0-142 ~]#


根據 Blocks per group: 8192 的信息,我定位了第一個備份 superblock 的位置為8193。


所以我做如下操作:


[root@dhcp-0-142 ~]# fsck -b 8193 /dev/sdb1
fsck 1.39 (29-May-2006)
e2fsck 1.39 (29-May-2006)
/dev/sdb1 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information


/dev/sdb1: ***** FILE SYSTEM WAS MODIFIED *****
/dev/sdb1: 11/26104 files (9.1% non-contiguous), 8966/104388 blocks


[root@dhcp-0-142 ~]# mount /dev/sdb1 /mnt/sdb1


[root@dhcp-0-142 ~]# ls /mnt/sdb1
lost+found


[root@dhcp-0-142 ~]#


superblock 已經修復,文件系統掛載正常。


之所以這麼做,是有依據的。


ext2/3文件系統在創建文件系統的時候會創建若干個 superblock 的備份存放於特定位置。


[root@dhcp-0-142 ~]# dumpe2fs /dev/sdb1 | grep --before-context=1 superblock
dumpe2fs 1.39 (29-May-2006)
Group 0: (Blocks 1-8192)
Primary superblock at 1, Group descriptors at 2-2
--
Group 1: (Blocks 8193-16384)
Backup superblock at 8193, Group descriptors at 8194-8194
--
Group 3: (Blocks 24577-32768)
Backup superblock at 24577, Group descriptors at 24578-24578
--
Group 5: (Blocks 40961-49152)
Backup superblock at 40961, Group descriptors at 40962-40962
--
Group 7: (Blocks 57345-65536)
Backup superblock at 57345, Group descriptors at 57346-57346
--
Group 9: (Blocks 73729-81920)
Backup superblock at 73729, Group descriptors at 73730-73730


[root@dhcp-0-142 ~]#


從上面操作可以看出,在第 1、3、4、7、9 這幾個 Block Group 上存放有 superblock 備份。


什麼是Block Group? ext2/3文件系統為了提高磁盤尋道效率,把 inode table 等信息按照 Inodes per group 分成若干組存放,而沒有全部放在一起。





此圖摘自:http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm


Inodes per group信息相見命令:


[root@dhcp-0-142 ~]# dumpe2fs /dev/sdb1 | grep 'Inodes per group'
dumpe2fs 1.39 (29-May-2006)
Inodes per group: 2008


[root@dhcp-0-142 ~]#




有些文件系統 superblock 損壞的很厲害。連 dumpe2fs和tune2fs 都看不到信息。


[root@dhcp-0-175 ~]# dd if=/dev/zero of=/dev/sdb1 bs=1 count=1024 seek=1024
1024+0 records in
1024+0 records out
1024 bytes (1.0 kB) copied, 0.0228272 seconds, 44.9 kB/s


[root@dhcp-0-175 ~]# dumpe2fs /dev/sdb1
dumpe2fs 1.39 (29-May-2006)
dumpe2fs: Bad magic number in super-block while trying to open /dev/sdb1
Couldn't find valid filesystem superblock.


[root@dhcp-0-175 ~]# tune2fs -l /dev/sdb1
tune2fs 1.39 (29-May-2006)
tune2fs: Bad magic number in super-block while trying to open /dev/sdb1
Couldn't find valid filesystem superblock.


[root@dhcp-0-175 ~]#


這時候我們根本無法從 dumpe2fs 和 tune2fs 看到 Backup superblock 的位置。


我們可以嘗試從 superblock 的結構來猜測 superblock 的位置(superblock結構見上圖)。


我們從 superblock 結構可以知道,卷標 volume name 存放於 superblock 中。所以如果文件系統有設置卷標,那麼我們可以嘗試從卷標來定位 superblock。


我們用 hexdump 把文件系統 dump 出來:


[root@dhcp-0-175 ~]# hexdump -C /dev/sdb1 > /var/sdb1.hexdump 


[root@dhcp-0-175 ~]# 


我們已知 /dev/sdb1 的捲標是 sdb1 (如果不知道卷標或者沒有設置卷標,那麼我就沒辦法了)。


我們搜索sdb1,搜到結果如下:





我們猜測這裡就是備份 superblock 的位置。


卷標起始位置是 0x18000078。由於 superblock 結構裡 volume name 位於 0x78 的位置,所以我們可以猜測備份 superblock 的起始位置是 0x18000078 – 0x78 = 0x18000000。


由於blocksize位於 superblock 的 (0x18, 0x22) 的位置,這裡的值是 0x0002,得出 blocksize 是 0x0400 x ( 0x00020x0002 ) = 0x1000 = 4096


(0x18, 0x22) 處值 n 和 blocksize 的關係是 blocksize = 0x0400 x 0x0002n此公式感謝得新傾情贊助)


而備份 superblock 的偏移量為 offset / blocksize,即 0x18000000 / 0x1000 = 0x00018000 = 98304。


因此我們執行:


[root@dhcp-0-175 ~]# fsck.ext3 -b 98304 /dev/sdb1
e2fsck 1.39 (29-May-2006)
sdb1 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information


sdb1: ***** FILE SYSTEM WAS MODIFIED *****
sdb1: 11/123648 files (9.1% non-contiguous), 8298/246991 blocks


[root@dhcp-0-175 ~]#


這樣文件系統就有給修復的可能性了。


測試一下:


[root@dhcp-0-175 ~]# dumpe2fs /dev/sdb1
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name: sdb1
Last mounted on: <not available>
Filesystem UUID: 0293bd85-b911-43bf-853e-6588b3eaaf39
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal resize_inode dir_index filetype sparse_super large_file
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 123648
Block count: 246991
Reserved block count: 12349
Free blocks: 238693
Free inodes: 123637
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 60
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 15456
Inode blocks per group: 483
Filesystem created: Wed Oct 8 12:49:09 2008
Last mount time: n/a
Last write time: Wed Oct 8 12:52:10 2008
Mount count: 0
Maximum mount count: 28
Last checked: Wed Oct 8 12:52:10 2008
Check interval: 15552000 (6 months)
Next check after: Mon Apr 6 12:52:10 2009
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 128
Journal inode: 8
Default directory hash: tea
Directory Hash Seed: 2efa124c-dde6-4046-9181-a05b7e6d182a
Journal backup: inode blocks
Journal size: 16M
Group 0: (Blocks 0-32767)
Primary superblock at 0, Group descriptors at 1-1
Reserved GDT blocks at 2-61
Block bitmap at 62 (+62), Inode bitmap at 63 (+63)
Inode table at 64-546 (+64)
28113 free blocks, 15445 free inodes, 2 directories
Free blocks: 4655-32767
Free inodes: 12-15456
Group 1: (Blocks 32768-65535)
Backup superblock at 32768, Group descriptors at 32769-32769
Reserved GDT blocks at 32770-32829
Block bitmap at 32830 (+62), Inode bitmap at 32831 (+63)
Inode table at 32832-33314 (+64)
32221 free blocks, 15456 free inodes, 0 directories
Free blocks: 33315-65535
Free inodes: 15457-30912
Group 2: (Blocks 65536-98303)
Block bitmap at 65536 (+0), Inode bitmap at 65537 (+1)
Inode table at 65538-66020 (+2)
32283 free blocks, 15456 free inodes, 0 directories
Free blocks: 66021-98303
Free inodes: 30913-46368
Group 3: (Blocks 98304-131071)
Backup superblock at 98304, Group descriptors at 98305-98305
Reserved GDT blocks at 98306-98365
Block bitmap at 98366 (+62), Inode bitmap at 98367 (+63)
Inode table at 98368-98850 (+64)
32221 free blocks, 15456 free inodes, 0 directories
Free blocks: 98851-131071
Free inodes: 46369-61824
Group 4: (Blocks 131072-163839)
Block bitmap at 131072 (+0), Inode bitmap at 131073 (+1)
Inode table at 131074-131556 (+2)
32283 free blocks, 15456 free inodes, 0 directories
Free blocks: 131557-163839
Free inodes: 61825-77280
Group 5: (Blocks 163840-196607)
Backup superblock at 163840, Group descriptors at 163841-163841
Reserved GDT blocks at 163842-163901
Block bitmap at 163902 (+62), Inode bitmap at 163903 (+63)
Inode table at 163904-164386 (+64)
32221 free blocks, 15456 free inodes, 0 directories
Free blocks: 164387-196607
Free inodes: 77281-92736
Group 6: (Blocks 196608-229375)
Block bitmap at 196608 (+0), Inode bitmap at 196609 (+1)
Inode table at 196610-197092 (+2)
32283 free blocks, 15456 free inodes, 0 directories
Free blocks: 197093-229375
Free inodes: 92737-108192
Group 7: (Blocks 229376-246990)
Backup superblock at 229376, Group descriptors at 229377-229377
Reserved GDT blocks at 229378-229437
Block bitmap at 229438 (+62), Inode bitmap at 229439 (+63)
Inode table at 229440-229922 (+64)
17068 free blocks, 15456 free inodes, 0 directories
Free blocks: 229923-246990
Free inodes: 108193-123648


[root@dhcp-0-175 ~]# mount /dev/sdb1 /mnt


[root@dhcp-0-175 ~]# ls /mnt
lost+found


[root@dhcp-0-175 ~]#


看來我運氣很好。文件系統成功修復。


其實對於這種 superblock 破壞很嚴重的文件系統,其實係統已經有了很強大的修復方案:




我們可以用 mke2fs -S 來修復 superblock。


[root@dhcp-0-175 /]# mount /dev/sdb1 /mnt/
mount: you must specify the filesystem type


[root@dhcp-0-175 /]# mount /dev/sdb1 /mnt/ -t ext3
mount: wrong fs type, bad option, bad superblock on /dev/sdb1,
missing codepage or other error
In some cases useful info is found in syslog - try
dmesg | tail or so


[root@dhcp-0-175 /]# mke2fs -S /dev/sdb1
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
24480 inodes, 97656 blocks
4882 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
12 block groups
8192 blocks per group, 8192 fragments per group
2040 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729


Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 37 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.


[root@dhcp-0-175 /]# mount /dev/sdb1 /mnt/


[root@dhcp-0-175 /]# cd /mnt


[root@dhcp-0-175 mnt]# ls
file0 file14 file20 file27 file33 file4 file46 file52 file59 file65 file71 file78 file84 file90 file97
file1 file15 file21 file28 file34 file40 file47 file53 file6 file66 file72 file79 file85 file91 file98
file10 file16 file22 file29 file35 file41 file48 file54 file60 file67 file73 file8 file86 file92 file99
file100 file17 file23 file3 file36 file42 file49 file55 file61 file68 file74 file80 file87 file93 lost+found
file11 file18 file24 file30 file37 file43 file5 file56 file62 file69 file75 file81 file88 file94
file12 file19 file25 file31 file38 file44 file50 file57 file63 file7 file76 file82 file89 file95
file13 file2 file26 file32 file39 file45 file51 file58 file64 file70 file77 file83 file9 file96


[root@dhcp-0-175 mnt]# 


e2fsck也可以達到同樣的效果


[root@dhcp-0-175 /]# mount /dev/sdb1 /mnt/ -t ext3
mount: wrong fs type, bad option, bad superblock on /dev/sdb1,
missing codepage or other error
In some cases useful info is found in syslog - try
dmesg | tail or so


[root@dhcp-0-175 /]# e2fsck /dev/sdb1
e2fsck 1.39 (29-May-2006)
Couldn't find ext2 superblock, trying backup blocks...
/dev/sdb1 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong for group #0 (3549, counted=3547).
Fix<y>? yes


Free blocks count wrong (88895, counted=88893).
Fix<y>? yes


Free inodes count wrong for group #0 (2029, counted=1929).
Fix<y>? yes
Free inodes count wrong (24469, counted=24369).
Fix<y>? yes


/dev/sdb1: ***** FILE SYSTEM WAS MODIFIED *****
/dev/sdb1: 111/24480 files (1.8% non-contiguous), 8763/97656 blocks


[root@dhcp-0-175 /]# mount /dev/sdb1 /mnt/ -t ext3


[root@dhcp-0-175 /]# ls /mnt
file0 file15 file21 file28 file34 file40 file47 file53 file6 file66 file72 file79 file85 file91 file98
file1 file16 file22 file29 file35 file41 file48 file54 file60 file67 file73 file8 file86 file92 file99
file10 file17 file23 file3 file36 file42 file49 file55 file61 file68 file74 file80 file87 file93 lost+found
file11 file18 file24 file30 file37 file43 file5 file56 file62 file69 file75 file81 file88 file94
file12 file19 file25 file31 file38 file44 file50 file57 file63 file7 file76 file82 file89 file95
file13 file2 file26 file32 file39 file45 file51 file58 file64 file70 file77 file83 file9 file96
file14 file20 file27 file33 file4 file46 file52 file59 file65 file71 file78 file84 file90 file97


[root@dhcp-0-175 /]#




資料轉載原處:
http://blog.chinaunix.net/u1/48373/showart_1331657.html

沒有留言:

張貼留言