Recently my home server (a raspberry pi 3 with attached storage) has been encountering disk errors, and finally gave up on booting entirely. That’s probably because I’ve been running it 24/7 and it had a few unexpected reboots. (I should really add a physical shutdown switch someday).
First I obtained a new SD card, which should last another few years of heavy use.
Then I had the fun of remembering how to clone an SD card.
Backup the SD card
I still use the simple-but-dangerous
dd command for moving data around. It does the trick, plus there’s the thrill that comes with a risk of deleting your entire laptop accidentally.
sudo dd if=/dev/mmcblk0 of=~/backups/raspi-20181127.img status=progress
Then wait for a while, since I’m using large SD cards. The progress output is quite nice, and wasn’t always an option.
Attach the image to a loopback device
In order to do the next few steps, we want to have the disk image accessible. The loopback disk interface lets us pretend this image file is just like any other physical drive, which is awesome.
sudo modprobe loop sudo losetup -f sudo losetup /dev/loop0 ~/backups/raspi-20181127.img sudo partprobe /dev/loop0
Fix the filesystem errors
The reason I”m doing this is disk errors, so fixing them is kind of important. I can do that to the disk image, now that it’s available as a device!
Again, I’m just using low-tech tools,
fsck to the rescue.
The loop0p1 partition is the “boot” partition, and loop0p2 is the “/” partition from the pi.
sudo fsck /dev/loop0p1 sudo fsck /dev/loop0p2
I didn’t have any errors on the first partition - woo!
The second partition though, had a ton of errors - not unexpectedly. Fsck claims to have fixed them, but there were enough that I’ll need to reinstall a bunch of things later to have any confidence in the OS.
Shrink the image
This speeds up the re-copying process, and makes sure that the data will all fit on the new card.
Sometimes SD cards differ by a few kilobytes, and I’ve actually had disk copy operations fail right at the end by running out of space on the target device.
For resizing, I used
sudo gparted /dev/loop0
- Resize the last partition to be just big enough for the data, plus a bit. I eyeballed the extra.
- Apply the changes
- quit gparted
Prepare the new SD card
I had actually tried this process once earlier on this same SD card, and it ended in frustration, so I want to wipe the slate clean here.
gnome-disks tool complained about the partition table on the SD card, so I ended up sticking to what I know and using
- Start the partitioning tool:
sudo cfdisk /dev/mmcblk0
- triple-check that you’re looking at the SD card device!
- Use the arrow keys and hit enter to delete each of the existing partitions
- write the results to the device
- quit cfdisk
Copy the image to the new SD card
This is basically the reverse of the original step. Again, status update is awesome.
I’m also quite happy that I shrank the image down first to speed it up, since this took about an hour.
sudo dd if=~/backups/raspi-20181127.img of=/dev/mmcblk0 status=progress
Expand the partition
I want free space on the root partition, so once it’s got the data, use gparted on the SD card to expand the partition.
sudo gparted /dev/mmcblk0
- quadruple-check that you’re looking at the SD card device!
- resize the last partition to use all of the free space
- apply the changes
- quit gparted
Plug it into the pi!
There’s nothing left but to plug it into the pi and see it boot up.
I got the details on the loopback interface from Software Bakery