Archive

One Disk To Another


Introduction

Usually when one gets some new hardware (say, a new hard drive) they want to use it, and replace their old one. But just how does one go about copying/creating partitions on the new drive, and then copy the data across safely? It’s not quite as simple as a “cp” command….

The Theory

If you are copying from one filesystem to another, they both have to be mounted. However, you can’t mount both the old and the new filesystem on the same place, as you will only be able to see one of them.

The first job, therefore, is to prepare your filesystems and mount them in suitable places.

The second and easiest part is to copy the contents of the source onto the destination.

The final part is to ensure that your system is updated so that it will mount the new partition where the old one was.

Depending on exactly what you are doing, the procedure may vary quite a bit. The details of duplicating a hard disk onto a new one of the same size are different from the details of moving to a larger drive, which are different from the details of moving to a different drive with a different partitioning scheme.

One Disk to Another: Device-for-device copy

This procedure works only if the target disk is at least as big as the source disk. Basically you copy the raw device block for block with dd but you need to force dd to carry on reading even if it encounters bad sectors on the disk. It is probably more effieicent to use a partition for partition approach listed below, as this method can be quite slow. I’ve used this today to recover the data on a 18GiB SCSI U320 disk that was failing in under 3 hours. Once the copy is complete you will need to fsck the new disk, there will be problems with the file system if the source disk was failing. — AdamTrickett idea suggested by DavidRamsden

dd conv=noerror,sync if=/dev/source-drive of=/dev/destination-drive

This is essentially the same idea as dd_rescue http://www.garloff.de/kurt/linux/ddrescue/

This method will work with any file system on the disk, as you are copying the data on the disk one block at a time.

One disk to another: Partition-for-partition copy

This procedure is the one you should use if you want to copy your system onto a new disk keeping the same partitioning scheme, so that each partition on the old disk has an equivalent on the new one. You can also use this if you are copying single partitions – Copying /home onto a larger drive, for example, or moving the data from one partition to another on the same disk.

Assuming that the original disk is /dev/hda, and the new disk is /dev/hdc (modify appropriately if your disks are different devices):

  • Partition the new drive to match the old one (partition size can be different)
# cfdisk /dev/hdc

Note that Red Hat-based distributions don’t ship cfdisk. You will have to use fdisk, or something like DiskDruid to do the partitioning.

  • Make the filesystems on the drive. Example commands for this might be:
# mke2fs -j /dev/hdc1  1. mkreiserfs /dev/hdc5
  • One at a time, copy the data from the old partitions to the new ones. Ideally, this should be done with the original partitions in read-only mode (or at least where they can’t be modified by background processes). Booting in single-user mode, or from a live distribution such as Knoppix or tomsrtbt will do this.
  • First, mount the new partition somewhere:
# mount /dev/hdc5 /mnt/new

(Create /mnt/new using mkdir if it doesn’t already exist, or use some other directory)

  • Copy all the data from the old partition to the new one. In this example, we’re copying /usr.
# (cd /usr && tar -clpsf- *) | (cd /mnt/new && tar -xpsf-) 

This copies all the directories and files from the first filesystem (/usr in this case) to the second (/mnt/new – this will become the new /usr). Actually, what it does is tar up the old filesystem, writing it to the second tar process which unpacks it all. This may seem a little peculiar, but tar understands all about links and device nodes and other stange things which cp doesn’t. This is why it’s sometimes known as “the tar trick”.

  • Unmount the new partition
# umount /mnt/new
  • Finally, if you want to make the new partition “live” immediately, unmount the old partition and mount the new one:
# umount /usr  1. mount /dev/hda5 /usr
  • You should also edit /etc/fstab to reflect the location of the new partition.
  • Repeat this process for each partition you are moving across to the new disk.

Points to be aware of

  1. You can’t unmount your root filesystem and remount it while the system is running. This will require a reboot to take effect.
  2. If you move the partition with your kernel on (usually /boot or /) then you will need to set up your bootloader (grub or lilo, usually) to point to the new kernel. If you are removing the original disk after making your copy, you will also need to install a bootloader on the new disk. See the /LostLILO page for how to do this with lilo.

  3. If you use the LABEL= partition naming scheme, remember to use tune2fs -L YOUR_NEW_LABEL /dev/hdxx to change the LABELs on your partitions, to match what you have in your /etc/fstab, and rename the old partitions LABELs.
  4. You don’t need to copy /proc or /sys, since they are virtual filesystems created by the kernel, and you may not necessarily need to copy /dev. See the “Copying /dev” section at the bottom of the page.

One disk to another: Changing the partition scheme

If you are copying your system (or a large section of it) onto a new disk, and want to change the partitioning scheme, then the procedure is slightly different. We still use the tar trick, but we mount the entire partition structure at once before using it.

  • As before, prepare your new disk with cfdisk (or fdisk) and the appropriate mkfs. There are tips on /PartitioningSchemes if you need them.

  • Mount all the partitions you need at once. So, if you are repartitioning to give yourself a / partition on /dev/hdc1 and separate /home and /usr partitions on /dev/hdc5 and /dev/hdc6 repsectively, you would do the following:
mount /dev/hdc1 /mnt/new mkdir /mnt/new/home mount /dev/hdc5 /home mkdir /mnt/new/usr mount /dev/hdc6 /usr

Note that you have to create the mount-points for each filesystem.

  • Do the tar trick. This is slightly different from the previous version, since we want to copy potentially several filesystems from the source material, and we don’t want to copy /mnt/new into itself. We also don’t want to copy /proc or /sys. We therefore create a list of all the files in the root directory, and remove the ones we don’t want to take.
 1. ls -a / >/list.txt
  • Edit the /list.txt file, and remove the entries for proc and sys. Also remove dev and .dev, if you need to (see Copying /dev, below).
  • Now do the “tar trick”. Note that the -l option is not used, because we do want it to traverse filesystems this time.

# (cd / && tar -cpsf- --files-from=/list.txt) | (cd /mnt/new && tar -xpsf-)  1. rm /list.txt
  • Finally, check your fstab and boot loader as before.

Copying /dev

There are three different ways that your /dev could be set up. Each of these requires a slightly different way of handling it.

Traditional static /dev

If you look in /dev, you will see vast numbers of devices. You have this configuration if you have device nodes for devices you don’t have in the computer (/dev/hdg when you only have the on-board IDE controllers, for example. Or /dev/hda14 when you only have three partitions on hda).

If you have a static /dev like this, you will definitely need to copy it when you copy your root filesystem, and it will bring itself across normally if you use the tar trick on /

devfs

devfs is a way of dynamically creating devices in /dev as they are needed. It is used on 2.4 kernels, and is available but (strongly) deprecated in 2.6 kernels, as it has known problems and race conditions. If you have directory structures such as /dev/ide/host0/bus0/target0/lun0/ in your /dev directory, then you have devfs.

devfs configurations don’t need to be copied across, as they are regenerated automatically at boot.

udev

udev is a version of devfs which doesn’t have the problems of devfs. It uses the hotplug subsystem, and requires a 2.6 kernel. You probably have this configuration if you have only a few devices in /dev (a couple of hundred, rather than the several thousand of the static /dev). You will probably have a “udev” package installed as well, if you have this configuration. Most udev installations will have something like:

none on /dev type tmpfs (rw,size=5M,mode=0755)

in the output of “mount”.

udev configurations don’t need to be copied across, as they are regenerated automatically at boot.

Exisiting Tools

While all of this may seem complicated, there are some tools which make this “easier”. One of them is:

http://www-106.ibm.com/developerworks/library/l-partplan.html#h6

Leave a Reply