What do you do when you need (or sometimes, simply want) to upgrade your boot hard drive?  I recently found myself in that position, wondering how to accomplish the job with nothing more than free tools.  It seems like the kind of thing that Linux should definitely have the ability to handle.  As usual in the FOSS world, the question comes down to: just which way do you want to skin this cat?

Option 1

Forensicly copy all the data and then resize the partitions

I found a couple of guides that explained the process in language that I could understand, using tools that I have at least some vague familiarity with.  I use dd at work all the time to overwrite hard drives, so it came as no surprise when I found this article which uses ddrescue (a tool that builds on dd to copy data without borking over read errors).  In a nutshell, this method uses ddrescue to copy the entire contents of the old drive onto the new one.  If your new drive has more space on it than your old one (a typical reason for wanting to upgrade), then after copying everything over, you find yourself left with a lot of unused space at the end of the drive.  You then go in with a partitioning tool like gparted and move you swap down to the end of the drive and resize your primary partition to fill up the unused space.  It sounds like a workable plan, and if you want to try it, you can follow this guide at Linux.com: Clone your Ubuntu installation onto a new hard disk.

Option 2

Partition the disk the way you want and then copy over the data

The previous option sounded a little backwards to me.  Not only do you have to resize and rearrange your partitions after the fact, but you also end up copying over every single bit of data from one drive to the other.  It figured that surely somebody must have found a way to just copy the actual data into an already partitioned drive.  I found the answer at linuxjournal.com, in this article: Hack and / – Migrate to a New Hard Drive.

This method uses a tool called find to pipe data to another tool called cpio.  This combination basically reads through the old drive and finds all the files and directories and then passes them to the cpio command to copy to the new location.  Since this method only deals with the used space on your drive, it takes a lot less time, and you can dump the data into a drive that you have already partitioned to your liking.

Take note, that with either method, you will have to futz with both grub and fstab.  In current Ubuntu distros, at least, both grub’s menu.lst and fstab reference drives by their UUID.  This article does a good job of explaining how to fix grub and fstab so that the system will boot properly when you switch the drives out.

I used this second option when I migrated my old hard drive data to a new, larger drive.  It worked like a charm except for the fact that I didn’t replace every single instance of the old drive’s UUID with the new drive’s UUID in the grub menu.lst.  I had to go back a second time and find the instances that I had missed.  Once I did that, everything worked perfectly when I booted from the new drive.

You should note that this guide for using find | cpio offers two different methods for handling the migration: 1) from  single-user mode and 2) from a boot disc.  I chose the boot disc option and had no troubles, but do make sure you read the guide carefully, as the author gives commands for both methods, and you don’t want to get them confused since they work from different locations in the file system.

Also, if you happen to accidentally reference the wrong drive in your command and try to write the old hard drive back over itself, cpio will simply skip report that a newer or same-age version exists and skip over it.  If you have more than two drives mounted in your system, however, you could potentially overwrite data that you wanted to keep.  You might want to make sure that you only have the two drives physically located in the system (i.e., unplug any external hard drives) so that you don’t wind up losing a ton of good data due to a typo.