Local Storage (Configuring an LVM Volume on Voltage Park On-Demand Bare Metal Servers)

This guide explains how to configure an LVM volume from six unmounted NVMe SSDs and mount it at /localnvme.

By default, Voltage Park On-Demand bare metal servers have one NVMe SSD mounted at the root partition. Additional NVMe SSDs are unmounted, offering high flexibility for custom HPC workloads.

Step 1: Update and Install LVM2

Before proceeding, ensure that your system is updated and that the LVM2 package is installed.

sudo apt update
sudo apt install -y lvm2

Verify that LVM2 is installed correctly by checking for the pvcreate command:

which pvcreate

Step 2: Check Available Disks

After deploying your server, verify the presence of all disks:

sudo fdisk -l

Ensure that the following disks are available:

  • /dev/nvme1n1

  • /dev/nvme2n1

  • /dev/nvme3n1

  • /dev/nvme4n1

  • /dev/nvme5n1

  • /dev/nvme6n1

Alternatively, list all block devices:

lsblk

Step 3: Initialize Physical Volumes

Create physical volumes for all six unmounted NVMe SSDs:

sudo pvcreate /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/nvme5n1 /dev/nvme6n1

Verify the setup:

sudo pvs

Step 4: Create a Volume Group

Create a volume group named nvme_vg using all six physical volumes:

sudo vgcreate nvme_vg /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/nvme5n1 /dev/nvme6n1

Verify the volume group:

sudo vgs

Step 5: Create a Logical Volume

Create a logical volume named nvme_lv spanning the entire volume group:

sudo lvcreate -l 100%FREE -n nvme_lv nvme_vg

Verify the logical volume:

sudo lvs

Step 6: Format the Logical Volume

Format the logical volume with the ext4 filesystem:

sudo mkfs.ext4 /dev/nvme_vg/nvme_lv

Step 7: Temporarily Mount the Logical Volume

Create the mount point directory:

sudo mkdir -p /localnvme

Mount the logical volume:

sudo mount /dev/nvme_vg/nvme_lv /localnvme

Verify the mount:

df -h

Ensure that /dev/mapper/nvme_vg-nvme_lv is listed as mounted at /localnvme.


Create a symbolic link to /home/ubuntu/localnvme:

sudo ln -s /localnvme /home/ubuntu/localnvme

Verify the symbolic link:

ls -l /home/ubuntu/localnvme

Step 9: Configure Persistent Mounting

Find the UUID of the logical volume:

sudo blkid /dev/nvme_vg/nvme_lv

Copy the UUID from the output and add it to /etc/fstab:

sudo nano /etc/fstab

Append the following line at the bottom, replacing [INSERT UUID HERE] with the actual UUID:

UUID=[INSERT UUID HERE] /localnvme ext4 defaults 0 0

Save and exit (Ctrl + X, then Y, then Enter).

Verify the fstab file:

sudo findmnt --verify

Ensure there are 0 errors before proceeding.


Step 10: Remount and Validate

Remount all partitions:

sudo mount -a

Verify that the logical volume is correctly mounted:

df -h

Confirm that /dev/mapper/nvme_vg-nvme_lv is mounted at /localnvme with the expected size.

List contents of both directories to validate:

ls /localnvme
ls /home/ubuntu/localnvme

Step 11: Reboot (Optional)

Reboot to ensure the configuration persists across system restarts:

sudo reboot

After rebooting, verify that /localnvme is mounted correctly:

df -h

Experimental Automated setup script

#!/bin/bash

# Color codes
RED='\e[31m'
GREEN='\e[32m'
YELLOW='\e[33m'
BLUE='\e[34m'
CYAN='\e[36m'
RESET='\e[0m'

############################################################
# This script:
# 1) Lists unmounted NVMe disks.
# 2) Creates an LVM volume from selected disks.
# 3) Mounts the new LVM volume at a user-provided mount point.
# 4) Offers the option to create a symbolic link in a chosen user's home directory.
# 5) Explains symbolic links and any necessary permission fixes.
############################################################

############################################################
# Disk Discovery
############################################################

