Resizing Linux partitions: yes, you can!

I recently installed Ubuntu linux, and everything came up working fine. Then Ubuntu wanted to install “system updates” (all packages that have had updates since version 6.0.6 was released), so I let it go ahead and download the 200 MB of upgrades. One of those upgrades was a new linux kernel (2.6.15-28, vs. my current 2.6.15-26). To “install” this upgrade, Ubuntu attempted to write the new kernel into my /boot partition. Which lacked enough space. “Write error!” Ubuntu declared, leaving half of a kernel stuck to the end of the partition. I cleaned this off, happy to stay with my current kernel, but then I wondered. Would I ever be able to upgrade my kernel? Maybe 16 MB was too small for /boot. (Kernels are getting large and fat these days!)

After hashing this over with some friends, the solution seemed straightforward. I decided to stretch /boot out to cover 128 MB — plenty of space for several kernels and all of their friends. Now, partitions are physical divisions of your hard drive, so their position matters. My 16-MB /boot partition was first on the disk, followed by my 5-GB / partition (less than 1 GB used). Therefore, I planned to save a full copy of /boot and /, modify both partitions, then copy my data back onto the partitions.

After making and checking my full copy of this data, I turned to some man pages to acquaint myself with fdisk for the partitioning rite. Here’s where I learned something: there is a utility, parted, that will permit you to move and resize partitions! (For you geeks, this “resize” applies to both the partition and the filesystem, which is what does the trick.) Instead of destroying and re-creating them, saving and copying data, in theory I could simply shuffle them around. In theory, this is all I would need to do:

/dev/hda5 goes from 65kB to 16MB
/dev/hda6 goes from 16MB to 5256MB
So…

  1. parted /dev/hda5
  2. resize 6 128MB 5256MB
    # move and shrink /dev/hda6, which is /, to start at 128MB
  3. resize 5 65kB 128MB
    # move and grow /dev/hda5, which is /boot, to end at 128MB

In reality, parted had some tricks up its sleeve. It flat-out refused to move partition 6 anywhere above 17MB. (“Error: unable to satisfy all constraints on the partition.”) I still am not sure exactly what those constraints were, but in the end, here’s what worked:

  1. resize 6 16MB 2000MB
    # really, it's mostly empty. This was safe. I hoped.
  2. move 6 2000MB 4000MB
    # get partition 6 out of the way. Note that I couldn't just move it to start at 128MB because you "can't move a partition to overlap with itself" and it ended at 2000 MB.
  3. resize 5 65kB 128MB
    # grow partition 5
  4. resize 6 2000MB 3000MB
    # parted won't let me resize 6 back down to start at 128 MB. I can't move it there, either, because (you guessed it) it would overlap with its current position. So I had to shrink it again.
  5. move 6 128MB 1128MB
    # now I can move it down!
  6. resize 6 128MB 5256MB
    # and make it bigger.

Now I have that same post-puzzle fatigue-glow that you get after escaping Zork’s maze of twisty little passages. Puzzle completed in 6 steps. I could have done it in 5 if I’d known that I’d need to shrink partition 6 down to 1000MB from the start. Thank goodness / gave me 5 GB to mess around in — and that the shrinking steps succeeded! After rebooting, I’m back up and running, with 120 MB on /boot (not 128, possibly because partitions like to start and stop on cylinder boundaries?). Done! And I can delete that backup copy I made and never needed.