HowTo: Resize an LVM partition on a GPT drive after expanding the underlying array

Scenario: You have an Ubuntu Linux server. The storage system is a large RAID array, partitioned as a GPT disk and it has two partitions on it – a small boot partition and the second partition is setup for use with LVM with one or more Logical Volumes in it.

You’re starting to run out of space and intend to expand the system by adding one or more disks to the array. Once you’ve done this, you will obviously need to extend the partition to use the new space, but GPT is a slightly different kettle of fish to regular partitioning, and being a server you don’t have a GUI to use traditional tools.

So how do you do this?

The basic flow of necessary steps is essentially:

  1. Resize the array by adding new disks (not covered by this article).
  2. Resize LVM partition to use the new space in the array.
  3. Resize the Physical Volume in the LVM partition to use the newly resized space.
  4. Resize the Logical Volume(s) inside the Volume Group to their new sizes.
  5. Resize the filesystems in each Logical Volume to match their sizes.

WARNING: You are about to manipulate the partitions and data on your drive. Any mistake made during that process can result in data loss. Following this article is done at your own risk and no responsibility for any errors or data loss will be accepted by the author. Always have backups before performing any major changes to your drive’s geometry. You have been warned!

The instruction for this article was tested on the following server:

  • Ubuntu 12.04.3 LTS Server
  • An Intel SRCSATAWB PCI-E RAID controller (LSI chipset) – presents a single large drive to the OS
  • The array is a RAID6 array with eight 2TB drives (two drives were global hotspares)
  • The array was expanded from 8TB to 10TB by converting one of the global hotspares to an active member

As always, while this article is written with Ubuntu in mind, it should apply equally to just about any distribution.

