Resizing a Linux Partition (Running in VirtualBox)

Filed under IT, Linux, VirtualBox
Tagged as , , , , ,

I was recently setting up a new test environment (BackTrack 5) inside a VirtualBox VM. Half way down the road of my project I realized that I was way to stingily with the amount of space I assigned to the virtual drive. Well, I thought no problem – I am going to enlarge the virtual drive. The steps would be easy:

  1. Enlarging the virtual drive
  2. Enlarging the partition holding the root file system with parted
  3. Enlarging the file system with resize2fs

Easy in theory. In reality it was still a little bit tricky.

Note, that everything that I describe in steps 2 and 3 also applies to a real linux machine. Step 1 is only necessary, because I happened to work inside a VM. On a real machine, step 1 would be something like copying the data of the old physical  drive onto a newer bigger drive with dd or the likes.

I also realize that there may be more professional programs like partition magic, which would have saved me some trouble. But I wanted to make it work right here and there with the things I had at hand. Which was parted. Or even the plain old fdisk would have done I guess.

It also goes without saying, that before you do things like this, that you need to make a backup if the data is of any value to you at all.

Step 1: Enlarging the Virtual Drive

This was the easy part. The virtual drive is actually a .vdi file. There is a VirtualBox command line tool, that can resize the drive. On a real computer, this would be like copying the hard drive data onto a larger disk.

My host computer is running Windows. The virtual drive was initially set to have a size of 8GB. I wanted it to be twice as big. So the command looks like:

C:\Users\Netzgewitter\VirtualBox VMs\BackTrack5>"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" modifyhd "BackTrack 5.vdi" --resize 16384
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

The operation only took a second. The size is given in MB so 16GB = 16*1024MB = 16386MB.

Step 2: Resizing the Partition

I booted up the VM and checked the hard drive size with fdisk -l. Yep, /dev/sda1 had now 16GB. So all I had to do was to enlarge the partition holding the root file system to 16GB and then resize the file system with resize2fs.

Parted didn’t let me resize the partition, since it was mounted as the current file system at /. That was expected. So I booted Linux from a live CD. I used the BackTrack 5 CD since I had it at hand. But any other live CD like Knoppix would have done just as well.

Once I’d booted into the live CD I checked the partitions again with parted:

