For experimental reasons I was running a RAID0 array (the speed!) off of two Sandisk Cruiser Mini USB sticks connected to a Raspberry PI.
As expected, due to wear and tear one of the flash memories eventually failed causing the array to go read-only and crash everything that was writing to it, including the array activation
Out of laziness, I didn’t want to look for and restore the lost data from its original source and preferred to simply somehow recover it, then migrate the volume to a single disk (a recycled SSD this time) and be done with it in a matter of minutes. Everything below was done on a Raspberry PI running Raspberry PI OS (so Debian) – on other Linux flavours commands and things in general may be different.
First off, examine if the disks are actually still usable (and mdadm still finds its array members on them). The raid members are partitions a single full-size partition on each of the disks – sdX1, sdY1, so I run the appropriate command:
mdadm --examine /dev/sd[X,Y]1
/dev/sdX1: Magic : a92b4efc Version : 1.2 Feature Map : 0x0 Array UUID : 41f1a962:cb87c516:45aedb09:982104cc Name : pi-raid:0 (local to host pi-raid) Creation Time : Tue May 19 18:02:01 2020 Raid Level : raid0 Raid Devices : 2 Avail Dev Size : 58683393 (27.98 GiB 30.05 GB) Data Offset : 34816 sectors Super Offset : 8 sectors Unused Space : before=34736 sectors, after=0 sectors State : clean Device UUID : abeb438f:e5d1858a:a08c75c0:6324d680 Update Time : Tue May 19 18:02:01 2020 Bad Block Log : 512 entries available at offset 8 sectors Checksum : 97b7675 - correct Events : 0 Chunk Size : 512K Device Role : Active device 1 Array State : AA ('A' == active, '.' == missing, 'R' == replacing) /dev/sdY1: Magic : a92b4efc Version : 1.2 Feature Map : 0x0 Array UUID : 41f1a962:cb87c516:45aedb09:982104cc Name : pi-raid:0 (local to host pi-raid) Creation Time : Tue May 19 18:02:01 2020 Raid Level : raid0 Raid Devices : 2 Avail Dev Size : 58683393 (27.98 GiB 30.05 GB) Data Offset : 34816 sectors Super Offset : 8 sectors Unused Space : before=34736 sectors, after=0 sectors State : clean Device UUID : 9269e3ce:d3bfe7f5:0c6954c9:cd6c26bf Update Time : Tue May 19 18:02:01 2020 Bad Block Log : 512 entries available at offset 8 sectors Checksum : fbac071f - correct Events : 0 Chunk Size : 512K Device Role : Active device 0 Array State : AA ('A' == active, '.' == missing, 'R' == replacing)
Then create images of both (or all) disks
dd if=/dev/sdX of=/disk-imageX.dd bs=10M status=progress dd if=/dev/sdY of=/disk-imageY.dd bs=10M status=progress
If the data is (somehow) important, make a copy of these images before performing any actions on them.
Since the array members are partitions on the disk images the image files are not directly usable to assemble the array, but instead will need to mount the images as loops first:
losetup –find –show –partscan /disk-imageX.dd
losetup –find –show –partscan /disk-imageY.dd
The commands returns a partitions list in the format:
/dev/loopX ... /dev/loopY
We can use fdisk to look at the disk structure and find the necessary partition identifiers:
fdisk -l ... Disk /dev/loopX: 29.25 GiB, 31406948352 bytes, 61341969 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x960b5c8f Device Boot Start End Sectors Size Id Type /dev/loopXp1 2048 58720256 58718209 28G 83 Linux ... Disk /dev/loopY: 29.25 GiB, 32015679488 bytes, 62530624 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x6fcee283 Device Boot Start End Sectors Size Id Type /dev/loopYp1 2048 58720256 58718209 28G 83 Linux
This shows that the two array member partitions are /dev/loopXp1 and /dev/loopYp1, which can be used to (re)assemble the array:
mdadm --assemble /dev/mdZ /dev/loopXp1 /dev/loopYp1
You should get a confirmation similar to:
mdadm: /dev/mdZ has been started with 2 drives.
Check that the array actually gets mounted
mdadm --detail /dev/mdZ /dev/mdZ: Version : 1.2 Creation Time : Tue May 19 17:02:01 2020 Raid Level : raid0 Array Size : 58683392 (55.96 GiB 60.09 GB) Raid Devices : 2 Total Devices : 2 Persistence : Superblock is persistent Update Time : Tue May 19 17:02:01 2020 State : clean Active Devices : 2 Working Devices : 2 Failed Devices : 0 Spare Devices : 0 Layout : -unknown- Chunk Size : 512K Consistency Policy : none Name : pi-raid:0 UUID : 41f1a962:cb87c516:45aedb09:982104cc Events : 0 Number Major Minor RaidDevice State 0 259 0 0 active sync /dev/loopXp1 1 259 2 1 active sync /dev/loopYp1
Finally mount the array to extract the data:
mount -o ro /dev/mdZ /myfolder
I mounted it read-only to avoid having any data written to the array.
When we’re done recovering the data, unmount the array and then stop it:
umount /dev/mdZ mdadm --stop /dev/mdZ