How to clone a partition or hard drive in Ubuntu (Linux)

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:

  1. Which partition are we cloning?
  2. Which device (hard drive) do we want to create our new partition on?
  3. How big should the new partition be?
  4. What filesystem is our source?

For the purposes of this tutorial:

  1. I will be cloning /dev/sde1
  2. I will be creating a new partition on /dev/sde
  3. The partition should be 1GB
  4. 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:

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

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:

  1. Partition number – defaults to next available partition
  2. First section – the first sector on the device to start the partition
  3. Last sector – the last sector of the partition

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:

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:

…. 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:

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:

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:

 

Cloning

There are 2 things we need for this:

  1. if (input file): /dev/sde1
  2. of (output file): /dev/sde2

In the terminal type:

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:

This is process grep, looking for dd processes, the output will be something like this:

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:

This will temporarily kill the dd process and yield some output in the terminal running dd, the output will look something like this:

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

 

  • S Hodge

    Very helpful. This dd command is what I was missing in cloning my data.

  • Pingback: How to Clone a Hard Drive or Partition using GParted and DD | Wasamara()

  • jb0nez

    What if I have bad sectors on the original? (It’s failing, with SMART errors, that’s why I want to clone) will dd skip those?

    • No, dd will copy them. have you tried repairing through the disk utility?

  • Josh Perlstein

    Very helpful, thank you so much!

    • 진오 강

      Exactly what I was going to say! Thanks xD

    • John

      Another way to monitor progress is do it with pv from the start, e.g.:

      pv -ptearb /dev/sdd5 | dd of=/dev/sdd6 bs=4M

      Also choosing an appropriate block size with dd can massively impact performance (gparted’s copy partition feature will automatically determine the optimum blocksize with a quick benchmark before it starts). You can actually skip dd entirely if you don’t want to specify a block size (this blog’s usage of dd is equivalent to cp, in fact), e.g.:

      pv -ptearb /dev/sdd5 > /dev/sdd6

      Final note is pv can’t generally determine the size of a block device and so can’t give accurate ETAs and progress. For that you can use blockdev:

      pv -ptearb /dev/sdd5 -s `blockdev -getsize64 /dev/sdd5` | dd of=/dev/sdd6 bs=4M

      The pv program is available in most modern distribution’s repositories. It is a tool specifically designed to pipe data and monitor and print progress, speed, and ETA.

      Still, gparted copy partition does all of the above. Since gparted is available in just about every repository these days, unless you want to waste a lot of time ignoring tools that others have written to solve tedious problems for us, it is the right tool for this job.

    • inpos

      while true; do killall -USR1 dd; sleep 5; done

      • Alexandra Tiffany Tilbrook

        status=progress. See my original comment.

    • Paul James Kratz

      I personally like using htop. You would have to install before you use it though, its in the general repository.

      sudo apt-get install htop
      htop

      It shows the processeses running, %cpu of each of your cores, RAM useage, and a few kill commands.

  • omi

    What happens if target/ output file is of a greater size ?

  • Viktor Kunz

    WTH!?
    When you open Gparted just select the partition you want to clone, right click on the selection and choose copy. In the disk selection list choose another disk you want to clone your partition to. Select the free (unallocated space), right click and choose paste. Then just apply the operations and that’s it! Your disk is being cloning now.

    Kind Regards

    • GParted’s role here is purely for prep. If you wanted to prepare the target in true Linux fashion learning the partitioning commands would be the best option… Completely removing GParted from the equation!

  • Bartłomiej Tomala

    great, but if you use gparted to create partition, why you don’t use option ‘copy partition to the clipboard’ and then ‘paste partition from the clipboard’, it easiest way and works for me

    • Looking at the gparted man page it doesn’t look very helpful. So if you were to try use it on a server I’m guessing it might be a bit more complicated. I like the Unix philosophy of writing a program that does one thing and does it well…. so I would prefer to create a partition via terminal using a different program to the one I’m cloning with (my next post I think!)

      • John

        [g]parted is a program that does one (well a few) things and does them well. It sounds more like you like the Unix philosophy of reinventing wheels. And I’m assuming you just didn’t realize gparted could copy partitions when you wrote this.

  • TheSoftman

    well.. trying for hours to clone a BACKBOX distro and his persistant volume from one USB drivce to one other.. it sucks!!!
    Basicaly errors are: volume is not bootable, or some files are missing to boot, or it boots but no persistent datas are available, or landing on a black screen with bash..
    Finally i have to admit that linux is just a bunch of pretending scrub !!!

  • Alexandra Tiffany Tilbrook

    Thanks for this tutorial, Gareth!! Naw, it’s not complicated at all… in fact, it’s written in a way I can actually understand…

    But there is a dd flag that has been introduced in Ubuntu 16.04 that shows progress without the need of the kill command. Just add `status=progress` to your dd command and no need to find out how much has been done or if it’s crashed.

    using your command example and applying the new dd flag to demonstrate:

    sudo dd if=/dev/sde1 of=/dev/sde2 bs=4096 conv=notrunc,noerror,sync status=progress

    which will show something like:
    1048576000 bytes (1.0 GB, 1000 MiB) copied, 9 s, 116 MB/s

    during the copy.

    Thanks again and hope my contribution helped.