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:
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.