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
- 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