Team LiB
Previous Section Next Section

Hack 74. Clone Your Linux Install

Deploy a single installation of Linux across many computers.

Cloning is simply a method by which some data is copied exactly, from one medium to another. This can be a physical CD being copied into a CD image (such as an ISO image) or, in the case of this hack, copying a hard-disk partition into a file that can be stored for archival purposes or deployed to several machines. The use of cloning is very widespread on the Internet, with CDs and floppies being distributed as images that are just a bit-for-bit copy of the original medium. Cloning can also be used to move your Linux system to a larger hard drive.

9.6.1. Create an Image

Linux systems generally have a utility installed called dd (data dump) that can accept an input from a device and pipe the output as an exact copy of the original to another device or a file. This is the tool you should use when creating a cloned image of an installation.

First, you need to find out which partition on the hard disk contains the root filesystem. You can do this using the mount command:

foo@bar:~# mount

It should give some output similar to the following:

/dev/hda1 on / type ext3 (rw,noatime)
none on /proc type proc (rw)
none on /sys type sysfs (rw)

The entry you're looking for is the one mounted on the root filesystem, /. In this case, it is /dev/hda1. Now that you know the device for the root partition, you can use dd to clone the partition. However, it is very unwise to start trying to clone a partition while it is still mounted, because processes that are currently running on the box constantly change the data and the image produced will be inconsistent. The best method is to enter single-user mode when you boot your system, then run a command to remount the root filesystem as read-only. (Other methods are available for doing this; you could use a Knoppix boot CD and log in via a virtual terminal to run your commands, for example.)

To boot into single-user mode, you need to add the kernel argument single on startup. You can find details on how to add kernel arguments to your bootloader in [Hack #1]. If you use this method, you cannot simply unmount the root partition, as it contains the binary for dd, which you need to perform the hack. Also while a partition is being cloned, you cannot write the resulting image to anywhere on that partition, because the write process will change the partition while you are copying it. So, you need to find another partition to which you can write the image (it doesn't have to be a Linux partition, but it must have more free space than the size of the partition you are cloning). As such, create a mount point for the partition to which you are going to write the image (/mnt/foo in this example):

foo@bar:~# mkdir /mnt/foo

Then mount your destination partition on that mount point so that you can write the image to it. Another option is to use an external USB hard-disk drive and load the usb_storage module to read it. Most systems have the usb_storage module already compiled, but if yours doesn't, you need to compile it [Hack #88] . You need to have the option under Device DriversUSB supportUSB Mass Storage support set to "Compile as a module." If you have the module loaded, it appears as a SCSI device which can be mounted:

foo@bar:~# modprobe usb_storage
foo@bar:~# mount /dev/sda1 /mnt/foo

Finally, you need to sync and remount the root partition as read-only so that things cannot change when you are creating the image:

foo@bar:~# sync
foo@bar:~# mount -o remount,ro /

Now you are ready to create the image. The following command copies the contents of /dev/hda1 and places it as an image file called image.bin on the filesystem mounted on /mnt/foo:

foo@bar:~# dd if=/dev/hda1 of=/mnt/foo/image.bin

The dd command takes two arguments: if= and of=. The if= argument points to the device or file from which it is to take its input (i.e., the device you are cloning), and of= points to the device or file where you want to dump the clone. Depending on the size of your root partition, this could take a very long time, indeed. Go have a cup of coffee or tea, or watch television. When it's finished, it should tell you how many in and out records it has read and written. If it says "Input/Output error," something's gone wrong (such as a bad block on the hard disk), but all is not lost. A tool called dd_rescue will skip over the bad blocks and clone as much of the filesystem as possible. You can read more about this tool at http://www.oreillynet.com/pub/wlg/5205.

9.6.2. Restore the Image

Now you should have a large file called image.bin in the root directory of /dev/sda1 (or whichever partition you mounted on /mnt/foo). At this point, you should unmount the disk to which you wrote the image. If you used an external USB drive, you can plug it into any computer onto which you want to clone this Linux install.

To restore the image, you literally do the commands in reverse. You need a Linux boot CD of some sort (such as Knoppix, SUSE, Ubuntu, or Red Hat) and boot into a recovery mode, or gain access to a shell (Ctrl-Alt-F2 when you are in the installation portion of a distribution). Then you can load the usb_storage module again, and mount the external hard disk:

foo@bar:~# mkdir /foo
foo@bar:~# modprobe usb_storage
foo@bar:~# mount /dev/sda1 /foo

Now you need to partition the disk on the new machine using fdisk or a similar partitioning tool. A root partition and a swap partition are required. Assuming that the root partition is the first partition on the disk and the swap is the second, you need to format the swap partition using the following command:

foo@bar:~# mkswap /dev/hda2

It isn't necessary to write a filesystem to the root partition, because the image is providing a filesystem. At this point you can load the image file onto the hard disk using the dd command again:

foo@bar:~# dd if=/foo/image.bin of=/dev/hda1

As you can see, the command just reverses the source and destination of the input and output. When this is finished, you need to mount the partition and chroot into it so that you are "inside" the Linux installation:

foo@bar:~# mkdir /install
foo@bar:~# mount /dev/hda1 /install
foo@bar:~# chroot /install /bin/bash

The last line tells the system to pretend the root directory is /install, and run the bash shell upon entering it. Now you need to sort out the bootloader for the system. Most systems use either LILO or GRUB. In the case of LILO, you need to run lilo in the chrooted environment. This will write the necessary code to the master boot record:

foo@bar:~# lilo

With GRUB you need to run grub-install:

foo@bar:~# grub-install /dev/hda

If all has gone well, you can exit the chroot environment and reboot the system. It should boot up as normal.

George Wright

    Team LiB
    Previous Section Next Section