GNU Parted 2.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit cyl
(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 2088cyl
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 2088,255,63.  Each cylinder is 8225kB.
Partition Table: msdos

Number  Start   End      Size    Type      File system     Flags
 1      0cyl    993cyl   993cyl  primary   ext4            boot
 2      993cyl  1044cyl  50cyl   extended
 5      993cyl  1044cyl  50cyl   logical   linux-swap(v1)

As you can see, I switched the units to cylinders with “unit cyl“. That way it would be easier to determine the new end of the partition. Since there was a swap partition at the end of the drive, it was not possible to just resize the partition holding the file system. First I had to move the swap partition to the end of the drive. There is a command in parted to move a partition. But it didn’t let me move an extended partition. Since that was not possible I tried to remove partition 2 and recreated it at the end of the drive:

(parted) rm 2
Error: Partition /dev/sda2 is being used. You must unmount it before you modify it with Parted.

Dang. It didn’t let me. The reason was that the live CD automatically detected and used the swap partition. So I first had to turn off the swap partition:

root@bt:~# swapoff /dev/sda5

Now I tried to remove the swap partition again with parted:

(parted) rm 2
(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 2088cyl
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 2088,255,63.  Each cylinder is 8225kB.
Partition Table: msdos

Number  Start  End     Size    Type     File system  Flags

 1      0cyl   993cyl  993cyl  primary  ext4         boot

Ok, that did the trick. Now I could recreate the swap partition at the end of the drive with the command mkpart:

(parted) mkpart extended -51 -1
(parted) mkpart logical linux-swap -51 -1
(parted) print                                                            
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 2088cyl
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 2088,255,63.  Each cylinder is 8225kB.
Partition Table: msdos

Number  Start    End      Size    Type      File system     Flags
 1      0cyl     993cyl   993cyl  primary   ext4            boot
 2      2037cyl  2088cyl  50cyl   extended                 
 5      2037cyl  2088cyl  50cyl   logical   linux-swap(v1)

I created a logical partition inside an extended partition again. A single second primary partition would have done as well, since we would not exceed the limit of four primary partitions. But I recreated the partitions as they were. It makes no difference. Here you can also see why I switched the units to cylinders. Since I knew the partition was exactly 50 cylinders big, I only needed to specify -51 for the start and -1 for the end. No other calculations were required. Negative numbers are counted backwards from the end of the disc. That’s a neat feature of parted.

The new swap partition also needs to be activated:

root@bt:~# mkswap /dev/sda5
Setting up swapspace version 1, size = 413692 KiB
no label, UUID=57eb8574-d471-42e6-8bf4-5ba2ef0bbc0f

Now I was finally ready to enlarge my file system partition. I tried with the command resize, but parted was again being stubborn and didn’t execute the operation because the file system had some features enabled that it was not compatible with.

WARNING: you are attempting to use parted to operate on (move) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs.  We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
Error: File system has an incompatible feature enabled.  Compatible features are
has_journal, dir_index, filetype, sparse_super and large_file.  Use tune2fs or
debugfs to remove features.

This is somewhat silly of parted, since I only wanted to resize the partition table entries and not the file system as well. I would do that with resize2fs myself later on. Maybe there is a trick to make parted to do it. But I didn’t know any better then to delete the first partition and recreate it at the exact same location. Just bigger.

This is a somewhat scary thought. But the actual data inside the partition is going to be unchanged by the process. We are only manipulating partition table entries here. Up to now we did not do anything really dangerous. So this is the point of no return. Make your backup now or forever hold your peace.

To be really sure that I would place the new partition at the exact same position I switched the displayed units to chs (cylinder/head/sector).

(parted) unit chs
(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 2088,170,1
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 2088,255,63.  Each cylinder is 8225kB.
Partition Table: msdos

Number  Start        End          Type      File system     Flags
 1      0,32,32      933,254,62  primary   ext4            boot
 2      2037,171,54  2088,170,1   extended
 5      2037,204,23  2088,170,1   logical   linux-swap(v1)

So maybe that was not a bad thing. It tells me that the partition starts at 0,32,32. If I would have created the new partition just by specifying the cylinder, it might have created the new partition at 0,0,0. I guess that would have been the death of my file system (but I didn’t really try that to say for sure). Anyway, specifying the position by chs is certainly not a bad idea.

Now I removed the partition and created a new one from 0,32,32 – 2036,254,62. The end of the partition is the last sector of cylinder 2036 which is the one before the one where the swap partition is on:

(parted) rm 1
(parted) mkpart primary ext4 0,32,32 2036,254,6
(parted) print                                                            
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 2088,170,1
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 2088,255,63.  Each cylinder is 8225kB.
Partition Table: msdos

Number  Start        End          Type      File system     Flags
 1      0,32,32      2036,254,62  primary   ext4           
 2      2037,171,54  2088,170,1   extended
 5      2037,204,23  2088,170,1   logical   linux-swap(v1)

Almost done. Let’s not forget to make the partition bootable:

(parted) toggle 1 boot
(parted) print                                                            
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 2088,170,1
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 2088,255,63.  Each cylinder is 8225kB.
Partition Table: msdos

Number  Start       End          Type      File system  Flags
 1      0,32,32     2036,254,62  primary   ext4         boot
 2      2037,171,54  2088,170,1   extended
 5      2037,204,23  2088,170,1   logical   linux-swap(v1)

Another problem I had was that the partitions in /etc/fstab were identified by their UUID and not by the device file. You can check your drive’s UUID with blkid:

root@bt:~# blkid
/dev/sda1: UUID="f9ae2c40-1edd-47c0-9ae7-11c4c08dcf50" TYPE="ext4"
/dev/sda5: UUID="57eb8574-d471-42e6-8bf4-5ba2ef0bbc0f" TYPE="swap"

And the content of /etc/fstab was:

# / was on /dev/sda1 during installation
UUID=f9ae2c40-1edd-47c0-9ae7-11c4c08dcf50 /               ext4    errors=remount-ro 0       1
# swap was on /dev/sda5 during installation
UUID=91eaafab-b4e2-4821-90d7-2b3ef093bdcf none            swap    sw              0       0

So I had to adjust the UUID of the swap partition in /etc/fstab.

Step 3: Enlarging the File System

I powered up the VM and after a couple seconds it booted into linux from the virtual drive again. YEAAH! I only realized afterwards that I was holding my breath during the whole reboot.

Since the partition has now the right size, we can resize the contained file system. I guess we could have also done that while I was still working from the live CD. But resize2fs also let’s you resize a mounted file system. Calling resize2fs with only the device makes the file system as big as possible:

root@bt:~# resize2fs /dev/sda1

Now let’s check the size of the file system:

root@bt:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1              16G  7.0G  7.7G  48% /

Mission accomplished!

18 Comments

  1. Rumman says:

    Hi. This is one of the best articles of HD resizing ... helped me a lot ... btw how did you learn so much abt hard disks? any sources ?? coz i wanna be able to do all this myself

  2. Bill says:

    Worked like a charm!

  3. Andre says:

    Great article. Worked like a charm. Thanks so much.

  4. wm says:

    Funny, I was just trying to accomplish exactly the same task - resizing a virtual drive in VirtualBox for Backtrack 5. Thanks to your instructions it just took me a few minutes instead of hours ... Cheers!

  5. marquis says:

    um...i just booted into a live cd (like you did) and used apt-get install gparted . gparted gui is way easier IMHO

    • norbert says:

      Hi marquis. Yes of course. gparted is also nice and easier to use. But it's only a graphical front end to parted. I guess it's a matter of taste. I sometimes prefer the command line tools. That way I don't even need to fire up X11.

  6. Derek says:

    Excellent article - I would have been lost without it. I used a gparted image and booted it as a live cd within Virtualbox, but I would have been stuck without your advice on dealing with the swap partition.

  7. Eugene says:

    Excelent article - very helpfull. Thank you very much.

  8. Rick says:

    The moderator at VirtualBox.org created a program that makes it VERY easy. The program is free and I just used it. It is perfect. Here is the link for more information:

    https://forums.virtualbox.org/viewtopic.php?f=6&t=22422

  9. Naga says:

    Very helpful..Just followed the instructions and it worked like a charm

  10. jvelez30 says:

    Now a days step2 is very short .
    Just attach BT5 LiveCD again to VB Host
    startx
    open terminal
    apt-get install gparted
    swapoff /dev/sda5
    gparted

    And visually you can remove /dev/sda2 and /dev/sda5
    Then you can enlarge /dev/sda1 to the desired size (don't forget to reserve 564 MB for the swap)
    Create a extended partition at the end with 564MB, and another extended partition inside the last one but you should choose linux-swap type.
    Finally you should to apply changes.

    And that all !! You can continue with step 3
    Don't forget you're still in LiveCD, reboot to get in the harddisk BT5

  11. wmaas says:

    Thanks a lot, excellent. it works like a charm

  12. Ash says:

    Great article! Thanks!

  13. QS says:

    Phenomenal article, thank you. You just saved me quite a bit of time, allowing me to resize an existing VM rather than having to build one all over from scratch. Much appreciated.

  14. Alex says:

    You fucking saved my life!!
    Thx man!

  15. random dude says:

    After an hour of searching I stumbled upon this article, no one else mentions you can use parted in console and not always you have the luxury of gParted.

    In recent version you can just run command 'resizepartition'
    and just give the size you want, follow up by resize2fs and chill.


Trackbacks/Pingbacks

  1. Resizing a VirtualBox Linux guest Partition | Erlend's Lookout Post
  2. 不完全な死体

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*