📜 ⬆️ ⬇️

A tale about how a fake RAID 0 crashed

... or, more precisely, how I recovered data from my nVidia RAID 0.

Outset

Actually, the prelude. The computer lives at my home, the IDE controller is implemented in nVidia MCP65. This controller has an option that turns it into a RAID controller with support for RAID 0 and RAID 1. In my case - RAID 0 of two Samsung 250 GB each. In general, nothing supernatural, it was difficult to surprise with on-board RAID 5 years ago, not like in our time. If someone is interested in the prefix "fake" - so it is called semi-hardware implementation of RAID. Let's sort on the fingers.

In operating systems such as Windows 2003 or, say, Debian Lenny GNU Linux, it is possible to implement a software RAID array using OS. In the first case, this will be the conversion of disks into so-called dynamic disks and manipulation with partitions existing on them, in the second - for example, the use of LVM utilities (in general, also “like” dynamic disks). Lack of need for additional controllers, use of processor power and RAM for operation, etc.

On the other side of the village - hardware implementations, say, Intel SRCSATAWB : up to 16 SATA drives, RAID levels up to 60, controller costs - about 15,000 rubles ... Compared to the first case - removing the load from the processor and RAM, hardware implementation, costs for the purchase of the device.
')
The concepts of “hardware RAID” and “software RAID” are counter, that is, they are opposite to each other, but they allow intermediate variants to exist, whose common name is “semi-hardware RAID”, or “fake RAID”. As if part of the work of such a RAID is delegated to the driver in the OS. In fact, almost all work is delegated: fake RAID'u can only pretend to be a rag (RAID'om), saying OSes, we say that the PC does not have 2 disks, but 1, but 2 times more, and require firewood for work, but to engage in basic monitoring of disks, slyly throwing out disks from the RAID array (however, it is also the responsibility of hardware RAID); the rest is the implementation of the functionality of RAID 0, RAID 1, RAID 5 (underline the necessary) the driver of the RAID controller. By the way, this is IMHO and the main identification sign of fake RAID - if such a device is not able to decide and make money in any system using the standard IDE driver, presenting it as a single drive, but it functions exclusively using its own personal driver - fake, “fake”, horn and hooves ...

Uh-uh ... So, the prelude. =) Zaimev at my disposal from my native technical department left a “non-working” WD disk of 400 GB left by the client, I made the decision to look again at some fresh Linux distribution. The choice this time fell on Ubuntu 9.04 x86. On the already configured system, I poked myself to try to access my fake RAID. I did not remember the name of the utility that I used last year (however, later I remembered - dmraid), but in a couple of minutes I googled another software - mdadm . I found software in Ubuntyatnik, installed it, began to figure it out, came across somewhere in Google saying that “it would be nice to restore the space reserved by the drive for HPA ”. It is said - done (with the help of Victoria ). As it turned out - in vain. =)

This is what I love RAID for - this is for certainty. If the disk fell out of the RAID 0 array, the maximum that you can try is to check whether the screw has contact with the power supply and the controller / motherboard. So it is with me: the disks are connected, but in the RAID BIOS only one of them is in the array. Options for action - delete the array.

In the end I had: remote RAID 0, disabled RAID-BIOS, two working screws of 250 gigabytes each with data available on them (i.e. smeared on both screws), 400 GB boot screw with Ubuntu installed on it, and the same desire to restore the acquired "overwork".

Action

In principle, there is nothing difficult in recovering data from RAID 0, if the cause of array degradation is not the failure of one of the drives, but only the dismantling of the array manually (for example, with the assistance of the human factor, as in my case). All the data is in place, perhaps with the exception of the information about the array itself (which, however, in digital form, is no longer necessary to recover data from the array); the main thing is to remember how RAID 0 is organized, what MBR and Partition Table are , to collect data to restore the structure of the array and merge the data from the disks.

The data recovery algorithm in my case turned out to be the following:
1. Find out which of the 2 disks is the first in the array, and which is the second.
2. Find out the stripe size in the array.
3. Take advantage of the software, which will accept this data as the source, and the output will give the recovered data (or will give a more or less simple option to access them).
4. Access the recovered data.
And all this is desirable to do in a Linux environment - for fun. =)

Let's sort the points in order.

one.
The data in a RAID 0 array of two drives are written to each of the disks in turn by blocks equal to the entire array (stripes).

For example:
the first X Kb is on disk 1 by LBA offset Y (for simplicity, we can take that Y = 0 - this will be 0 disk sector; I merged a specific disk partition, and Y turned out to be equal to the initial sector number of this section),
following X Kb - to disk 2 at the same offset Y,
the following X Kb - to disk 1 at the offset Y + 1 * (X / 512),
the following X Kb - to disk 2 at the offset Y + 1 * (X / 512),
the following X Kb - to disk 1 at offset Y + 2 * (X / 512),
the following X Kb - to disk 2 at offset Y + 2 * (X / 512),
the following X Kb - to disk 1 at offset Y + 3 * (X / 512),
the following X Kb - to disk 2 at offset Y + 3 * (X / 512),
...

Determine which of the disks is the first one by looking at the zero sector of both disks in the hex editor: in this case the MBR of the array with all its MBR signs will be in the zero sector of the first disk: signature “55AA” at offset 510 ( 1FEh) byte zero sector, the text a la "Invalid partition table"; whereas in the zero sector of the second disk, none of this will almost certainly be the case.

sudo dd if=/dev/sdb of=/home/f/mbr01 count=1
sudo dd if=/dev/sdc of=/home/f/mbr02 count=1
ghex2 /home/f/mbr01
ghex2 /home/f/mbr02


In my case, the first disk of the array was / dev / sdb, the second - / dev / sdc. Below this order of devices will be used.

