Skip to content

Instantly share code, notes, and snippets.

@Apsu
Created May 7, 2025 20:43
Show Gist options
  • Save Apsu/edf9bc0f32df73a1d04daeb3eebafbb1 to your computer and use it in GitHub Desktop.
Save Apsu/edf9bc0f32df73a1d04daeb3eebafbb1 to your computer and use it in GitHub Desktop.
RAID array creator
#!/usr/bin/env bash
set -euo pipefail
# Require: RAID name, mount path, RAID level
if [[ $# -ne 3 ]]; then
echo "Usage: $0 <raid_name> <mount_path> <raid_level>"
echo "Example: $0 data /mnt/data 0"
exit 1
fi
raid_name="$1"
mount_path="$2"
raid_level="$3"
md_path="/dev/md/$raid_name"
# Require absolute mount path
if [[ "$mount_path" != /* ]]; then
echo "Error: mount path must be absolute. Got '$mount_path'."
exit 1
fi
# Check for existing RAID config
if grep -q "$md_path" /etc/mdadm/mdadm.conf 2>/dev/null; then
echo "Error: RAID device '$md_path' already exists in mdadm.conf."
exit 1
fi
# Check if mount path is already mounted
if mountpoint -q "$mount_path"; then
echo "Error: '$mount_path' is already mounted."
exit 1
fi
# Check if already in fstab
if grep -q -E "[[:space:]]$mount_path[[:space:]]" /etc/fstab; then
echo "Error: mount path '$mount_path' already exists in /etc/fstab."
exit 1
fi
# Discover eligible NVMe disks
disks=()
sizes=()
while IFS= read -r disk; do
if lsblk -npr --output FSTYPE "$disk" | grep -q "linux_raid_member"; then
continue
fi
size=$(lsblk -nbdo SIZE "$disk")
disks+=("$disk")
sizes+=("$size")
done < <(lsblk -dnp --output NAME | grep "^/dev/nvme")
if [[ ${#disks[@]} -eq 0 ]]; then
echo "No eligible NVMe disks found."
exit 1
fi
# Verify all disks are same size
first_size="${sizes[0]}"
for sz in "${sizes[@]}"; do
if [[ "$sz" != "$first_size" ]]; then
echo "Error: Disks are not the same size:"
paste <(printf "%s\n" "${disks[@]}") <(printf "%s\n" "${sizes[@]}")
exit 1
fi
done
# Display disks
echo "The following disks will be used for RAID$raid_level:"
for disk in "${disks[@]}"; do
echo "→ $disk"
lsblk -d "$disk"
done
# Confirm
read -rp "Proceed with creating RAID$raid_level on these disks? This will erase all data. [y/N]: " confirm
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
echo "Aborted by user."
exit 1
fi
# Create the RAID array
mdadm --create --verbose "$md_path" \
--level="$raid_level" \
--raid-devices=${#disks[@]} \
"${disks[@]}"
# Persist config and update initramfs
mdadm --detail --scan "$md_path" | tee -a /etc/mdadm/mdadm.conf
update-initramfs -u
# Format and mount
mkfs.ext4 "$md_path"
mkdir -p "$mount_path"
echo "$md_path $mount_path ext4 defaults,nofail,discard 0 0" | tee -a /etc/fstab
mount "$mount_path"
echo "RAID$raid_level array '$md_path' created and mounted at '$mount_path'."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment