|
看到大家对磁盘阵列raid都这么热情高亢,俺也来凑凑热闹,下图是raid5的示意图,一般情况下,我们使用这张图所示的构建原理,可以对一些硬件受损的raid进行恢复,但是在工业实现上raid可能有许多种不同的实现,会存在许多变种,完全按照这张示意图去做,你会“吃药”的。而且虽然目前有一些恢复raid的工具,但是工具也不一定可以完全解决全部问题。
最近恢复一个非完全标准的raid5,这个案例虽然不能涵盖所有非标准的raid5重建的问题,但是对今后遇到类似的问题还是可以借鉴一下的。
最近,遇到一个raid重建的问题:因为一次停电事故,公司的服务器坏了,(COMPAQ proliant DL380型,4块硬盘用Compaq Share LVD Cage 4 Drives做的硬件raid)硬件的raid卡坏了,晕啊!公司的网站,客户资料都在上面啊,还没有备份!所以必须要恢复上面的数据,于是我们开始我们的raid之旅。
首先,当然是对组成raid的四块硬盘按顺序进行备份,我们用linux下面的dd,或者是winhex的clone disk功能完成硬盘备份的工作,然后我想到的是使用工具重建raid,我们选用runtime公司出品的raid reconstructor和R-TT公司的R-STUDIO工具进行恢复。但是令我们失望的是:这两个工具并没有能够识别出我们的raid。
我们看红笔标出的部分,显然raid reconstructor不认为这是一个raid,用R-STUDIO也得到了同样的结果。晕,那只好看一看磁盘的校验情况了,幸好raid reconstructor内置了一个异或校验功能,于是我们校验一把,结果如下:
嗯,我们看到除了开头有一部分没有通过校验外,硬盘的其他部分都通过了异或校验。那么,开头部分没有通过异或校验的部分又是什么呢?我们用winhex打开一个磁盘镜像看看:
我们注意到一个不寻常的问题:第一、二、四主分区是空的,第三主分区有效,分区标志是0x12,查一下fdisk,如下图,得到:12 Compaq diagnost。
再上google查一下“Compaq diagnost”,得一些E文的文章,大意是说Compaq diagnost是compaq公司的机器在硬盘头加的一个小小的校验程序,跳过即可。
Ok,接着用“55aa”找下面有没有MBR,好黄天不负我这有心人啊,在硬盘0,(按照习惯,我的硬盘编号从0开始)偏移88000h处:
显然是一个主分区(NTFS),一个扩展分区,注意我单独划出来的20000000,根据intel的高位在后,低位在前的规则应是20h,也就是说在虚拟的raid镜像中这个扇区后32个扇区(32=20h)应该就是NTFS的boot扇区。再看,硬盘1的偏移88000h处:
嘿嘿,NTFS的boot区,这就强烈的向我们暗示:硬盘的raid是从88000h处开始的,每个数据块的大小是:200h*20h=4000h,即32个扇区16384字节!
好,我们就把所有硬盘自88000处至镜像文件结尾处另存为另一组镜像,然后再用raid reconstructor和R-STUDIO工具进行恢复。天哪,不可思议的事发生了,竟然结果还是:
晕,我已经开始怀疑它是不是一个raid了。但是还记得上面我们做的异或校验吗?异或校验的结果强烈的暗示我们——这就是一个raid!可是为什么?为什么有这个结果呢?
现在让我们冷静的想一想,还有什么问题我们忽略了吗?Ok,重建raid有几个重要的参数:
1、raid的序列,没有正确的序列,重建raid是不可能的,但是我们的的确确是按照原始物理硬盘在阵列中的位置做的镜像,所以这个参数我们假设一定是正确的。
2、从文章开头的那幅raid示意图可以看出另一个参数是数据块的大小,这个我们也已经算出来了(详见上文),所以我们默认它也是正确的。
3、另一个重要的参数我们还没有确定,那就是校验块出现的位置,或者说校验块位置的算法。据网上一些资料说compaq公司的raid校验块出现的顺序是3-2-1-0(后续)。我们也默认是对的。
4、因为还有一个“Compaq diagnost”的问题,我们把raid重建的起始位置调整为:88000h。
嗯,仔细考虑上面这4个raid重建的要点,我认为:1、2、4三点是我们手工算出来的,因此,我相信是正确的,但是3?网上资料如斯,但实际情况呢?
Raid reconstructor一共提供三种情况的测试:a、0-1-2-3(正续)b、3-2-1-0(后续)c、动态盘续。我都做了,但是没有一个正确,这又是为什么呢??看来只能手工做一下校验块出现的位置了。
看一下硬盘2和硬盘3的88000h处的情况吧:
呵呵,显然硬盘2中的数据块已经是MFT表中的数据了,MFT表是NTFS文件系统的主文件分配表,记录了文件系统中每个文件,一个文件记录有1k大小,总是以“FILE*”开头。而且MFT占用硬盘中的一块连续空间,没有碎片!(更详细的请看http://linux-ntfs.sourceforge.net/ ),因此,显然硬盘3中那个数据块不是以“FILE*”开头的是校验块!好,我们至少已经找到一个校验块了,而且对怎样找校验块好像也有点思路了(检查数据块是不是以“FILE*”开头)。那么然后呢?既然数据块大小是4000h,那么接下来应该就去看8c000h处了。
哦,太令我们失望了,怎么四个盘的块都是以"File*"开头的呢?难道没有校验块?!
让我们仔细想想 开头的,而为了保证校验通过,校验块这个位置的数据也一定是“FILE*”!(如果这里不懂您可以查一下raid的基本原理)
好吧!现在我是多么热爱奇数个硬盘组成的raid啊!可惜我们这个raid是有四个硬盘组成的,不光是不能以"File*"这个值去查找校验块,而且会在特定位置出线队定值都不能利用了,(想一想,既然“FILE*”在劫难逃,其他的值又有什么理由幸免呢?)好了原理想通了,我也江郎才尽,黔驴技穷了。 嗯,现在让我们不抱任何希望的再回头看一眼吧。。。。。。。。。。
等等,你想到了什么?
我说过:在特定位置出现的定值是不能利用了,但是在特定位置出现的不定值我们还是可以利用了,什么?你说因为是不定值所以没有办法判定是数据块还是校验块,嗯,你说的有点道理,对于数字你可能是对的,但是,我们想想:计算机中字符也是用二进制数据表示的。呵呵,现在你想到什么了?我想到了文件名!
呵呵,"文件名"!多么亲切的名字在啊!对于我们可读,而由于每个file record中的文件名都是不同的,所以校验盘上一定是一串乱码,我想我们应该能很容易的从一堆文件名中找出一个乱码,嘿嘿,好!很好! 复习一下MFT中file record的格式,请看一下:http://linux-ntfs.sourceforge.nt/。标准属性记录0x30个直接,属性列表记录0x60个字节,所以一般情况下:文件名长度在本file record偏移E8的位置上,文件名开头在file record偏移EA的位置上,说干就干,写一个程序看看: 代码截图如下:
好,在XP下用VC6.0编译通过,执行上述程序的结果如下:
你发现了这些红笔划出的内容中的相关内容绝对不是windows的文件名!我现在终于明白为什么raid reconstructor和R-STUDIO不能处理这个raid了!因为这里多了一个参数!校验块出现的顺序的确是后续的,但是并不是前一个校验块是an,这一个校验块就是a(n-1)了(就像本文开头的那张示意图中的情况),而是连续在一块盘中出现16个校验块后校验块才转移到下一个硬盘上去。这一点是任何文献上都没有讲过的。而我们看看raid reconstructor,它只为我们提供了两个参数:数据块大小和盘续,但是重要的是,校验块大小是否与数据快大小相等呢?
是的,没有,该软件没有提供这一参数,一般默认这两个是相等的,但是,不幸的是我们这个例子中这两个参数恰恰是不相等的!所以,你现在明白为什么raid reconstructor不能处理我们这个案例了吧!
R-STUDIO的问题和raid reconstructor基本一致,恕我不再复述。好了,现在我们可以写一个程序把它挖出来了。
代码:
补充最后一行:
cout << "OK! The raid have been reconstructed!" << endl;
return 0;
} |
|