Raspberry Pi Backup and Restoration

Note

This article targets distributions based on debian stretch. Details may vary with different distributions and releases. Please be very careful when writing to important filesystems.

Backing up a functional Raspberry Pi can be problematic. Creating an image copy of a card works, but suffers from a number of frustrating limitations:

  1. The entire card, including any unused space, must be copied to disk. On a large capacity card, simply storing such a large image can be a problem. The image can be compressed, but can still be rather large.
  2. Writing the image from a backup requires a card of the same size or larger.
  3. Writing the image is slow, even with compressed images as the entire image, including empty space, must still be written to the card.

This page summarizes some alternate methods that can be used to work around these problems.

Copying card contents to disk

Rather than copying a byte-by-byte image of a card, we can simply copy the contents of the card to disk. This eliminates the need to allocate space for, or re-write empty space, greatly speeding up the backup and restoration process.

This procedure makes use of another Linux machine, or Raspberry Pi running booted from a different image to make a copy of the card to be backed up.

This approach has the advantage of maintaining a current backup of the original card on disk. If the procedure is repeated periodically, filesystem changes will be written to disk using rsync to copy only changed files, greatly speeding up subsequent backups.

Backup existing card

  1. Insert the card to be backed up into a card reader and insert it into a running Raspberry Pi or other Linux system. Verify that the card is recognized as /dev/sda:

    cat /proc/partitions
    

Todo

Verify 1st stage bootloader process. This isn’t consistently documented.

  1. Create directories to hold boot and / (root) partitions:

    mkdir boot
    mkdir root
    
  2. Create temporary mount points for the card partitions to be backed up:

    mkdir /tmp/sda1
    mkdir /tmp/sda2
    
  3. Mount the existing boot and root partitions to the temporary mount points for reading:

    mount /dev/sda1 /tmp/sda1
    mount /dev/sda2 /tmp/sda2
    
  4. Copy the existing boot and root partitions to the backup directories:

    rsync -qaHAXS /tmp/sda1/ boot
    rsync -qaHAXS /tmp/sda2/ root
    

Todo

Verify root permissions not needed for writing card contents with rsync.

  1. Unmount the boot and root filesystems:

    sudo umount /tmp/sda1
    sudo umount /tmp/sda2
    
  2. Remove the card reader with the original card and set the card aside for safekeeping.

