Linux Notes: Extending a File System in a Virtual Disk

Recently, a comment came to the community about extending a virtual disk and the filesystem within. Given the filesystem type, it is possible to extend without rebooting the guest operating system, even if it is the boot device. In fact, it has been possible to do this on Linux and Windows for many years, but the Linux process seems to be an arcane invocation of commands. It is not magic.

There are several ways to add storage to a virtual disk. You can add a new virtual disk, extend the virtual disk, or even mount iSCSI volumes. In any of these cases, if you want to extend your filesystem, you can pursue a few options.

Mounts or Symlinks

For a new virtual disk, an iSCSI mount, or an NFS mount, you have two options. You can mount a volume onto part of the existing filesystem or use a symlink to redirect data to the new disk. In either case, the steps are the same. In the following, “source” and “destination” should be full paths.

  1. For a new virtual disk or an iSCSI mount, create a filesystem on the new device. I usually use the default for the operating system.
  2. For a new virtual disk, an iSCSI mount, or an NFS mount, copy all the data within the source location to the new filesystem. Be sure to preserve all access, user, group, and permissions settings. I usually use one of the following tools, as straight /bin/cp often does not catch everything, especially if there are existing symlinks:
    • rsync -aE source destination
    • Only works as root: tar -cf - source | (cd destination; tar -xpf -)
  3. Remove the original data.
  4. Mount or symlink the new location on top of the old.
    • mount destination source
    • rm -rf source; ln -s destination source
  5. If using a mount, update /etc/fstab.

Extending Volume

There are three use cases for extending filesystems, and they all depend on what is underneath the filesystem. The stack can be one of the following:

Filesystem Layers
Potential Filesystem Layers

Filesystem options 1 and 2 rely on resizing the underlying disk to make it larger. Option 3 can be either a resized disk or a new disk. Each of the layers outlined needs to be resized in some fashion.

Option 1 is often used by databases that require raw disk devices and is not recommended for much outside of that. There are cases in which people use this option for non-database disks; however, this is not recommended.

Option 2 partitions a disk into multiple areas.

Option 3 joins more than one disk together into a logical volume.

What are the nuts and bolts of extending the volume for each option? For ext2/ext3/ext4-based filesystems, you use the following commands. Let us assume the disk name is /dev/sdb for these examples.

Option 1

Option 1 is by far the easiest to extend. If your filesystem has the resize capability, that capability is what you use.

  • Check if disk is available: dmesg | grep sdb
    If the line reads something like: sdb: sdb1 sdb2 sdb3, then you have multiple partitions, and you cannot use this option.
  • Check if disk is mounted: df -h | grep sdb
    If the result is blank or has a number in the device name, then you cannot use this option.
  • Ensure there are no other partitions on disk: fdisk -l /dev/sdb
    If one of the partitions has a type of Linux LVM, you cannot use this option.
  • Verify the disk: fsck /dev/sdb
  • Resize the filesystem: resize2fs /dev/sdb
Option 2

Option 2 is very similar to option 1, except that you need to resize the partition as well, not just the filesystem. You can only extend the last partition easily. Assume three partitions, where /dev/sdb3 is the last partition.

  • Check if disk is available: dmesg | grep sdb
  • Check if disk is mounted: df -h | grep sdb
  • Ensure there are no other partitions on disk: fdisk -l /dev/sdb
    If the last partition has a type of Linux LVM, you cannot use this option. If the partition you wish to extend is not the last partition, stop.
  • Resize the last partition:
    fdisk /dev/sdb
    Command (m for help): d
    Partition number (1,2,3 default 3): 3
    Partition 3 has been deleted.
    Command (m for help): n
    Partition type:
    p primary (2 primary, 0 extended, 2 free)
    e extended
    Select (default p): p
    Partition number (3-4, default 3): 3
    First sector (1026048-854745087, default 1026048): <enter>
    Last sector, +sectors or +size{K,M,G,T,P} (1026048-854745087, default 854745087): <enter>
    Created a new partition 3 of type 'Linux' and size of the rest of the disk MiB.
    Command (m for help): p
    Command (m for help): w
  • Verify the partition: fsck /dev/sdb
  • Resize the filesystem: resize2fs /dev/sdb3
Option 3

