Disk Cloning in Linux

The dd command utility is a simple yet powerful and useful command available in Unix and Linux systems which is used to convert and copy files. Unix like systems treat all devices as files and these device files are located in the /dev directory in your system. So typically your hard disk drive is a file in the /dev directory with the prefix of hd or sd (depending on IDE or SCSI driver). This concept of device as files makes dd a perfect candidate for backup and restore of disk images or cloning some partitions or the entire disk.

You can use the fdisk command or check the /proc/partitions to view all the disk partitions in your system.

cat /proc/partitions

	major minor  #blocks  name
	  11    0    1048575 sr0
	   8    0   20480000 sda
	   8    1    1048576 sda1
	   8    2    7339008 sda2
	   8   16    8388608 sdb
	 253    0    6496256 dm-0
	 253    1     839680 dm-1
fdisk -l

	Disk /dev/sda: 21.0 GB, 20971520000 bytes, 40960000 sectors
	Units = sectors of 1 * 512 = 512 bytes
	Sector size (logical/physical): 512 bytes / 512 bytes
	I/O size (minimum/optimal): 512 bytes / 512 bytes
	Disk label type: dos
	Disk identifier: 0x0005c57d

	   Device Boot      Start         End      Blocks   Id  System
	/dev/sda1   *        2048     2099199     1048576   83  Linux
	/dev/sda2         2099200    16777215     7339008   8e  Linux LVM

	Disk /dev/sdb: 8589 MB, 8589934592 bytes, 16777216 sectors
	Units = sectors of 1 * 512 = 512 bytes
	Sector size (logical/physical): 512 bytes / 512 bytes
	I/O size (minimum/optimal): 512 bytes / 512 bytes

	Disk /dev/mapper/centos-root: 6652 MB, 6652166144 bytes, 12992512 sectors
	Units = sectors of 1 * 512 = 512 bytes
	Sector size (logical/physical): 512 bytes / 512 bytes
	I/O size (minimum/optimal): 512 bytes / 512 bytes

	Disk /dev/mapper/centos-swap: 859 MB, 859832320 bytes, 1679360 sectors
	Units = sectors of 1 * 512 = 512 bytes
	Sector size (logical/physical): 512 bytes / 512 bytes
	I/O size (minimum/optimal): 512 bytes / 512 bytes

From the above output we can deduce that you have hard disks on your system and their device file names are sda and sdb. There are two partitions in sda which are sda1 and sda2 and we also know that sda1 is a boot partition.

How to clone a partition from one disk to another

The following are the steps to create a clone of a partition from one disk to another disk, lets say for example you want to clone sda1 partition to sdb1. In this case sda is your source disk and sdb is the destination disk.

Step 1: Create a new partition in the destination disk if it does not already exist. You can use the fdisk command to create the new partition.

fdisk /dev/sdb

	Welcome to fdisk (util-linux 2.23.2).

	Changes will remain in memory only, until you decide to write them.
	Be careful before using the write command.

	Device does not contain a recognized partition table
	Building a new DOS disklabel with disk identifier 0xb109bc13.

	Command (m for help): n
	Partition type:
		p   primary (0 primary, 0 extended, 4 free)
		e   extended
	Select (default p): p
	Partition number (1-4, default 1):1
	First sector (2048-16777215, default 2048):
	Using default value 2048
	Last sector, +sectors or +size{K,M,G} (2048-16777215, default 16777215): +2G
	Partition 1 of type Linux and of size 2 GiB is set

	Command (m for help): w
	The partition table has been altered!

	Calling ioctl() to re-read partition table.
	Syncing disks.

Step 2: Run the dd command.

dd if=/dev/sda1 of=/dev/sdb1 bs=64M conv=sync,noerror status=progress

#	1006632960 bytes (1.0 GB) copied, 7.836029 s, 128 MB/s
#	16+0 records in
#	16+0 records out
#	1073741824 bytes (1.1 GB) copied, 9.49951 s, 113 MB/s

How to clone an entire disk

To clone an entire disk, say for example sda to sdb, run:

dd if=/dev/sda of=/dev/sdb bs=64M conv=sync,noerror status=progress

When you clone a entire disk, the destination disk will get all the partitions that are on the source disk.

How to create a disk image

Before you create a disk image backup, make sure no partitions on that disk are mounted and run the following command

dd if=/dev/sdb of=/path/to/backup.img bs=64M conv=sync,noerror status=progress

where sdb is the disk file name and /path/to/backup.img is the path and filename of the backup image.

Compressed disk image

You could also compress the backup image with gzip as shown in the example below

 dd if=/dev/sdb bs=64M conv=sync,noerror status=progress | gzip -c > /path/to/backup.img.gz

Send disk image to remote system

You could send the backup image to a remote machine using ssh as in the below example.

dd if=/dev/sdb bs=64M conv=sync,noerror status=progress | gzip -c | ssh root@remotehost dd of=/path/to/backup.img.gz

Split the disk image by size

You can split the disk image in to smaller pieces of any size that you specify by passing the dd output through split command.

dd if=/dev/sdb bs=64M conv=sync,noerror status=progress | gzip -c | split -b 50M - /path/to/backup.img.gz.

The above command splits the backup image file to smaller files of size 50MB or less. A two letter suffix will be added to the files. The resulting files will have names backup.img.gz.aa, backup.img.gz.ab, backup.img.gz.ac,…

To join the split files into a single image file, you run the command

cat backup.img.gz.* >  backup.img.gz

Restoring disk image

The below command restores the disk sdb from the image file backup.img.

dd if=/path/to/backup.img of=/dev/sdb status=progress

To restore from a compressed backup image, use the gunzip command with dd

gunzip -c /path/to/backup.img | dd of=/dev/sdb status=progress

To restore from a backup image that is compressed and split, run:

cat backup.img.gz.* | gunzip -c | dd of=/dev/sdb status=progress