2
I vaguely remembered that the size of the stripe of my array was 64 Kb. However, verification was needed.

It is not too difficult to verify this, but it is more troublesome than paragraph 1. For analysis, it took the dumps, similar to those made in paragraph 1, only larger volumes - 32 MB each (65536 sectors).

sudo dd if=/dev/sdb of=/home/f/dump01 count=65536
sudo dd if=/dev/sdc of=/home/f/dump02 count=65536
ghex2 /home/f/dump01
ghex2 /home/f/dump02


It makes sense to start with the maximum stripe size - as a rule it is 64 Kb. Transferring the number 65536 to the hexadecimal number system (in the hexadecimal editor, the offset is displayed naturally in it), we get 10000h. Moving over offsets that are multiples of this number, we are convinced of the following: the data directly above these offsets look visually very different from the data immediately below these offsets.
image
Of course, at these offsets you may come across (especially at the beginning of the dump) such pictures when everything is filled with zeros, or vice versa, the entropy above and below the data offset is so high that it is impossible to conclude whether this shift is the beginning of a new stripe.
image
In the hex editor, you should find the offset data area that is a multiple of the stripe size (10000h), in which you can navigate and draw a conclusion.

Having received confirmation that we see sharp transitions at offsets multiple to 10000h, as if part of the data were missing (and at this offset it would almost certainly be so), the next step we put forward the assumption that we could be 2 times less - 32 Kb or 8000h. Repeat the above operation for a given offset size. If we find several offsets that have the same effect - changing the data pattern at the offset boundary - we conclude that the stripe size can actually be 32 KB ... Reduce the estimated stripe size by 2 times - and repeat ... We stop in that case when we stumble upon at least one confirmation of the fact that with the current estimated stripe size at least one offset, we found data for which with a high degree of probability the part under the offset is a continuation of the part over the offset, etc. In other words, we see a clearly continuous sequence of data. This is especially noticeable in the case when we stumbled upon the contents of a text file. In this case, we discard the current size of the stripe and return to the previous version of the stripe size, which is 2 times larger, and especially carefully check this option: a text document or clearly consistent information (of course, this does not concern the sequence of zeros, as well as the chaotic debris) at the boundary of the displacements should not be found, otherwise you should increase the size of the stripe by another 2 times.

In my case, the stripe size was confirmed - 64 Kb, or 128 sectors. Below this number will be used.

3
A Google search for a ready-made solution did not give anything either on the Windows software or on the Linux software: maybe it was looking bad, maybe it was too drunk (which, however, is the same). Accordingly, I decided that the most appropriate way would be to build a single file-image of the disk (array), and then somehow figure it out. I, an employee of the technical department, borrowed the media for recording the image in the warehouse of the company, where I have the honor to work, to comrade tozx - hello to you, my friend! =)

I had to remember my poor script skills in Perl:

#! /usr/bin/perl

use strict;
use warnings;

my $innnum = 0; # -, ex-
my $outnum = 0; # -, -
my $multipler = 128; # ;
my $lbasize = 488395008; # ex- , ( 128 )
my $timert1 = 0; #
my $timert2 = 0; #

while ($lbasize - $innnum >= $multipler) #
{
system ("dd if=/dev/sdb of=/media/recovery/image count=$multipler skip=$innnum seek=$outnum 2> /dev/null");
$outnum += $multipler;
system ("dd if=/dev/sdc of=/media/recovery/image count=$multipler skip=$innnum seek=$outnum 2> /dev/null");
$outnum += $multipler;
$innnum += $multipler;
$timert1++;
$timert2++;
if ($timert2 == 256) { #
$timert2 = 0;
print ("$innnum OF $lbasize\n");
}
if ($timert1 == 16192) { # ,
$timert1 = 0;
print ("So hot! Sleeping for 33 sec...\n");
sleep (33);
}
}
print ("DONE.\n");


The size of a single disk in sectors can be found out with the help of Victoria, or by looking at the label on the disk (LBA).

four.
Here is a recipe for mounting the HDD image, which I used, with minor changes:

sudo losetup /dev/loop0 /media/recovery/image
sudo fdisk -lu /dev/loop0


We get to the terminal a list of sections found in the image. In my case:

/dev/loop0: 500.1 , 500116488192
255 heads, 63 sectors/track, 60802 cylinders, 976790016
Units = of 1 * 512 = 512 bytes
Disk identifier: 0xdf39af97

- Id
/dev/loop0p1 * 2048 83891429 41944691 7 HPFS/NTFS
/dev/loop0p2 83892224 488395055 202251416 7 HPFS/NTFS


For the desired section (in my case I was interested in the second section), we take a number from the “Start” column, multiply it by the sector size (512), getting 42952818688, and we drive in the command:

sudo losetup -o42952818688 /dev/loop1 /dev/loop0


Next, it remains to mount the device / dev / loop1 as a partition with the appropriate file system (do not forget to create a directory for the mount in advance):

sudo mkdir /media/yuppi
sudo mount -t ntfs -o ro /dev/loop1 /media/yuppi


Afterword


"On everything about everything" spent four evenings. The copying of 500 GB (250 GB from disk) took almost a day - the speed is affected by the fact that the script reads 64 KB from the disk, for each reading you need to call the system command. The read speed was ~ 15 MB / s. To speed up the operation, the pearl barley script can be improved by adding 2 buffer arrays of several megabytes each (one for each physical disk) into which to read data from the disks, and after reading it, disassemble the data from these buffers into an image file. But it was too lazy to spend time - it would take me more time to realize this possibility in pearl than slow copying in the way I described.

Should I mention that nothing is lost ... =)

Successes.

Source: https://habr.com/ru/post/67229/


All Articles