Option 3 is a bit more complex and depends on whether you are adding to an existing disk or to a new disk. If you are adding to an existing disk, you can either create a new partition and therefore extend any logical volume, or add to the last partition as in option 2. I prefer adding more partitions or newer disks, as it simplifies the work. Therefore, that is the approach I cover here. The start is very similar to the start of options 1 and 2, except that you also need to add a partition or new disk, and you do not extend the filesystem.

  • Check if disk is available: dmesg | grep sdb
  • Check if disk is mounted: df -h | grep sdb
  • Ensure there are no other partitions on disk: fdisk -l /dev/sdb
  • Resize the last partition:
    fdisk /dev/sdb
    Command (m for help): n
    Partition type:
    p primary (2 primary, 0 extended, 2 free)
    e extended
    Select (default p): p
    Partition number (3-4, default 3): 3
    First sector (1026048-854745087, default 1026048): <enter>
    Last sector, +sectors or +size{K,M,G,T,P} (1026048-854745087, default 854745087): <enter>
    Created a new partition 3 of type 'Linux' and size of the rest of the disk MiB.
    Command (m for help): t
    Partition number: 3
    Hex code (type L to list codes): 8e
    Changed system type of partition 3 to 8e (Linux LVM)

    Command (m for help): p
    Command (m for help): w
  • Verify the partition: fsck /dev/sdb3
  • Extend and resize the logical volume:
    pvcreate /dev/sdb3
    Physical volume "/dev/sdb3" successfully created
    vgdisplay
    --- Volume group ---
    VG name  VolGroup00
    ...
    vgextend VolGroup00 /dev/sdb3
    lvdisplay
    --- Logical volume ---
    LV Name.  /dev/VolGroup00/LogVol00
    lvextend /dev/VolGroup00/LogVol00 /dev/sdb3
    Extending logical volume root to <size> GiB
    Logical volume LogVol00 successfully resized
    ...
    resize2fs /dev/VolGroup00/LogVol00
Option 3 – Extend Existing Volume using LVM

Similar to option 3, this approach requires you to do the following:

  • Check if disk is available: dmesg | grep sdb
  • Check if disk is mounted: df -h | grep sdb
  • Ensure there are no other partitions on disk: fdisk -l /dev/sdb
  • Resize the last partition:
    fdisk /dev/sdb
    Command (m for help): d
    Partition number (1-2, default 2): 2
    Command (m for help): n
    Partition type:
    p primary (2 primary, 0 extended, 2 free)
    e extended
    Select (default p): p
    Partition number (2-4, default 2): 2
    First sector (1026048-854745087, default 1026048): <enter>
    Last sector, +sectors or +size{K,M,G,T,P} (1026048-854745087, default 854745087): <enter>
    Created a new partition 2 of type 'Linux' and size of the rest of the disk MiB.
    Command (m for help): t
    Partition number: 2
    Hex code (type L to list codes): 8e
    Changed system type of partition 3 to 8e (Linux LVM)

    Command (m for help): p
    Command (m for help): w
  • Resize the physical volume:
    pvresize /dev/sdb
  • Resize the Logical Volume:
    lvresize -l +100%FREE /dev/VolGroup00/LogVol00
  • Resize the filesystem:
    resize2fs /dev/VolGroup00/LogVol00

Final Notes

If you are using XFS instead of ext? filesystems, use xfs_growfs instead of resize2fs. Lastly, if you are modifying the boot disk via fdisk, usually /dev/sda, then a reboot is required.

Join the Conversation

  1. Edward Haletky

3 Comments

  1. Hi, Good post.
    I want to ask about Option 1.
    You mentioned raw disk so did you mean RDM disks?
    For example if we want to use it option 1 for VMDK disk. Is it best practise for database VM’s? Or we must use Option 2?

  2. Hello Mehmet,

    Raw Disks in Linux are different than RDMs from VMware. Raw Disks refer to /dev/rdisk? devices which usually reference a /dev/sd? device. Raw is the type of IO allowed and are not usually referenced by partition numbers but the entire disk itself. Many larger databases wish for the entire disk for themselves.

    From a VMware perspective, whether you use RDMs or VMDKs, the expansion approaches are all the same and are independent of how the new or expanded disk is presented.

    -Edward L. Haletky, aka Texiwill

Leave a comment

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

I accept the Privacy Policy

This site uses Akismet to reduce spam. Learn how your comment data is processed.