Resizing Partitions

From WTFwiki
Jump to navigation Jump to search

This is a HOWTO on resizing diskslices/partitons with FreeBSD.

NOTE: this has the potential to break things very badly, be sure you have backups of anything you do this on. Also make sure that you specify the right disk, most of these tools will assume the primary hard drive of your machine, and you might not want to be messing with that (unless you know what you're doing).

The Situation

I have a 245 meg disk image I want to put on my 1G CompactFlash card. I don't want to waste 75% of the space so I need to resize the slices and the filesystem.

Once the image is dded to the flash card the setup is as follows:

  • /dev/ad4 - entire device
  • /dev/ad4a - the first slice (unused)
  • /dev/ad4c - the 'entire' /dev/ad4 disk
  • /dev/ad4s1 - the first slice of ad4c (same as ad4cs1)
  • /dev/ad4s1a - the first slice of ad4s1 (the actual freebsd filesystem)
  • /dev/ad4s1c - the 'entire' /dev/ad4s1 slice

the 'c' slices are always, by convention, the entire slice. So, you can see we only have one real 'slice' on the disk. Now we need to start changing the slice sizes...

Changing the slice sizes with disklabel(8) and fdisk

Disklabeling the root of the drive

(do we *really* need to disklabel this?) Notice that to make /dev/ad4s1 bigger, we'll need to resize /dev/ad4 first, to make it the proper size, we use disklabel for this:

 $disklabel -e /dev/ad4
 # /dev/ad4:
 8 partitions:
 #        size   offset    fstype   [fsize bsize bps/cpg]
   a:   501744       16    unused        0     0
   c:   501760        0    unused        0     0         # "raw" part, don't edit

The units of size here are 'sectors' which, by default, are 512 bytes, so if we do the math ((501760*512)/1024)/1024 we find the disk is 245 megs.

Now, we need to define a NEW size for this stuff, and since HD manufactures want to rip you off, they assume that a kilobyte has 1000 bytes (not 1024) and a megabyte has 1,000,000 bytes and so on. This makes storage smaller than it seems (256 meg card is really ~245) and it makes some fun math for us. My CF card is a gig so... (1000*1000*1000)/512 = 1,953,125 sectors or ~953 megs. So, we edit the disklabel to reflect this:

 # /dev/ad4:
 8 partitions:
 #        size   offset    fstype   [fsize bsize bps/cpg]
   a:  1953109       16    unused        0     0
   c:  1953125        0    unused        0     0         # "raw" part, don't edit

Note the 16 sector offset has been preserved on the 'a' slice.

Resizing the drive with fdisk

Now, we need to actually modify the partition table to reflect this change:

 fdisk -u /dev/ad4

Tell it you want to change the first partition, accept the default until it asks you about the size. Then input the size of the 'a' slice minus 32 (because of the "start" value fdisk reports) 1953077

Keep accepting the defaults until it asks you if you want to write the new partition table, say yes here.

Disklabling the first slice

Now, we need to disklabel the first slice too:

 $disklabel -e /dev/ad4s1
 # /dev/ad4s1:
 8 partitions:
 #        size   offset    fstype   [fsize bsize bps/cpg]
   a:   501712       16    4.2BSD     2048 16384 31360
   c:   501728        0    unused        0     0         # "raw" part, don't edit

So, there's the 'real' filesystem that we're ultimately trying to resize. So we just edit the disklabel again, using the sector size of the 'a' slice we just resized above (1953077)

 # /dev/ad4s1:
 8 partitions:
 #        size   offset    fstype   [fsize bsize bps/cpg]
   a:  1953061       16    4.2BSD     2048 16384 31360
   c:  1953077        0    unused        0     0         # "raw" part, don't edit

Using growfs(8) to increase the filesystem size

Okay, now we're ready to do the final step:

 growfs /dev/ad4s1a

Yo'll be asked if your data was backed up, type the appropiate response (the 'Yes' is case-sensitive). If you type yes it will do the resize and it all should be good... If it's not, then it's time to dig out that backup...

Recommended Reading

 man disklabel
 man fdisk
 man growfs