Backup of RPI Installation

Motivation

While experimenting with the Raspberry Pi (RPi) it is not unlikely to end up with an installation which is no longer functional. If at all possible, undoing the changes to recover from a faulty installation may be cumbersome and time consuming. In such a situation having a working backup copy will be welcome.

A workflow how to create such a backup copy (image) is described here.

Workflow

A working installation (OS + other programs) of the RPi is stored on a SD-card denoted SD-card#1. SD-card#1 has a maximum capacity of C1 GB of which only U1 GB are used. Hence we have:

U1 < C1

(tool gparted may be used to find the amount of storage U1 actually used as compared to the maximum capacity C1)

To backup the content of SD-card#1 on another SD-card denoted SD-card#2 we consider the following cases:

  • case#1: The maximum capacity C2 of SD-card#2 equals at least C1 or exceeds C1; C2 ≥ C1
  • case#2: The maximum capacity C2 of SD-card#2 is less than C1 but larger than the actually used storage U1 ; U1 ≤ C2 < C1

But regardless of case#1 or case#2, the first step will be creating an image file of SD-card#1.

SD-card#1 is inserted into the PC (Linux).

To locate SD-card#1 on the PC we excecute the fdisk utility like this:

sudo fdisk -l

Disk /dev/mmcblk0: 29,71 GiB, 31902400512 bytes, 62309376 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: 0x57785078
Device         Boot  Start      End  Sectors  Size Id Type
/dev/mmcblk0p1        8192   532479   524288  256M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      532480 62309375 61776896 29,5G 83 Linux

The output of fdisk tells us that SD-card#1 is associated with device /dev/mmcblk0 with about 32 GB memory with partitions mmcblk0p1 and mmcblk0p2.

Copying SD-card#1 to a local image file is done using utility dd (disk dump) like this:

Note: set blocksize parameter bs to some larger value than the default to speed up copying. (the default blocksize is far too small …)

sudo dd if=/dev/mmcblk0 of=~/raspi_mbi1955_backup/raspi64bit_2023_02_19.img bs=1MB status=progres

If no errors occur the image is stored in file raspi64bit_2023_02_19.img.

case#1

Considering first case#1 when SD-card#2 can store at least the same amount of data as SD-card#1.

Although there are several options I found these steps useful:

  1. copy image file (eg.: raspi64bit_2023_02_19.img) to an USB-stick
  2. clone the image file on the USB-stick to SD-card#2 using a tool like Balena Etcher (available on Windows)

case#2

The maximum capacity of SD-card#2 is less than the maximum capacity of SD-card#1. The image file must be reduced in size first. This is done with the script pishrink. Most likely script pishrink will not be part of a standard Linux installation and must be downloaded.

https://github.com/Drewsif/PiShrink

We assume pishrink has been downloaded and then copied to the user’s local ~/bin directory. Parameters and options of pishrink are obtained running this command:

sudo bin/pishrink.sh

pishrink.sh v0.1.2
Usage: bin/pishrink.sh [-adhrspvzZ] imagefile.img [newimagefile.img]


  -s         Don't expand filesystem when image is booted the first time
  -v         Be verbose
  -r         Use advanced filesystem repair option if the normal one fails
  -z         Compress image after shrinking with gzip
  -Z         Compress image after shrinking with xz
  -a         Compress image in parallel using multiple cores
  -p         Remove logs, apt archives, dhcp leases and ssh hostkeys
  -d         Write debug messages in a debug log file

I have done some experiments and found that to run pishrink successfully options -s, -v, -r or -svr had to be used:

To shrink image file raspi64bit_2023_02_19.img and store the shrinked image file as raspi64bit_2023_02_19_.img run this command:

sudo bin/pishrink.sh -s -v -r raspi_mbi1955_backup/raspi64bit_2023_02_19.img raspi_mbi1955_backup/raspi64bit_2023_02_19_.img

And this is the output:

pishrink.sh v0.1.2

pishrink.sh: Copying raspi_mbi1955_backup/raspi64bit_2023_02_19.img to raspi_mbi1955_backup/raspi64bit_2023_02_19_.img... ...
pishrink.sh: Gathering data ...
Skipping autoexpanding process...
pishrink.sh: Checking filesystem ...
rootfs: recovering journal
rootfs: 176250/1918208 files (0.3% non-contiguous), 1755559/7722112 blocks
resize2fs 1.46.5 (30-Dec-2021)
pishrink.sh: Shrinking filesystem ...
resize2fs 1.46.5 (30-Dec-2021)
Resizing the filesystem on /dev/loop16 to 2005928 (4k) blocks.
Begin pass 2 (max = 266094)
Relocating blocks             XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 236)
Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 4 (max = 19275)
Updating inode references     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/loop16 is now 2005928 (4k) blocks long.
pishrink.sh: Shrinking image ...
pishrink.sh: Shrunk raspi_mbi1955_backup/raspi64bit_2023_02_19_.img from 30G to 8.0G ...

The output of pishrink tells us that the original image file raspi64bit_2023_02_19.img has been reduced to about 8 GB and stored in file raspi64bit_2023_02_19_.img.

After shrinking the image should fit into a 16 GB SD-card#2.

We insert SD-card#2 into the PC (Linux). It is associated with device /dev/mmcblk0 as can be verified with fdisk .

The content of the (shrinked) image file raspi64bit_2023_02_19_.img is written to the 16 GB SD-card. Again command dd is used:

udo dd if=raspi_mbi1955_backup/raspi64bit_2023_02_19_.img of=/dev/mmcblk0 bs=50MB status=progress

Output...

8488911360 bytes (8,5 GB, 7,9 GiB) copied, 904 s, 9,4 MB/s
169+1 records in
169+1 records out
8488911360 bytes (8,5 GB, 7,9 GiB) copied, 904,18 s, 9,4 MB/s

Finally SD-card#2 has been analysed with gparted after expanding partition mmcblk0p1 by a small amount (again using gparted).

After inserting SD-Card#2 into RPi, booting from this SD-card (16 GB) is successful. To use the full capacity of this SD-card requires to expand the partition. This can be done with the Raspi-Config tool of RPi.


Resources:

https://beebom.com/how-clone-raspberry-pi-sd-card-windows-linux-macos/

https://github.com/Drewsif/PiShrink