Write files to new card

  1. Insert the new card to be written to into a card reader and insert it into a running Raspberry Pi or other Linux system. Verify that the card is recognized as /dev/sda:

    cat /proc/partitions
    
  2. Partition the new card using fdisk:

    sudo fdisk /dev/sda
    
  3. Create a new 100 MB boot and allocate the remaining space to the ``root` partition:

    o # clear the in memory partition table
    n # new boot partition
    p # primary partition
    1 # partition number 1
    0  # start at sector 0
    +100M # 100 MB boot parttion
    n # new root partition
    p # primary partition
    2 # partion number 2
      # default, start immediately after preceding partition
      # default, extend partition to end of disk
    a # make a partition bootable
    1 # bootable partition is partition 1 -- /dev/sda1
    p # print the in-memory partition table
    w # write the partition table
    q # and we're done
    

Todo

investigate use of parted

  1. Format boot partition with vfat filesystem:

    sudo mkfs.vfat /dev/sda1
    
  2. Format root partition with ext4 filesystem:

    sudo mkfs.ext4 /dev/sda2
    
  3. Mount the newly-formatted partitions:

    mount /dev/sda1 /tmp/sda1
    mount /dev/sda2 /tmp/sda2
    
  4. Copy the existing boot and root partitions to the backup directories using rsync:

    rsync -qaHAXS boot /tmp/sda1/
    rsync -qaHAXS boot /tmp/sda2/
    

Todo

Verify root permissions not needed for writing card contents with rsync.

Todo

Verify directories are copied correctly.

Todo

investigate –delete and –whole-file options for rsync

  1. Unmount the boot and root filesystems:

    sudo umount /tmp/sda1
    sudo umount /tmp/sda2
    
  2. Remove the card reader with the duplicate card. Remove the card and boot it to verify everything is working properly.

Direct card-to-card copy

This approach is essentially the same as the card-to-disk copy, but eliminates the intermediate copying of files to intermediate disk storage. The original card contents are copied directly to a second card.

This procedure also makes use of another Linux machine, or Raspberry Pi running booted from a different image to make a copy of the card to be backed up.

Caution

This procedure writes disk content and files with your original card mounted. Pay careful attention to the source and destinations for file writes. In this procedure, the original card will be /dev/sdb and the duplicate card will be /dev/sda.

Prepare the duplicate card

  1. Insert the new card to be written to into a card reader and insert it into a running Raspberry Pi or other Linux system. Verify that the card is recognized as /dev/sda:

    cat /proc/partitions
    
  2. Partition the new card using fdisk:

    sudo fdisk /dev/sda
    
  3. Create the new boot and root partitions on the new card.

    This procedure will create a 100 MB boot partition and allocate the remaining space to the root partition:

    o # clear the in memory partition table n # new partition p # primary partition 1 # partition number 1

    # default - start at beginning of disk

    +100M # 100 MB boot parttion n # new partition p # primary partition 2 # partion number 2

    # default, start immediately after preceding partition # default, extend partition to end of disk

    a # make a partition bootable 1 # bootable partition is partition 1 – /dev/sda1 p # print the in-memory partition table w # write the partition table q # and we’re done

  4. Format boot partition with vfat filesystem:

    sudo mkfs.vfat /dev/sda1
    
  5. Format root partition with ext4 filesystem:

    sudo mkfs.ext4 /dev/sda2
    
  6. Mount the newly-formatted partitions:

    mount /dev/sda1 /tmp/sda1
    mount /dev/sda2 /tmp/sda2
    

Backup existing card

  1. Insert the card to be backed up into a card reader and insert it into a running Raspberry Pi or other Linux system. Verify that the card is recognized as /dev/sdb:

    cat /proc/partitions
    
  2. Copy RPi boot image from existing card.

    The first 4M of a bootable image contains a boot image that must be present to boot the Raspberry Pi. Our first step is to create a copy of this 4M on disk:

    dd if=/dev/sdb of=/dev/sda bs=512 count=8192

  3. Create temporary mount points for the card partitions to be backed up:

    mkdir /tmp/sdb1
    mkdir /tmp/sdb2
    
  4. Mount the existing boot and root partitions to the temporary mount points for reading:

    mount /dev/sdb1 /tmp/sdb1
    mount /dev/sdb2 /tmp/sdb2
    
  5. Copy the existing boot and root partitions to the backup directories:

    rsync -qaHAXS /tmp/sdb1/ /dev/sda1/
    rsync -qaHAXS /tmp/sdb2/ /dev/sda2/
    

Todo

Verify root permissions not needed for writing card contents with rsync.

Todo

Verify directories are copied correctly.

  1. Unmount the original and backup filesystems:

    sudo umount /tmp/sda1
    sudo umount /tmp/sda2
    sudo umount /tmp/sdb1
    sudo umount /tmp/sdb2
    
  2. Remove the card reader with the original card and set the card aside for safekeeping.

  3. Remove the card reader with the duplicate card. Remove the card and boot it to verify everything is working properly.

In-place backup of running system to new card

Todo

Add fsfreeze instructions

Enter single-user (recovery) mode

  1. Reboot the Raspberry Pi to be backed up in single-user mode:

    sudo init 1
    

Prepare the duplicate card

  1. Insert the new card to be written to into a card reader and insert it into a running Raspberry Pi or other Linux system. Verify that the card is recognized as /dev/sda:

    cat /proc/partitions
    
  2. Partition the new card using fdisk:

    sudo fdisk /dev/sda
    
  3. Create the new boot and root partitions on the new card.

    This procedure will create a 100 MB boot partition and allocate the remaining space to the root partition:

    o # clear the in memory partition table n # new partition p # primary partition 1 # partition number 1 # default - start at beginning of disk +100M # 100 MB boot parttion n # new partition p # primary partition 2 # partion number 2 # default, start immediately after preceding partition # default, extend partition to end of disk a # make a partition bootable 1 # bootable partition is partition 1 – /dev/sda1 p # print the in-memory partition table w # write the partition table q # and we’re done

Todo

Replace with:

# Create partition table parted $DEST/ClusterHAT-$VER-lite-$REV-usbboot.img –script – mklabel msdos parted $DEST/ClusterHAT-$VER-lite-$REV-usbboot.img –script – mkpart primary fat32 0% 64M parted $DEST/ClusterHAT-$VER-lite-$REV-usbboot.img –script – mkpart primary 64M 100%

  1. Format boot partition with vfat filesystem:

    sudo mkfs.vfat /dev/sda1
    
  2. Format root partition with ext4 filesystem:

    sudo mkfs.ext4 /dev/sda2
    
  3. Mount the newly-formatted partitions:

    mount /dev/sda1 /tmp/sda1
    mount /dev/sda2 /tmp/sda2
    

Backup existing card

  1. Insert the card to be backed up into a card reader and insert it into a running Raspberry Pi or other Linux system. Verify that the card is recognized as /dev/mmcblk0:

    cat /proc/partitions
    
  2. Copy the existing boot and root partitions to the backup directories:

    rsync -qaHAXS /boot/ /dev/sda1/
    rsync -qaHAXS --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} / /dev/sda2/
    

Todo

Verify root permissions not needed for writing card contents with rsync.

Todo

Verify directories are copied correctly.

  1. Create the system folders:

    for NAME in /dev /proc /sys /tmp /run /mnt /media; do sudo mkdir /mnt/sda2/${NAME}; done
    
  2. Shut down the original system:

    sudo shutdown -h now
    
  3. Remove the card reader with the duplicate card. Remove the duplicate card and swap it with the original card, then boot it to verify everything is working properly.

Contact and feedback

You can find me on Reddit where I lurk in many of the raspberry pi-related subreddits.

Last updated on Oct 23, 2018