While rsync is excellent for file-level backups, system restoration requires more than just copying files. The core issue lies in maintaining:
- Package manager database consistency
- Bootloader configuration
- Systemd unit states
- User/group permissions
Here's an improved workflow for Fedora systems:
# 1. Create package list before disaster
sudo dnf list installed > ~/installed_packages.txt
sudo rpm -qa --queryformat '%{NAME}\n' > ~/rpm_qa_list.txt
# 2. During restoration after base install:
sudo dnf install $(cat ~/rpm_qa_list.txt)
# 3. Rsync with proper flags
sudo rsync -aAXv --delete \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
/backup/ /
For system-wide configuration consistency:
# Compare current vs backup configs
sudo diff -r /etc/ /backup/etc/ > ~/config_differences.log
# Restore critical configs selectively
sudo cp -a /backup/etc/{passwd,shadow,group,gshadow} /etc/
sudo cp -a /backup/var/lib/yum /var/lib/
For replicating systems across hardware:
#!/bin/bash
# clone-system.sh
TARGET_DEVICE="/dev/sdX"
# Partition and format (adjust sizes as needed)
parted -s $TARGET_DEVICE mklabel gpt
parted -s $TARGET_DEVICE mkpart primary ext4 1MiB 513MiB
parted -s $TARGET_DEVICE set 1 boot on
parted -s $TARGET_DEVICE mkpart primary ext4 513MiB 100%
# Create filesystems
mkfs.ext4 "${TARGET_DEVICE}1"
mkfs.ext4 "${TARGET_DEVICE}2"
# Mount and rsync
mkdir -p /mnt/{target-root,target-boot}
mount "${TARGET_DEVICE}2" /mnt/target-root
mount "${TARGET_DEVICE}1" /mnt/target-boot
rsync -aAXv --delete \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*"} \
/ /mnt/target-root/
# Install bootloader
chroot /mnt/target-root /bin/bash -c "grub2-install $TARGET_DEVICE"
chroot /mnt/target-root /bin/bash -c "grub2-mkconfig -o /boot/grub2/grub.cfg"
umount -R /mnt/target-*
After restoration, verify:
# Check bootloader
sudo grub2-mkconfig | grep -i error
# Verify package consistency
sudo rpm -Va | grep -vE 'prelink|.build-id'
# Check critical services
sudo systemctl list-units --failed
html
While rsync excels at incremental backups, full system restoration requires careful handling of package states, configuration files, and permission structures. The common approach of overlaying backups on fresh installs often misses critical package dependencies and system metadata.
# First, preserve package states:
sudo rpm -qa > installed_packages.list
sudo dnf repoquery --installed --qf "%{name}" > explicit_packages.list
For Debian-based systems:
sudo dpkg --get-selections > package-states.list
sudo apt-mark showmanual > manually-installed.list
Use this rsync command for comprehensive backups:
sudo rsync -aAXHv --delete \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
--include="/var/lib/dnf" \
--include="/var/lib/rpm" \
/ /mnt/backup/
Create a post-restoration script to handle machine-specific files:
#!/bin/bash
# Restore network configuration
cp /mnt/backup/etc/sysconfig/network-scripts/ifcfg-* /etc/sysconfig/network-scripts/
# Rebuild initramfs
dracut --force
# Restore SELinux contexts
restorecon -Rv /
For deploying to different hardware:
# Clean up hardware-specific files before backup
sudo rm -f /etc/machine-id /var/lib/dbus/machine-id
sudo systemd-machine-id-setup
# After restoration:
sudo dnf reinstall $(cat explicit_packages.list)
sudo dnf install $(comm -23 <(sort installed_packages.list) <(sort explicit_packages.list))
Implement an automated verification script:
#!/bin/bash
# Verify critical services
systemctl list-units --failed
# Check package consistency
rpm -Va | grep -v -E '^..5'
# Verify restored files
find /etc -type f -exec rpm -qf {} \; | grep "file not owned"
For bare-metal restores, consider dd-based imaging:
# Create compressed image
sudo dd if=/dev/sda | gzip -c > /backup/system.img.gz
# Restoration:
gunzip -c /backup/system.img.gz | sudo dd of=/dev/sda