Disk cloning in Linux using dd command

Last updated on 27th February 2018

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.

This article shows you some examples of how to use the dd command to backup or clone drive partitions and entire drives.

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

  • conv=sync,noerror tells dd command to continue copying after read errors and fill input block with nulls in case partial records.
  • status=progress shows progress of the copy.
  • bs=64M set the block size to copy at a time. Adjust this value could improve the copying speed

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

Post a comment

Comments

Kidpixo | July 21, 2020 9:24 PM |

Great resource, thanks a lot!

Joao Pimentel Ferreira | March 22, 2020 4:09 PM |

Great article