flogiston

Blog

Try to recover from a failed Raspberry PI SD card

· admin · Dev, Linux, Raspberry Pi

So my raspberry pi would no longer start.  After some investigation I could only conclude that the SD card became corrupted.  It would initially start but it would hang somewhere halfway.  I would see new log entries when I added/removed usb deviced but it would not continue to boot.

So I first created an Ubuntu Live usb stick as described here: https://www.ubuntu.com/download/desktop/create-a-usb-stick-on-windows

As luck would have it my SD card reader was broken, so I had to borrow another one. Misery loves company!

Then I tried to repair the disk, but it kept on failing.

$ sudo fsck -v /dev/sdX2
fsck from util-linux 2.20.1
e2fsck 1.42.9 (4-Feb-2014)
sd-ext: recovering journal
Superblock needs_recovery flag is clear, but journal has data.
Run journal anyway<y>? yes
fsck.ext4: unable to set superblock flags on sd-ext


sd-ext: ********** WARNING: Filesystem still has errors **********

The next step was to create a (file) image of the SD Card:

sudo dd if=/dev/sdX of=/media/flogiston/SomeDrive/data/raspberry-complete.img
    • sdX=> the value from X can be derived by doing a df -h before and after plugging in the corrupted sd card
      That will give you a list of devices.  Your new device may look like this:
      /dev/sdh1        56M   20M   37M  36% /media/flogiston/boot
      /dev/sdh2        15G  3,9G   10G  28% /media/flogiston/c1398422-7a7c-4863-8a8f-45a1db26b4f2

=>

    • As you can see the value of X is h in my case.  Do NOT use /dev/sdh2, just use /dev/sdh in the example above.  This will ensure that you will copy all partitions into the image
  • /media/flogiston/SomeDrive/data => replace with path were you want your image to be saved

This may take a while.  The larger your SD card, the longer this will take.  Think half an hour or more.  Time to get a coffee or some rest.

After your image has been created you can now fix it.

  • Determine the starting block of each partition
parted /media/flogiston/SomeDrive/data/raspberry-complete.img unit B print

This will look a bit like:

Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start      End           Size          Type     File system  Flags
 1      4194304B   62914559B     58720256B     primary  fat16        lba
 2      62914560B  15811477503B  15748562944B  primary  ext4

Set up a loop device for each of the partitions:

use the Start bytes from the parted cmd to set up the loop devices:

➜  ~ sudo losetup -o 4194304 /dev/loop2 /media/flogiston/SomeDrive/data/raspberry-complete.img
➜  ~ sudo losetup -o 62914560 /dev/loop3 /media/flogiston/SomeDrive/data/raspberry-complete.img

Now we can repair the image

sudo fsck -y /dev/loop2
sudo fsck -y /dev/loop3

This could look a bit like:

➜  ~ sudo fsck -y /dev/loop2
fsck from util-linux 2.27.1
fsck.fat 3.0.28 (2015-05-16)
/dev/loop2: 64 files, 2519/7161 clusters
➜  ~ sudo fsck -y /dev/loop3
fsck from util-linux 2.27.1
e2fsck 1.42.13 (17-May-2015)
/dev/loop3: recovering journal
Clearing orphaned inode 525978 (uid=107, gid=65534, mode=0100755, size=5)
Setting free inodes count to 830406 (was 830407)
Setting free blocks count to 2769926 (was 2769152)
/dev/loop3: clean, 134362/964768 files, 1074938/3844864 blocks

Detach the image associated with the specified loop devices

➜  ~ sudo losetup -d  /dev/loop2
➜  ~ sudo losetup -d  /dev/loop3

Now the image should be repared.  We no longer trust the old SD card and use a brand new one to copy the repared image to:

sudo dd if=/media/flogiston/SomeDrive/data/raspberry-complete.img of=/dev/sdh

If you are out of luck, then the new SD card is a few bytes smaller then the other one.  You will have to truncate the image (shave off some bytes at the end) to make it fit.

dd: writing to '/dev/sdh': No space left on device
30449665+0 records in
30449664+0 records out
15590227968 bytes (16 GB, 15 GiB) copied, 3830,5 s, 4,1 MB/s

I guess I was out of luck ...

sudo apt install dcfldd
sudo apt install gparted
➜  ~ sudo losetup -o 62914560 /dev/loop3 /media/flogiston/SomeDrive/data/raspberry-complete.img
➜  ~ sudo gparted /dev/loop3     

gparted starts. Select the the /dev/loop3 partition and select Partition menu, Resize/Move . Change the value of "New Size" so that it is slightly below the maximum size. Eg. 100MB free space. Resize, apply all operations and wait. Wait. Wait!

DO NOT close the window after it is finished.  When complete, it will display the new size. Make sure you write down the new size before you close the window.  If you don't see, it, click on details and drill down to the new size (a line like "resize2fs -p /dev/loop3 14980096K") where the number in K is the new size in kilobytes.

Now remove the loopback device for the second partition, create a new loopback device for the whole image and edit the partition table to reflect the new smaller size:

sudo losetup -d /dev/loop3
sudo losetup /dev/loop3 /media/flogiston/SomeDrive/data/raspberry-complete.img
sudo fdisk /dev/loop3
d
2
n
p
2
122880
+14980096K
w
➜  ~ sudo fdisk -l /dev/loop3        
Disk /dev/loop3: 14,7 GiB, 15811477504 bytes, 30881792 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: 0x000c45c9

Device       Boot  Start      End  Sectors  Size Id Type
/dev/loop3p1        8192   122879   114688   56M  c W95 FAT32 (LBA)
/dev/loop3p2      122880 30083071 29960192 14,3G 83 Linux
➜  ~ sudo losetup -d /dev/loop3
➜  ~ truncate -s $(((30083071+1)*512)) /media/flogiston/SomeDrive/data/raspberry-complete.img
sudo dcfldd if=/media/flogiston/SomeDrive/data/raspberry-complete.img of=/dev/sdh

Eject your new SD card, plug in to your Pi and reboot... Fingers crossed!

Source: http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php
Source: https://www.raspberrypi.org/forums/viewtopic.php?t=19468