So let’s begin:

  1. Using the instruction applicable to your RAID array, expand the array with new drives and begin the rebuild process. Note that it may take several hours or even days (!) to expand your array depending on what type of array you are using and the size of of your array members. You cannot proceed until the rebuild has concluded.
  2. Once the array has finished rebuilding, you will need to reboot into Recovery Mode or reboot into a Live CD/USB environment, as it is not possible to resize a partition while it is online.
  3. Since this is a GPT-partitioned disk, we have to use the Parted tool instead of FDisk. In your Recovery Mode or Live environment, open a terminal if you haven’t already got one and launch Parted to examine your array by typing in:

    $ sudo parted /dev/sda
    GNU Parted 2.3
    Using /dev/sda
    Welcome to GNU Parted! Type 'help' to view a list of commands.

    (If your array’s volume is not /dev/sda, substitute the appropriate device name)
  4. Now we have a “(parted)” prompt. First up, we need to switch the units of measurement we’re using to sectors. Do that by issuing the following command:

    (parted) u s
  5. Now list the existing partitions using the “print” command. You will see something similar to the following:

    (parted) print
    Model: INTEL SRCSATAWB (scsi)
    Disk /dev/sda: 19521474560s
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Number Start End Size File system Name Flags
    1 2048s 1953791s 1951744s ext4 Boot boot
    2 1953792s 19521474526s 19519520735s MYSERVER_HDD lvm

    NOTE: You may be shown a warning message advising that the GPT table is not at the end of the disk, saying that the disk size is smaller than the system expects it to be (because you resized your array, remember?). It will ask you if you wish to fix this. Type in “F” and hit enter. You may then be warned that the kernel is not yet aware of changes being made. Respond to this with Ignore by typing in “I” and hit enter. You may be prompted with the latter message several times whilst using Parted. Respond “Ignore” to it each time. In this environment, the current kernel does not need to be aware of the changes because we’re going to reboot at the end of it anyway.
  6. Make a note of the items that are highlighted in red above, namely the total sectors of the device (which represents the total size of your newly expanded array) and the start sector of the second partition. Please double-check your figures and make sure they are right. Any mistakes here can DESTROY YOUR DATA.
  7. Now we’re going to resize the second partition to use all of the newly created space in the array. Unfortunately GPT has no ability to resize. Instead you must remove the partition and recreate it. Don’t worry, as scary as it sounds, this process will NOT change any of the data on the drive. It simply deletes the geometry data relating to the start and end of the partition on the drive only. Remove the second partition with the following command:

    (parted) rm 2
  8. Now let’s create a new partition to replace it. Type in the following:

    (parted) mkpart
  9. You will be asked for name for the partition. Give it the same name you had for it before, or specify a new name if you like:

    Partition name?  []? MYSERVER_HDD
  10. You will then be asked about the file system type. You can’t specify LVM here, so just hit enter to accept “ext2″ – we’ll change it later:

    File system type?  [ext2]?
  11. You will then be asked for the start sector. Specify the value of the start of the second partition that you recorded earlier (don’t write the letter “s” on the end):

    Start? 1953792
  12. You will then be asked for the end sector. Specify the value of the total size of the drive that you recorded earlier minus one. If you specify the actual value, you will get an error saying that the value is “outside of the device” which is why you specify a value just inside that limit.

    End? 19521474559
  13. You will then be told that the system cannot actually make a partition up to that location (because there’s another partition on the disk taking up space), so the system will offer the next closest value which will just happen to be the maximum space remaining on the array. Simply respond “Y” for Yes.

    Warning: You requested a partition from 1953792s to 19521474559s.
    The closest location we can manage is 1953792s to 19521165533s.
    Is this still acceptable to you?

  14. Now we need to change the partition type to LVM as follows:

    (parted) toggle Partition number? 2
    Flag to Invert? lvm

  15. We’re now done with our partitioning so quit parted with the quit command:

    (parted) quit
  16. Reboot your server and boot up as normal. If you check your drive using parted or fdisk, it should now show that the total partition size includes the newly added space in your array, but nothing is using it yet. Now it’s time to tell LVM to use the new space by resizing the Physical Volume with the following command:

    $ sudo pvresize /dev/sda2
  17. Once completed, you can now check out the new free space (shown as free extents) in the LVM Physical Group by issuing the command:

    $ sudo pvdisplay
  18. Now we can start allocating this newly acquired free space to our LVM Logical Volumes. First up, let’s get a list of all our defined Logical Volumes:

    $ sudo lvdisplay
  19. Note down the “LV Name” of each Logical Volume you wish to add space to.
  20. Now let’s resize the Logical Volume. There are two ways you can do this. One method is to specify an absolute value that defines the new size of that Logical Volume, or specify a value that will add to the existing size of it. In this first example, I’m going to change the size of my Logical Volume called /dev/myserver/mylogicalvolume to be an absolute size of 20 gigabytes:

    $ sudo lvextend -L20G /dev/myserver/mylogicalvolume

    …which will make the /dev/myserver/mylogicalvolume Logical Volume 20 gigabytes in size regardless of its previous size. It does NOT add to the existing size.

    Alternatively to add space to the existing size using the following command instead:

    $ sudo lvextend -L+20G /dev/myserver/mylogicalvolume

    (note the plus sign between the -L and the 20G)

    …which will add 20 gigabytes of space to the /dev/myserver/mylogicalvolume Logical Volume. If it was 10 gigabytes in size before, it will now be 30 gigabytes in size.

    Alternatively, if you wish to allocate all remaining free space to a Logical Volume, issue the following command:

    $ sudo lvextend -l +100%FREE /dev/myserver/mylogicalvolume

    (notice that the parameter is a lowercase L instead of a capital L)

    Repeat for all Logical Volumes you are extending. There are other ways to allocate space as well, but the above are the most common methods that would be used. See the man page of the lvextend command for more information.
  21. You can confirm the new sizes for each Logical Volume by issuing the following command:

    $ sudo lvdisplay
  22. We’re nearly there! All that is left to do is now to resize the filesystems containing within our Logical Volumes to use the newly allocated space. Again, using the LV Names you recorded earlier, specify the following command for each Logical Volume you have modified:

    $ sudo resize2fs /dev/myserver/mylogicalvolume
  23. Once you have expanded the filesystems on all your Logical Volumes, you can check the free space on each of your filesystems by issuing the following command:

    $ df -h
  24. And that’s it! You have successfully expanded your LVM partition on your GPT-partitioned array! Pat yourself on the back. You are done.