**Purpose**:
The purpose of this workflow is to illustrate the process of expanding storage for a Linux server acting as a GuestVM.  We want the VM to have more storage space, so this document will go over the steps to expand that usable space.

!!! info "Assumptions"
    It is assumed you are using a RHEL variant of linux such as Rocky Linux.  This should apply to any version of Linux, but was written in a Rocky Linux 9.4 lab environment.

    This document also assumes you did not enable Logical Volume Management (LVM) when deploying your server.  If you did, you will need to perform additional LVM-specific steps after increasing the space.

!!! abstract "Oracle Linux Disk / LVM Terminology Idiosyncrasy"
    Oracle Linux refers to disks as `/dev/hda` and /dev/hda2` and not something like `/dev/sda` / `/dev/sda2`.  You will see certain parts of this document mention `/dev/hda`, in those cases, you may need to switch it to a standard `/dev/sda<#>` in order to make it work in your particular environment.

## Increase GuestVM Virtual Disk Size
This part should be fairly straight-forward.  Using whatever hypervisor is running the Linux GuestVM, expand the disk space of the disk to the desired size.

## Extend Partition Table
This step goes over how to increase the usable space of the virtual disk within the GuestVM itself after it was expanded within the hypervisor.

!!! warning "Be Careful"
    When you follow these steps, you will be deleting the existing partition and immediately re-creating it.  If you do not use the **EXACT SAME** starting sector for the new partition, you will destroy data.  Be sure to read every annotation next to each command to fully understand what you are doing.

=== "Using GDISK"

    ``` sh
    sudo dnf install gdisk -y
    gdisk /dev/<diskNumber> # (1)
    p <ENTER> # (2)
    d <ENTER> # (3)
    4 <ENTER> # (4)
    n <ENTER> # (5)
    4 <ENTER> # (6)
    <DEFAULT-FIRST-SECTOR-VALUE> (Just press ENTER) # (7)
    <DEFAULT-LAST-SECTOR-VALUE> (Just press ENTER) # (8)
    <FILESYSTEM-TYPE=8300 (Linux Filesystem)> (Just press ENTER) # (9)
    w <ENTER> # (10)
    ```
    ??? info "Detailed Command Breakdown"
        1.  The first command needs you to enter the disk identifier.  In most cases, this will likely be the first disk, such as `/dev/sda`.  You do not need to indicate a partition number in this step, as you will be asked for one in a later step after identifying all of the partitions on this disk in the next command.
        2.  This will list all of the partitions on the disk.
        3.  This will ask you for a partition number to delete.  Generally this is the last partition number listed.  In the example below, you would type `4` then press ++enter++ to schedule the deletion of the partition.
        4.  See the previous annotation for details on what entering `4` does in this context.
        5.  This tells gdisk to create a new partition.
        6.  This tells gdisk to re-make partition 4 (the one we just deleted in the example).
        7.  We just want to leave this as the default.  In my example, it would look like this:
            `First sector (34-2147483614, default = 19826688) or {+-}size{KMGTP}: 19826688`
        8.  We just want to leave this as the default.  In my example, it would look like this:
            `Last sector (19826688-2147483614, default = 2147483614) or {+-}size{KMGTP}: 2147483614`
        9.  Just leave this as-is and press ++enter++ without entering any values.  Assuming you are using XFS, as this guide was written for, the default "Linux Filesystem" is what you want for XFS.
        10.  This will write the changes to the partition table making them reality instead of just staging the changes.

    !!! example "Example Output"
        ```
        Command (? for help): p
        Disk /dev/sda: 2147483648 sectors, 1024.0 GiB
        Model: Virtual Disk
        Sector size (logical/physical): 512/4096 bytes
        Disk identifier (GUID): 8A5C2469-B07B-42AC-8E57-E756E62D37D1
        Partition table holds up to 128 entries
        Main partition table begins at sector 2 and ends at sector 33
        First usable sector is 34, last usable sector is 2147483614
        Partitions will be aligned on 2048-sector boundaries
        Total free space is 1073743838 sectors (512.0 GiB)

        Number  Start (sector)    End (sector)  Size       Code  Name
        1            2048         1230847   600.0 MiB   EF00  EFI System Partition
        2         1230848         3327999   1024.0 MiB  8300
        3         3328000        19826687   7.9 GiB     8200
        4        19826688      1073741790   502.5 GiB   8300  Linux filesystem
        ```
=== "Using FDISK"

    ``` sh
    pvdisplay # (1)
    fdisk /dev/hda # (2)
    p <ENTER> # List Partitions
    d <ENTER> # Delete a partition
    2 <ENTER> # Delete Partition 2 (e.g. /dev/hda2)
    n <ENTER> # Make a new Partition
    p <ENTER> # Primary Partition Type
    Starting Sector: <ENTER> # Use Default Value
    Ending Sector: <ENTER> # Use Default Value
    w <ENTER> # Commit all queued-up changes and write them to the disk

    
    ```
    ??? info "Detailed Command Breakdown"
        1.  Use pvdisplay to get the target disk identifier
        2.  Replace `/dev/hda` with the target disk identifier found in the previous step

    **Point of No Return**:
    When you press `w` in both cases of `gdisk` or `fdisk`, then ++enter++ the changes will be written to disk, meaning there is no turning back unless you have full GuestVM backups or a snapshot to rollback with, or something like Veeam Backup & Replication.  Be certain the first and last sector values are correctly configured before proceeding.  (Default values generally are good for this)

## Detect the New Partition Sizes
At this point, the operating system wont detect the changes without a reboot, so we are going to force the operating system to detect them immediately with the following commands to avoid a reboot (if we can avoid it).
``` sh
sudo partprobe /dev/<drive> # Drive Example: /dev/sda (Rocky) or /dev/hda (Oracle Linux)
sudo partx -u /dev/<diskNumber>
```

!!! bug "Partition Size Not Expanded?  Reboot."
    If you notice the partition still has not expanded to the desired size, you may have no choice but to reboot the server, then re-run the `gdisk` or `fdisk` commands a second time.  In my lab environment, it didn't work until I rebooted.  This might have been a hiccup on my end, but it's something to keep in mind if you run into the same issue of the size not changing.

    ``` sh
    sudo reboot
    ```

## Resize the Filesystem
=== "XFS Filesystem"
    ``` sh
    sudo xfs_growfs /
    ```

=== "Ext4 Filesystem"
    ``` sh
    resize2fs /dev/sda
    ```

=== "Ext4 Filesystem w/ LVM"
    ``` sh
    # Increase the Physical Volume Group Size
    pvdisplay # Check the Current Size of the Physical Volume
    pvresize /dev/hda2 # Enlarge the Physical Volume to Fit the New Partition Size
    pvdisplay # Validatre the Size of the Physical Volume Increased to the New Size

    # Increase the Logical Volume Group Size
    lvextend -l +100%FREE /dev/VolGroup00/LogVol00 # Get this from running "lvdisplay" to find the correct Logical Volume Name

    # Resize the Filesystem of the Disk to Fit the new Logical Volume
    resize2fs /dev/VolGroup00/LogVol00
    ```


## Validate Storage Expansion
At this point, you can leverage `lsblk` or `df -h` to determine if the usable storage space was successfully increased or not.  In this example, you can see that I increased my storage space from 512GB to 1TB.

!!! example "Example Command Output"
    Command: `lsblk | grep "sda4"`
    ```
    └─sda4   8:4    0 1014.5G  0 part /
    ```
    
    Command: `df -h | grep "sda4"`
    ```
    /dev/sda4      1015G  145G  871G  15% /
    ```
