Cloning a hard drive can be useful for backing up (byte for byte) or moving data to a new hard drive. In Ubuntu this is pretty simple, though it is important to pay attention!
We’re going to use a few tools:
- fdisk to create the partition
- mkfs to create the filesystem
- dd to clone bytes
Firstly, a few questions to answer
There are a few things we need to clarify before we start cloning:
- Which partition are we cloning?
- Which device (hard drive) do we want to create our new partition on?
- How big should the new partition be?
- What filesystem is our source?
For the purposes of this tutorial:
- I will be cloning /dev/sde1
- I will be creating a new partition on /dev/sde
- The partition should be 1GB
- My source filesystem is ext4
WARNING: if cloning a partition, it’s not ideal to clone it onto the same device as the source!
NOTE: 1GB is a pretty small partition, I’m using this size for tutorial sake.
How to clone a hard drive?
This post may seem a bit long, but it is essentially:
- sudo fdisk /dev/sde
- sudo mkfs.ext4 /dev/sde2
- sudo dd if=/dev/sde1 of=/dev/sde2 bs=4096 conv=notrunc,noerror,sync
Don’t copy them as they mean nothing yet and may not match your situation! But read on and all will be revealed….. so let’s open a terminal.
Create partition to backup to (target)
For this we use fdisk. Inside your terminal type/copy the following:
1 |
sudo fdisk /dev/sde |
/dev/sde here is the name of the device we identified earlier. This command take us into command mode enabling us to perform commands on this device.
NOTE: Any commands we do will not be written to the device until we use the w command
To create a new partition we issue the n command: (use m to view available commands)
1 2 3 4 5 |
Command (m for help): n Partition type: p primary (1 primary, 0 extended, 3 free) e extended Select (default p): |
After typing n (and pressing enter) you will be asked if you want to create a primary or extended partition. A drive can only have 4 primary partitions, in the above example you can see fdisk tells us how many primary partitions are available. The default type selection is primary.
After selecting the partition type, you will be asked:
- Partition number – defaults to next available partition
- First section – the first sector on the device to start the partition
- Last sector – the last sector of the partition
1 2 3 4 5 6 7 8 |
...... Select (default p): Using default response p Partition number (1–4, default 2): Using default value 2 First sector (2099200–625142447, default 2099200): Using default value 2099200 Last sector, +sectors or +size{K,M,G} (2099200–625142447, default 625142447): +1G |
Above you can see I pressed enter for the partition type, number and first sector: accepting the default values.
For the last sector, I entered +1G. This equates to a partition size of 1Gb. You can also use:
- +3K (for Kb)
- +6M (for Mb)
- or a specified block at which to end the partition (if you can be bothered with the maths)
NOTE: Remember to use the ‘+‘ at the beginning, and obviously swap out the numbers for the size of partition you want
What just happened?
Having pressed enter on the last sector you don’t receive any notification, no changes have been made yet. But you can see what the partition table will look like, at the prompt use the p command:
1 2 3 4 5 6 7 8 9 10 11 12 |
Command (m for help): p Disk /dev/sde: 320.1 GB, 320072933376 bytes 255 heads, 63 sectors/track, 38913 cylinders, total 625142448 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 identifier: 0x07f2837e Device Boot Start End Blocks Id System /dev/sde1 2048 2099199 1048576 83 Linux /dev/sde2 2099200 4196351 1048576 83 Linux |
The p command (print the partition table) prints the current partitions, here we have:
- /dev/sde1 – our source partition
- /dev/sde2 – our destination partition
To write the partition we have just created use the w command:
1 2 3 4 5 |
Command (m for help): w The partition table has been altered! Calling ioctl() to re–read partition table. Syncing disks. |
…. and the partition has now been created!
NOTE: to scrap the suggested changes, use the q command to quit and discard any partitioning.
Where has my partition gone?
Our partition has been created, but at the minute it is basically like a fence around some blocks. Using parted we can see our partition:
1 2 3 4 5 6 7 8 9 |
sudo parted –l /dev/sde Model: Hitachi HTS545032B9A300 (scsi) Disk /dev/sde: 320GB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 1049kB 1075MB 1074MB primary ext4 2 1075MB 2149MB 1074MB primary |
To be able to utilise our newly created partition we now need to give it a filesystem….
enter mkfs!
Giving our partition a filesystem is simple:
1 |
sudo mkfs.ext4 /dev/sde2 |
OK, Some Linux ninjas will pull me up that this isn’t actually mkfs I’m using but some sort of wrapper or alias for mke2fs – they are correct!
Anyway, if we run parted again you’ll see that our partition now has a filesystem:
1 2 3 4 5 6 7 8 9 |
sudo parted –l /dev/sde Model: Hitachi HTS545032B9A300 (scsi) Disk /dev/sde: 320GB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 1049kB 1075MB 1074MB primary ext4 2 1075MB 2149MB 1074MB primary <strong>ext4</strong> |
Cloning
There are 2 things we need for this:
- if (input file): /dev/sde1
- of (output file): /dev/sde2
In the terminal type:
1 |
sudo dd if=/dev/sde1 of=/dev/sde2 bs=4096 conv=notrunc,noerror,sync |
This will start copying your ‘if’ to your ‘of’. It may take a while so be patient, there won’t be any output so keep the terminal open until you get your command prompt back again.
There are a few other options used here:
bs=4096
- sets the block size to 4096
- Ideal size for hard drive read/write efficiency
- … though this may not be the case with SSD’s (discussion?)
conv=notrunc,noerror,sync
- notrunc – do not truncate any data
- noerror – continue operation ignoring all read errors, dd will otherwise halt at any error
- sync – writes zeroes to disk for read errors this keeps data offsets in sync
Can I clone a whole drive?
In the case of cloning a whole drive, the ‘if‘ here would have been /dev/sde. The command would have been the same format but the ‘of‘ would have to be another drive of capable size.
Does the target have to be the same size?
If the target isn’t the same size the dd program will copy as much as it can until it runs out of space.
This is taking a while, has it crashed?
Probably not is the quick answer. A way to get some output is to open up another terminal (while dd is running in another) then use the following command:
1 |
pgrep –l ‘dd$’ |
This is process grep, looking for dd processes, the output will be something like this:
1 2 |
pgrep –l ‘dd$’ 7406 dd |
Here the number 7406 is the process ID (which will be different in your output!), we can use this together with the following command to force some output:
1 |
sudo kill –USR1 7406 |
This will temporarily kill the dd process and yield some output in the terminal running dd, the output will look something like this:
1 2 3 |
165712+0 records in 165712+0 records out 678756352 bytes (679 MB) copied, 22.7643 s, 29.8 MB/s |
Once the output is displayed dd carries on as before. You can keep running the previous kill command to view output.
(Thanks to Josh Perlstein for commenting this tip below! )
Pingback: How to Clone a Hard Drive or Partition using GParted and DD | Wasamara()