Online resizing an ext4 root file system

Resizing online is possible and it is even better with the new 3.3 Linux kernel

You can extend an ext4 file system – even if it is your current root and your OS is running. On the other hand, online shrinking is only supported from version 3.3 of the Linux kernel.

In this example, I will show you how I extended a real life, live ~5 GB virtual disk (with an ext4 file system) to 10 GB.

Read more about the new 3.3 and 3.4 Linux kernel versions at http://www.ibm.com/developerworks/library/l-33linuxkernel/ (thanks Joro).

Preparing the storage device

If you have a physical device (such as your HDD in your PC), you probably already rearranged the partitions or you had free space all the time. In any case, the goal is to extend the current partition.

In my case, I have a virtual disk drive. First, I have to extend the image:

# qemu-img resize disk1.raw 10G
Image resized.

Now we have a 10 GB disk, but the partition and the file system is still only using the first 5 Gigabytes.

Resizing the partition

While the OS is still running, we can extend the partition under it. This one has a MBR partition table, so I will use fdisk:

# fdisk /dev/vda

Disk /dev/vda: 10.7 GB, 10737418240 bytes
118 heads, 3 sectors/track, 59241 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0001b344

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1            2048    12584959     6291456   83  Linux

Command (m for help): d
Selected partition 1
Partition 1 is deleted

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-20971519, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519):
Using default value 20971519
Partition 1 of type Linux and of size 10 GiB is set

Command (m for help): a
Partition number (1-4): 1

Command (m for help): p

Disk /dev/vda: 10.7 GB, 10737418240 bytes
118 heads, 3 sectors/track, 59241 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0001b344

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048    20971519    10484736   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

As you can see above:

  • I deleted the old entry for the partition
  • Recreated the partition, but now it extends to the end of the disk
  • Printed the partition table again for verification
  • Written changes to the disk

At the end you can see, that the kernel still uses the old partition table. If we try to inform it again, we get the following:

# partprobe /dev/vda
Error: Partition(s) 1 on /dev/vda have been written, but we have been unable to inform
the kernel of the change, probably because it/they are in use.
As a result, the old partition(s) will remain in use.
You should reboot now before making further changes.

We have to reboot. We could probably work around this in the new kernel or with some LVM based setup. Let me know about your experience!

Extending the ext4 file system while the OS is running

After the system starts up again, the kernel knows the new size (10 GB) of the partition, but the file system is still smaller than that, so we have to extend it. Online resizing is no different than normal – if you do not specify the new size, the file system will be aligned to the partition size:

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       6,0G  1,1G  4,7G  19% /

# resize2fs /dev/vda1
resize2fs 1.42.6 (21-Sep-2012)
Filesystem at /dev/vda1 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vda1 is now 2621184 blocks long.

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       9,9G  1,1G  8,4G  11% /

Now we successfully resized the ext4 file system, while the OS was running.

In this example, a virtual disk, a partition and the ext4 file system was extended to 10 GB. While I could resize the file system while the system was running, I had to reboot the operating system for the other two resize operations.

This means, that while you really can not extend your root partition without a reboot or halt – you can still do the whole process without the help of an other operating system (live CD, rescue disk, etc.)

Edit: With the new kernel, you can probably do much more. Not just online shrinking is now possible, but the process is done entirely in the kernel:

For users, an online resize is available for the fourth extended file system (ext4) through an I/O control (where online means that the system remains operational). This means that the entire resize is performed in the kernel, which results in a much faster resize.

2 thoughts on “Online resizing an ext4 root file system”

Leave a Reply

Your email address will not be published. Required fields are marked *