如何修复/修复Linux中的Badblocks
存储设备中的Badblocks是由于某种原因不可读取的设备的部分。
如果我们能够达到该块的确切位置,可以恢复这些包块。
智能技术内置于许多存储设备(例如许多ATA-3,稍后ATA,IDE和SCSI-3硬盘)监视硬盘驱动器的可靠性,并可以预测驱动器故障。
智能代表自我监控,分析和报告技术。
本教程描述了SmartMontools在运行Linux的硬盘上检测和报告某些Badblocks时可以采取的操作。
关于SmartMontools.
SmartMontools包提供了两个实用程序:Smartrd和Smartctl。
SmartD是DEAMON每30分钟调查ATA和SCSI设备(可以更改此值)并使用SYSLOG接口记录智能错误和更改智能属性。
SmartCTL执行智能任务,可用于在其他任务中打印智能自检和错误日志,例如支持来自SCSI磁带驱动器的磁带信息。
当我们通过本文时,此命令的使用将很清楚。
本文通过对不同类型的文件系统进行磁盘失败的一些示例进行。
smartctl命令
SmartCTL命令在逻辑块地址LBA = 0x016561E9处报告BADBLOCK,其中十进制数系统是23421417.
root]# smartctl -l selftest /dev/hda SMART Self-test log structure revision number 1 Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error # 1 Extended offline Completed: read failure 90% 217 0x016561e9
LBA以零开始以512字节为单位计数扇区。
"smartctl -a"命令中的"current_pending_sector"属性的值确认了坏扇区。
root]# smartctl -A /dev/hda ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE 5 Reallocated_Sector_Ct 0x0033 100 100 005 Pre-fail Always - 0 196 Reallocated_Event_Count 0x0032 100 100 000 Old_age Always - 0 197 Current_Pending_Sector 0x0022 100 100 000 Old_age Always - 1 198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 1
修复坏块
步骤1:
找到坏块所在的分区。
FDISK命令可用于查看硬盘分区的扇区。
root]# fdisk -lu /dev/hda Disk /dev/hda: 123.5 GB, 123522416640 bytes 255 heads, 63 sectors/track, 15017 cylinders, total 241254720 sectors Units = sectors of 1 * 512 = 512 bytes Device Boot Start End Blocks Id System /dev/hda1 * 63 4209029 2104483+ 83 Linux /dev/hda2 4209030 5269319 530145 82 Linux swap /dev/hda3 5269320 238227884 116479282+ 83 Linux /dev/hda4 238227885 241248104 1510110 83 Linux
其中我们可以看到LBA 23421417位于第三分区中,例如:/dev/hda3.
扇区的偏移值是23421417 5269320 =分区/dev/hda3中的扇区18152097扇区。
现在我们需要检查分区的文件系统的类型。
这可以从/etc/fstab文件检查。
root]# grep hda3 /etc/fstab /dev/hda3 /data ext2 defaults 1 2
第2步:
现在我们需要使用tune2fs命令找到文件系统的块大小
root]# tune2fs -l /dev/hda3 | grep Block Block count: 29119820 Block size: 4096
这将块大小报告为4096字节。
第3步:
找到包含此问题LBA的文件系统块。
我们使用以下公式:
b =(int)((l-s)* 512/b)
其中:
B =文件系统块号B =文件系统块大小以字节为单位L = LBA的坏扇区S = FDISK -LU和(int)所示的分区的起始扇区表示整数部分。
对于我们的示例,L = 23421417,S = 5269320和B = 4096.
B =(int)18152097 * 512/4096 =(int)2269012.125
所以B = 2269012.
第四步:
使用debugfs定位存储在此块中的inode,因此将存储在该位置的文件。
root]# debugfs debugfs 1.32 (09-Nov-2002) debugfs: open /dev/hda3 debugfs: testb 2269012 Block 2269012 not in use
其中在这种情况下,块不使用。
所以可以跳过这一步的其余部分,我们可以直接跳转到下一步。
否则,如果块正在使用中,如以下输出所报告:
debugfs: testb 2269012 Block 2269012 marked in use debugfs: icheck 2269012 Block Inode number 2269012 41032 debugfs: ncheck 41032 Inode Pathname 41032 /S1/R/H/714197568-714203359/H-R-714202192-16.gwf
在这种情况下,问题文件是:/data/s1/r/h/714197568-714203359/h-r-714202192-16.gwf
在ext3文件系统的情况下,此块可以是Junice本身的一部分。
inode将非常小,debugfs无法报告任何文件名。
debugfs: testb 2269012 Block 2269012 marked in use debugfs: icheck 2269012 Block Inode number 2269012 8 debugfs: ncheck 8 Inode Pathname debugfs:
在这种情况下,我们可以删除"使用tune2fs命令的日志:
tune2fs -O ^has_journal /dev/hda3
现在,我们重复第4步,如果没有报道问题,我们可以重建期刊:
tune2fs -j /dev/hda3
第5步:
此步骤将通过在其上写入零点来破坏该块上的数据。
坏块将被恢复,但文件的数据将丢失。
如果我们确定,我们可以继续执行以下步骤:
root]# dd if=/dev/zero of=/dev/hda3 bs=4096 count=1 seek=2269012 root]# sync
现在我们可以再次检查"smartctl -a"输出以验证一切恢复正常。
root]# smartctl -A /dev/hda ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE 5 Reallocated_Sector_Ct 0x0033 100 100 005 Pre-fail Always - 1 196 Reallocated_Event_Count 0x0032 100 100 000 Old_age Always - 1 197 Current_Pending_Sector 0x0022 100 100 000 Old_age Always - 0 198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 1
其中我们可以看到"current_pending_sector"的值为零。
ext2/ext3上的智能错误
To: ballen Subject: SMART error (selftest) detected on host: medusa-slave166.medusa.phys.uwm.edu This email was generated by the smartd daemon running on host: medusa-slave166.medusa.phys.uwm.edu in the domain: master001-nis The following warning/error was logged by the smartd daemon: Device: /dev/hda, Self-Test Log error count increased from 0 to 1
来自SmartD的此电子邮件显示了故障的第一个迹象。
正如前面的示例中谈到的那样,我们运行"SmartCtl -A/dev/hda"以确认问题:
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error # 1 Extended offline Completed: read failure 80% 682 0x021d9f44
报告的LBA是0x021D9F44(基部16)= 35495748(基部10)
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE 5 Reallocated_Sector_Ct 0x0033 100 100 005 Pre-fail Always - 0 196 Reallocated_Event_Count 0x0032 100 100 000 Old_age Always - 0 197 Current_Pending_Sector 0x0022 100 100 000 Old_age Always - 3 198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 3
其中3个扇区是不可读的。
使用以下Bash脚本,我们可以检查该区域周围的扇区。
[root]# export i=35495730 [root]# while [ $i -lt 35495800 ] > do echo $i > dd if=/dev/hda of=/dev/null bs=512 count=1 skip=$i > let i+=1 > done
35495734 1 + 0记录在1 + 0记录中备注35495735 DD:读取`/dev/hda':输入/输出错误0 + 0记录0 + 0记录出来
35495751 DD:读取`/dev/hda':输入/输出错误0 + 0记录0 + 0记录35495752 1 + 0记录在1 + 0记录出来
这表明17个扇区35495735-35495751是不可读的。
包含此区域的文件系统块是:
L = 35495735至35495751 S = 5269320 B = 4096所以B = 3778301至3778303
要识别这些位置的文件,我们运行debugfs:
[root]# debugfs debugfs 1.32 (09-Nov-2002) debugfs: open /dev/hda3 debugfs: icheck 3778301 Block Inode number 3778301 45192 debugfs: icheck 3778302 Block Inode number 3778302 45192 debugfs: icheck 3778303 Block Inode number 3778303 45192 debugfs: ncheck 45192 Inode Pathname 45192 /S1/R/H/714979488-714985279/H-R-714979984-16.gwf debugfs: quit
我们可以使用MD5SUM来确认我们的文件:
[root]# md5sum /data/S1/R/H/714979488-714985279/H-R-714979984-16.gwf md5sum: /data/S1/R/H/714979488-714985279/H-R-714979984-16.gwf: Input/output error
因此,我们强制磁盘重新分配坏块:
[root]# dd if=/dev/zero of=/dev/hda3 bs=4096 count=3 seek=3778301 [root]# sync
或者
[root]# dd if=/dev/zero of=/dev/hda bs=512 count=17 seek=35495735 [root]# sync
现在我们可以检查错误块是否在"current_pending_sector"属性(smart_pending_sector"属性(smartctl -a命令)的值中创建问题:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE 5 Reallocated_Sector_Ct 0x0033 100 100 005 Pre-fail Always - 0 196 Reallocated_Event_Count 0x0032 100 100 000 Old_age Always - 0 197 Current_Pending_Sector 0x0022 100 100 000 Old_age Always - 0 198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 0
未分配的部门
在上面的示例中,当未分配给任何文件时,我们未考虑错误块。
当我们运行debugfs命令查找对应于特定块的文件时,这将是清楚的。
如果是这种情况,那么我们可以首先创建一个足够大的文件来填充剩余的文件系统(再次,DD命令是救援)。
dd if=/dev/zero of=/some/mount/point bs=4k
此命令将运行,直到文件系统上没有剩余空间。
现在我们可以通过其余的步骤进行。
Reiserfs上的坏块
在此示例中,使用的文件系统是ReisErfs。
因此,使用的一些命令将与上述情况不同。
智能错误日志表示BAD块地址为58656333.分区表指示该块在具有Reiserfs文件系统的分区中,从块地址54781650开始。
获取文件系统的块大小
# debugreiserfs /dev/hda3 | grep '^Blocksize' Blocksize: 4096
获取块号码
# echo "(58656333-54781650)*512/4096" | bc -l 484335.37500000000000000000
有关该块的更多信息
# debugreiserfs -1 484335 /dev/hda3 debugreiserfs 3.6.19 (2003 http://www.namesys.com) 484335 is free in ondisk bitmap
问题已发生如硬件问题。
其中我们看到读取块失败。
但我们现在从这个输出中知道它是未使用的块。
此时,我们可以尝试编写坏块,看看驱动器是否倒退了坏块。
如果无法重新映射块,请使用ReiserFS Utils使用Badblock选项(-b)正确处理此块。
面包:无法读取块(484335):(输入/输出错误)。
中产响
至少我们有正确的坏块。
找到受影响的文件
tar -cO /mydir | cat >/dev/null
运行badblock-n以引发重新分配
# badblocks -b 4096 -p 3 -s -v -n /dev/hda3 `expr 484335 + 100` `expr 484335 - 100`
如果一切正常发生,Debugreiserfs -1 484335/dev/hda3报告没有错误。
除此以外:
使用dd命令在特定区域写入zeroes
# dd if=/dev/zero of=/dev/hda3 count=1 bs=4096 seek=484335 1+0 records in 1+0 records out 4096 bytes transferred in 0.007770 seconds (527153 bytes/sec)
坏块修复LVM.
此示例认为Badblock在LVM卷上:
报告错误,发现错误的块在LBA 37383668中,其中包含以下命令:
# smartctl -a /dev/hdb ... SMART Self-test log structure revision number 1 Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error # 1 Short offline Completed: read failure 90% 66 37383668
sfdisk可以帮助找到坏块的物理分区:
# sfdisk -luS /dev/hdb
或者
# fdisk -ul /dev/hdb
Disk /dev/hdb: 9729 cylinders, 255 heads, 63 sectors/track Units = sectors of 512 bytes, counting from 0 Device Boot Start End #sectors Id System /dev/hdb1 63 996029 995967 82 Linux swap/Solaris /dev/hdb2 * 996030 1188809 192780 83 Linux /dev/hdb3 1188810 156296384 155107575 8e Linux LVM /dev/hdb4 0 - 0 0 Empty
坏块位于/dev/hdb3分区中,它是基于LVM的分区。
该块的偏移是:(37383668 1188810)= 36194858
LVM使用的物理分区分为PE(物理范围)。
'pvdisplay'命令为lvm分区提供PE的大小:
part =/dev/hdb3; pvdisplay -c $part | awk-f:'{打印$8}'4096
要在LBA块大小(512字节或者0.5 kB)中获得其大小,我们将此数字乘以2:4096 * 2 =每个PE的8192块。
现在我们搜索了糟糕块居住的PE:物理分区的坏块号/尺寸(PE)
36194858/8192 = 4418.3176
现在我们需要找到与PE号4418对应的逻辑分区。
# lvdisplay --maps |egrep 'Physical|LV Name|Type' LV Name /dev/WDC80Go/racine Type linear Physical volume /dev/hdb3 Physical extents 0 to 127 LV Name /dev/WDC80Go/usr Type linear Physical volume /dev/hdb3 Physical extents 128 to 1407 LV Name /dev/WDC80Go/var Type linear Physical volume /dev/hdb3 Physical extents 1408 to 1663 LV Name /dev/WDC80Go/tmp Type linear Physical volume /dev/hdb3 Physical extents 1664 to 1791 LV Name /dev/WDC80Go/home Type linear Physical volume /dev/hdb3 Physical extents 1792 to 3071 LV Name /dev/WDC80Go/ext1 Type linear Physical volume /dev/hdb3 Physical extents 3072 to 10751 LV Name /dev/WDC80Go/ext2 Type linear Physical volume /dev/hdb3 Physical extents 10752 to 18932
因此,PE 4418处于/dev/wdc80go/ext1逻辑分区。
文件系统逻辑块的大小/dev/wdc80go/ext1是
# dumpe2fs /dev/WDC80Go/ext1 | grep 'Block size' dumpe2fs 1.37 (21-Mar-2005) Block size: 4096
逻辑分区从PE 3072开始:
(PE的分区开始* sizeof(pe))+ parttion offset [pe_start] =(3072 * 8192)+ 384 = 25166208
有512个物理分区块,因此错误的块号是:
(36194858 25166208)/(尺寸(FS块)/512)= 11028650 /(4096/512)= 1378581.25
我们可以验证是否是具有DD命令的实际坏块:
dd if=/dev/WDC80Go/ext1 of=block1378581 bs=4096 count=1 skip=1378581
如果命令发出一些错误,则BAD块的计算是正确的。
否则,请重新检查计算以查找正确的块。
找到了正确的块后,用DD命令解析问题,如上所述中解释:
dd if=/dev/zero of=/dev/WDC80Go/ext1 count=1 bs=4096 seek=1378581