# This function finds only those NVMe disks whose partitions are not mounted.
list_disks() {
    echo -e "\n${CYAN}Scanning for unmounted NVMe disks...${RESET}"

    available_disks=()
    all_nvme_disks=( $(lsblk -dno NAME -e7 | grep nvme) )

    for disk in "${all_nvme_disks[@]}"; do
        part_mounts=( $(lsblk -rno NAME,TYPE,MOUNTPOINT "/dev/$disk" | awk '$2=="part" && $3!="" {print $3}') )
        if [ ${#part_mounts[@]} -eq 0 ]; then
            available_disks+=("/dev/$disk")
        fi
    done

    if [ ${#available_disks[@]} -eq 0 ]; then
        echo -e "${RED}No unmounted NVMe disks found. Exiting.${RESET}"
        exit 1
    fi

    echo -e "\n${GREEN}Available unmounted NVMe disks:${RESET}"
    for i in "${!available_disks[@]}"; do
        echo -e "${YELLOW}$((i+1))) ${available_disks[$i]}${RESET}"
    done
}

validate_disks() {
    for disk in "${selected_disks[@]}"; do
        if mount | grep -q "^$disk"; then
            echo -e "${RED}Error: $disk is already mounted. Please select unmounted disks.${RESET}"
            exit 1
        fi
    done
}

get_user_choices() {
    read -p "Enter the number of disks to use for LVM (default: all found): " disk_count
    disk_count=${disk_count:-${#available_disks[@]}}
    selected_disks=("${available_disks[@]:0:$disk_count}")
    validate_disks
    echo -e "\n${BLUE}Selected disks: ${selected_disks[@]}${RESET}"

    read -p "Enter mount point (default: /localnvme): " mount_path
    mount_path=${mount_path:-/localnvme}
}

############################################################
# LVM Setup and Mounting
############################################################

setup_lvm() {
    echo -e "\n${CYAN}Setting up LVM...${RESET}"
    sudo apt update && sudo apt install -y lvm2

    echo -e "\n${GREEN}Initializing physical volumes...${RESET}"
    for disk in "${selected_disks[@]}"; do
        if sudo pvs | grep -q "$disk"; then
            echo -e "${YELLOW}Warning: $disk is already part of a volume group. Skipping pvcreate.${RESET}"
        else
            if ! sudo pvcreate "$disk"; then
                echo -e "${RED}Error: Failed to initialize physical volume on $disk. Exiting.${RESET}"
                exit 1
            fi
        fi
    done

    echo -e "\n${GREEN}Creating volume group (nvme_vg)...${RESET}"
    if ! sudo vgcreate nvme_vg "${selected_disks[@]}"; then
        echo -e "${RED}Error: Failed to create volume group. Exiting.${RESET}"
        exit 1
    fi

    echo -e "\n${GREEN}Creating logical volume (nvme_lv)...${RESET}"
    if ! sudo lvcreate -l 100%FREE -n nvme_lv nvme_vg; then
        echo -e "${RED}Error: Failed to create logical volume. Exiting.${RESET}"
        exit 1
    fi

    echo -e "\n${GREEN}Formatting logical volume...${RESET}"
    sudo mkfs.ext4 /dev/nvme_vg/nvme_lv
}

mount_lvm() {
    echo -e "\n${CYAN}Creating mount point at $mount_path...${RESET}"
    sudo mkdir -p "$mount_path"

    echo -e "\n${GREEN}Mounting LVM volume...${RESET}"
    if ! sudo mount /dev/nvme_vg/nvme_lv "$mount_path"; then
        echo -e "${RED}Error: Failed to mount LVM volume. Exiting.${RESET}"
        exit 1
    fi
}

persist_mount() {
    echo -e "\n${CYAN}Persisting mount configuration...${RESET}"
    uuid=$(sudo blkid -s UUID -o value /dev/nvme_vg/nvme_lv)
    if [ -z "$uuid" ]; then
        echo -e "${RED}Error: Could not retrieve UUID. Exiting.${RESET}"
        exit 1
    fi
    echo "UUID=$uuid $mount_path ext4 defaults 0 0" | sudo tee -a /etc/fstab
    echo -e "\n${GREEN}Verifying fstab...${RESET}"
    sudo findmnt --verify
}

############################################################
# Symbolic Link Setup
############################################################
setup_symbolic_link() {
    echo -e "\n${CYAN}Would you like to create a symbolic link to your mount point? [y/N]${RESET}"
    read -p "Enter 'y' or 'n': " symlink_choice

    # Convert symlink_choice to lowercase
    symlink_choice="${symlink_choice,,}"

    if [[ "$symlink_choice" == "y" ]]; then
        echo -e "\n${CYAN}Listing system users (excluding root):${RESET}"
        users=( $(awk -F: '{ if($1 != "root") print $1}' /etc/passwd) )
        for i in "${!users[@]}"; do
            echo -e "${YELLOW}$((i+1))) ${users[$i]}${RESET}"
        done

        read -p "Select a user for the symbolic link: " user_choice
        if [[ "$user_choice" =~ ^[0-9]+$ ]] && [ "$user_choice" -ge 1 ] && [ "$user_choice" -le ${#users[@]} ]; then
            selected_user="${users[$((user_choice-1))]}"
        else
            echo -e "${RED}Invalid user selection. Skipping symbolic link creation.${RESET}"
            return
        fi

        user_home="/home/$selected_user"
        if [ ! -d "$user_home" ]; then
            echo -e "${RED}Home directory for user $selected_user not found. Skipping symbolic link creation.${RESET}"
            return
        fi

        local link_path="$user_home/localnvme"
        echo -e "\n${BLUE}Creating symbolic link at $link_path...${RESET}"
        sudo ln -s "$mount_path" "$link_path"
        echo -e "\n${YELLOW}Note: A symbolic link (symlink) is a shortcut that points to another location."
        echo -e "If $selected_user does not have permission to access $mount_path, run:${RESET}"
        echo -e "${CYAN}sudo chown -R $selected_user:$selected_user $mount_path${RESET}"
        echo -e "\n${YELLOW}This command changes ownership of $mount_path to $selected_user so they can read/write in that directory if needed.${RESET}"
    else
        echo -e "${BLUE}Skipping symbolic link creation.${RESET}"
    fi
}

############################################################
# Main Menu
############################################################
main_menu() {
    while true; do
        echo -e "\n${YELLOW}VoltagePark LVM Creator${RESET}"
        echo -e "${CYAN}1) List available unmounted NVMe disks${RESET}"
        echo -e "${CYAN}2) Configure LVM and mount${RESET}"
        echo -e "${CYAN}3) Exit${RESET}"
        read -p "Select an option: " choice
        case $choice in
            1)
                list_disks
                ;;
            2)
                list_disks
                get_user_choices
                setup_lvm
                mount_lvm
                persist_mount
                setup_symbolic_link
                echo -e "\n${GREEN}Setup complete!${RESET}"
                ;;
            3)
                exit 0
                ;;
            *)
                echo -e "${RED}Invalid option. Try again.${RESET}"
                ;;
        esac
    done
}

# Start the script
main_menu
```

Conclusion

Congratulations! You have successfully created an LVM volume using six unmounted NVMe SSDs and permanently mounted it at /localnvme. You can now use this storage for high-performance workloads.

If you encounter issues, reach out to support@voltagepark.com for assistance.

Last updated