I was faced with the problem of cloning one Ubuntu server box to another. My solution is purposefully minimalist, requiring only a bootable Linux CD-ROM (I used the Xubuntu 10.04 Desktop CD-ROM) and an external USB drive to transfer the HDD data.
The procedure involves backing up and restoring the MBR, partition table and partition image files then manually tweaking hardware configuration differences. The examples are for HDD /dev/sda with a single ext3 partition and external USB backup drive /dev/sdb with an ext3 partition /dev/sdb1 — you need to adjust the drive and partition device names to match your environment.
- The MBR is reinstalled by the GRUB boot loader instead of backing up and restoring the raw 512 byte MRB sector because the existing MBR will only work if the target HDD has exactly the same geometry as the source drive.
- The target HDD’s geometry doesn’t need to match the source drive but the target drive’s capacity cannot not be less that the source drive. You can use hdparm(1) to view the drive’s parameters:
hdparm -gi /dev/sda
- Because raw partitions are involved this procedure should also work for non-Linux operating systems, but you will need to use the tools recommended by your operating system to regenerate the MBR and tweak the hardware configuration differences.
- This procedure can be used to upgrade to a larger HDD. After you’ve restored to the new disk run gparted and resize your primary partition (on the Xubuntu 10.04 Live CD you will find gparted in the Applications→System menu).
- Most of the commands require superuser privilege — logon as root or apply a sudo command prefix.
- Mount the USB backup drive:
mount /dev/sdb1 /mnt
- Backup partition table:
sfdisk -d /dev/sda > /mnt/sda-partition-table
- Backup partition — the partition must be unmounted to copy it so at this point you need to running off the Live CD.
- Copy the partition to a file sda1-image on the USB drive:
dd if=/dev/sda1 of=/mnt/sda1-image bs=1K
Instead of the last command you could reduce the partition size by first zero filling unused space and then compressing with gzip(1):
dd if=/dev/zero of=zerofill bs=1M rm zerofill dd if=/dev/sda1 bs=1K | gzip -c > /mnt/sda1-image.gz
|I found that compression saved about 40% (will vary depending on free space) but was almost 50% slower. I have plenty of space on the USB backup drive so I didn’t bother with compression.|
- Go to the target PC and boot the Live CD.
- Mount the USB backup drive:
mount -o ro /dev/sdb1 /mnt
- Restore partition table:
sfdisk /dev/sda < /mnt/sda-partition-table
If there was already a swap partition on the target HDD the Live CD may be using it and you will get a device busy message (you can check by running the swapon -s command). Use swapoff(8) to umount the swap, for example: swapoff /dev/sda5
- Restore partition:
dd if=/mnt/sda1-image of=/dev/sda1 bs=1K
Or if you compressed the partition:
gzip -cd /mnt/sda1-image.gz | dd of=/dev/sda1 bs=1K
- Write a new MBR using GRUB. You need to use the version of GRUB (GRUB Legacy or GRUB 2) used by the cloned machine. The easiest way to do this is to change root to the cloned root partition and then run GRUB in it’s native environment:
mount /dev/sda1 /mnt chroot /mnt
If you have GRUB Legacy (version 0.9x) run these commands:
grub > root (hd0,0) > setup (hd0) > quit
If you have GRUB 2 then do:
You can find some nice Ubuntu GRUB2 documentation here.
- It’s a good idea to check your restored drive with fsck:
e2fsck -f /dev/sda1
Creating partition images involves taking the source PC down and is time consuming. Instead of maintaining up to date partition images I update the restored target with the latest rsnapshot backups from an external USB drive and use rsync to restore the latest snapshot, for example:
mount -o ro /dev/sdb1 /mnt mkdir /sda1 mount /dev/sda1 /sda1 rsync -aHxv --delete --exclude /var/local/backups/ \ /mnt/backups/hosts/kestrel/hourly.0/ /sda1/
The updating is done from the Live CD as it may be undesirable to boot the target machine until it has been completely updated.
Before rebooting you need to initialize the target swap partition and update the swap UUID in /etc/fstab. If you don’t initialize the swap it won’t be mounted and you will get boot errors like unable to canonicalize swap (check for mounted swap with swapon -s). Use mkswap(8) to initialize the swap partition, for example:
mkswap(8) will print a UUID, note it down and then edit the swap entry in the target machine’s /etc/fstab file. Alternatively you could just replace the UUID name with the swap device partition name (/dev/sda5 in our example). If your fstab doesn’t use UUIDs you won’t need to change anything. You can print the partition UUID using the vol_id(8) command, for example:
You can now reboot the target machine. If your cloned drive is installed on different hardware you will need to read the next section.
Here are post restoration configuration tweaks I had to make in order to get my cloned Ubuntu 7.10 server fully operational.
Even if the target machine is be exactly the same make and model as the original the MAC address will be different. I my case the CD-ROM drive was also different. When I booted the target machine the eth0 network interface failed to come up (check this with ifconfig -a). To regenerate the correct network configuration delete the file
|This procedure varies depending on which Linux distribution you are using (see also this blog entry).|
Similarly, to regenerate the CD-ROM drive parameters delete the file
The only other configuration problem I had was an unable to iterate IDE devices: missing file or directory message when halting the PC. The problem is benign and is caused by a missing /proc/ide directory (no idea why it’s missing though). The error can be suppressed by removing the halt(8) command -h option in the /etc/init.d/halt script. My guess is that this oddity is distribution dependent.
Finally, don’t forget to exclude the modified configuration files from any subsequent rsnapshot updates you make to the cloned machine.