Raspberry backup

Tools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Partition
parted
partx, kpartx
fdisk, cfdisk

# Device
lsblk
blkid

# Filesystem
mount, umount
mkfs.vfat, mkfs.ext4
dump, restore
dumpe2fs
resize2fs
e2fsck

Insert sdcard to usb slot

Use sudo disk -l or sudo lsblk to checkout disk name, for example /dev/sda.

/dev/sda1 is the boot partition, which is fat32. /dev/sda2 is the root partition, which is ext4.

Prepare directories

1
2
3
4
5
6
mkdir backupimg/
mkdir backupimg/src_boot
mkdir backupimg/src_root
mkdir backupimg/dst_boot
mkdir backupimg/dst_root
cd backupimg/

Mount source disk

1
2
sudo mount -t vfat -o uid=pi,gid=pi /dev/sda1 ./src_boot    # Mount boot partition
sudo mount -t ext4 /dev/sda2 ./src_boot # Mount root partition

Then use sudo df -h to check it.

pi.img: Create empty file

Use df -h to checkout size of /dev/sda1 and /dev/sda2, caculate FILESIZE=/dev/sda1.Size+/dev/sda2.Used. It’s a good idea to add more size to FILESIZE, e.g. 1G.

Then create an empty file(example with FILESIZE=5G):

1
2
# bs*count = FILESIZE = 5G
sudo dd bs=1M count=5120 if=/dev/zero | pv -s 5G | sudo dd bs=1M of=./pi.img

pi.img: Make partitions

Use sudo fdisk -l /dev/sda1 to checkout start and end sector of /dev/sda1 and /dev/sda2.

1
2
3
sudo parted pi.img --script mklabel msdos
sudo parted pi.img --script mkpart primary fat32 8192s 122479s # 8192s/122479s is start/end sector of `/dev/sda1`
sudo parted pi.img --script mkpart primary ext4 122880s -1 # 122880s is start sector of `/dev/sda2`, -1 is the last sector of device

After parted, use sudo parted pi.img --script print free to double check.

pi.img: Create loop device

1
2
3
4
sudo losetup -f --show pi.img                   # Create loop device with pi.img
sudo kpartx -va /dev/loop0 # Create device map with partition tables of /dev/loop0
sudo mkfs.vfat -n boot /dev/mapper/loop0p1 # Format boot partition
sudo mkfs.ext4 /dev/mapper/loop0p2 # Format root pratition

Check /dev/mapper/loop0p1 and /dev/mapper/loop0p2, or use sudo lsblk.

pi.img: Mount filesystem

1
2
sudo mount -t vfat -o uid=pi,gid=pi /dev/mapper/loop0p1 ./dst_boot/    # Mount boot partition
sudo mount -t ext4 /dev/mapper/loop0p2 ./dst_root/ # Mount root partition

Clone

1
2
3
4
5
6
7
sudo cp -rfvp ./src_boot/* ./dst_boot/                  # Copy boot files

sudo chown -R pi:pi dst_root
sudo rm -rf dst_root/*

cd dst_root/
sudo dump -0auf - ../src_root/ | sudo restore -rf - # Dump filesystem from `src_root/`, and restore to `dst_root/`

On success DUMP IS DONE will be printed out. If there is Broken pipe error, use df -h to check if Avail of /dev/mapper/loo0p2 greater than Used of /dev/sda2.

Modify boot/fstab

Use sudo blkid to check PARTUUID of boot partition and root partition, print info as below:

1
2
/dev/mapper/loop0p1: SRC_TYPE="msdos"   LABEL="boot"    UUID="755C-729C"    TYPE="vfat" PARTUUID=="af2f8761-01"
/dev/mapper/loop0p2: UUID="xxx" TYPE="ext4" PARTUUID=="af2f8761-02"

Modify ./dst_boot/cmdline.txt as below:

1
2
## Set root=PARTUUID=af2f8761-02
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=af2f8761-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

Modify ./dst_root/etc/fstab, as below:

1
2
3
4
5
## Mount boot partition to '/boot'
## Mount root partition to '/'
proc /proc proc defaults 0 0
PARTUUID=af2f8761-01 /boot vfat defaults 0 2
PARTUUID=af2f8761-02 / ext4 defaults,noatime 0 1

Cleanup

1
2
3
4
5
sudo umount /dev/mapper/loop0p1 /dev/mapper/loop0p2 /dev/sda1 /dev/sda2
sudo kpartx -d /dev/loop0
sudo losetup -d /dev/loop0

sudo rm -rf src_boot src_root dst_boot dst_root