Full System Backup (and restore)
I thought I’d play around with backups as a continuation of my btrfs experiment. Well basically btrfs can’t do it without dd’ing the entire drive as the UUID’s can’t be changed.
So I thought I’d stick to ext4, and I’ve finally figured out how to do full root filesystem backup including LUKS encryption (without LUKS its easy, you could even do it with tar) using rsync of just the files instead of using dd to backup every bit (17Gb of files instead of 64Gb drive size in my case).
All of the backup section can be done from a live running system.
- Backup the filesystem UUID’s:
blkid > uuids.txt
- Backup full MBR (446 boot sector + 64 partition table + 2 sig) and extended partition info:
dd if=/dev/sda of=mbr.img count=1 bs=512
sfdisk -d /dev/sda > sda.sf
- rsync the root filesystem to a remote server, or external disk, whatever. Obviously only do this to an encrypted filesystem as you’re copying the unencrypted files:
rsync -avp -P --numeric-ids --delete --delete-excluded \
--exclude-from=excludes.txt / root@ip:/path/
My excludes.txt file looks like this:
# Include
+ /dev/console
+ /dev/initctl
+ /dev/null
+ /dev/zero
# Exclude
- /dev/*
- /proc/*
- /sys/*
- /tmp/*
- /media/*
- lost+found/
- .gvfs/
- .ccache/
That’s the backup done, now to restore to a new disk, do all of this from a live CD, you’ll have to scp the mbr.img and sda.sf files across.
- Restore the MBR and partition info to a new blank disk:
dd if=mbr.img of=/dev/sda count=1 bs=512
sfdisk /dev/sda < sda.sf
If you want to restore just the boot sector and not the partition table, for example if your disks are different sizes, just change the block count, but you’ll have to use fdisk to create the partitions then:
dd if=mbr.img of=/dev/sda count=1 bs=446
- You’ll have to format the filesystems and setup LUKS, but you don’t need to create the partitions using fdisk:
mkfs.ext4 /dev/sda1
cryptsetup luksFormat /dev/sda2
cryptsetup luksOpen /dev/sda2 sda2_crypt
mkfs.ext4 /dev/mapper/sda2_crypt
Now for the complicated part. If you just dd the entire disk, then all the partitions would keep the same UUID’s, but as we’ve created new partitions on a blank disk, we have to reset them to the values we captured in #1, this is the part that’s not possible on btrfs.
- Reset LUKS UUID - for this your boot CD will need to have a newer cryptsetup than 1.1.3 found on F14 which doesn’t have the ability to change UUID, cryptsetup 1.3.1 as on F16 LiveCD worked here:
cryptsetup luksUUID /dev/sda2 --uuid=12c92874-51ee-11e1-9c56-001d7d00626d
- Reset root (/) ext4 partition UUID:
tune2fs /dev/mapper/sda2_crypt -U 19086ed4-51ee-11e1-864d-001d7d00626d
- Reset /boot ext4 partition UUID:
tune2fs /dev/sda1 -U 23162d3a-51ee-11e1-b203-001d7d00626d
- Finally we need to reinstall grub (I’m not sure why as we used dd on the MBR). So we mount root, and inside that mount /boot, and as we’re not backing up /dev, we need to mount the live CD’s /dev inside root too, then make that a chroot:
mount /dev/mapper/sda2_crypt /mnt
mount /dev/sda1 /mnt/boot
mount --bind /dev /mnt/dev
chroot /mnt
grub-install /dev/sda
That’s it, done. Reboot into your cloned system.
Update: If you have an encrypted swap partition, on first boot you’ll also need to run something like:
cryptsetup luksOpen /dev/sda3 sda3_swap
mkswap /dev/mapper/sda3_swap -U 9421cbe2-559f-11e1-9ec6-001d7d00626d
I’ve just restored my desktop machine into a VirtualBox VM using this method, including shrinking the disk from a 64Gb SSD to a 40Gb virtual disk (as only about 17Gb was used) and it works fine - encrypted swap and root (ext4).
On first boot I made some small modifications to /etc/hosts
and /etc/sysconfig/networks
to change IP, mac and hostname, and deleted /etc/udev/rules.d/70-persistent-net.rules
so it would rescan for eth0 on reboot.
I also ran nvidia-installer --uninstall
and deleted /etc/X11/xorg.conf
to reconfigure Xorg. Of course if I rsynced the physical machine to the VM, I’d have to redo these steps again, so I’ve added some files to excludes.txt (such as guest additions).