Added BTRFS RAID1 3-disk support

This commit is contained in:
2026-01-24 11:16:07 -05:00
parent 5d573f83db
commit d210c4a104
5 changed files with 153 additions and 11 deletions

View File

@@ -61,7 +61,8 @@ select_storage_mode() {
print " 1 - BTRFS (Single disk)"
print " 2 - BTRFS DUP (Single disk with duplicate data and metadata)"
print " 3 - BTRFS RAID1 (Two disks with full redundancy)"
print " 4 - ext4 (Single disk)"
print " 4 - BTRFS RAID1 (Three disks with enhanced metadata redundancy)"
print " 5 - ext4 (Single disk)"
read -r storage_choice
case "$storage_choice" in
@@ -76,6 +77,11 @@ select_storage_mode() {
print "BTRFS RAID1 mode selected. You will need two disks of similar size."
;;
"4")
STORAGE_MODE="raid1-3disk"
FILESYSTEM="btrfs"
print "BTRFS RAID1 3-disk mode selected. You will need three disks of similar size."
;;
"5")
STORAGE_MODE="single"
FILESYSTEM="ext4"
print "ext4 on single disk selected."
@@ -137,6 +143,10 @@ main() {
if ! select_raid1_disks; then
exit 1
fi
elif [ "$STORAGE_MODE" = "raid1-3disk" ]; then
if ! select_raid1_3disk_disks; then
exit 1
fi
else
if ! select_single_disk; then
exit 1
@@ -153,6 +163,8 @@ main() {
# Setup encryption
if [ "$STORAGE_MODE" = "raid1" ]; then
setup_encryption_raid1 "$ROOT_PARTITION" "$ROOT_PARTITION_2"
elif [ "$STORAGE_MODE" = "raid1-3disk" ]; then
setup_encryption_raid1_3disk "$ROOT_PARTITION" "$ROOT_PARTITION_2" "$ROOT_PARTITION_3"
else
setup_encryption_single "$ROOT_PARTITION"
fi

View File

@@ -75,17 +75,31 @@ format_btrfs_raid1() {
run_visible_cmd mkfs.btrfs --csum xxhash --data raid1 --metadata raid1 "$device1" "$device2"
}
# Format three devices as BTRFS RAID1 with enhanced metadata redundancy
# Arguments:
# $1 - first device path
# $2 - second device path
# $3 - third device path
format_btrfs_raid1_3disk() {
local device1="$1"
local device2="$2"
local device3="$3"
print "Formatting ${device1}, ${device2}, and ${device3} as btrfs RAID1..."
run_visible_cmd mkfs.btrfs --csum xxhash --data raid1 --metadata raid1c3 "$device1" "$device2" "$device3"
}
# Format the root filesystem based on configuration
# Arguments:
# $1 - filesystem type (ext4, btrfs, btrfs-dup)
# $2 - storage mode (single, raid1)
# $2 - storage mode (single, raid1, raid1-3disk)
format_root_filesystem() {
local filesystem="$1"
local storage_mode="$2"
case "$filesystem" in
"ext4")
if [ "$storage_mode" = "raid1" ]; then
if [ "$storage_mode" = "raid1" ] || [ "$storage_mode" = "raid1-3disk" ]; then
print_error "ext4 cannot be used with RAID1."
exit 1
fi
@@ -98,7 +112,9 @@ format_root_filesystem() {
"btrfs"|*)
if [ "$storage_mode" = "raid1" ]; then
format_btrfs_raid1 /dev/mapper/cryptroot-primary /dev/mapper/cryptroot-secondary
format_btrfs_raid1 /dev/mapper/cryptroot-1 /dev/mapper/cryptroot-2
elif [ "$storage_mode" = "raid1-3disk" ]; then
format_btrfs_raid1_3disk /dev/mapper/cryptroot-1 /dev/mapper/cryptroot-2 /dev/mapper/cryptroot-3
else
format_btrfs /dev/mapper/cryptroot
fi
@@ -109,7 +125,7 @@ format_root_filesystem() {
# Mount the root filesystem with appropriate options
# Arguments:
# $1 - filesystem type (ext4, btrfs, btrfs-dup)
# $2 - storage mode (single, raid1)
# $2 - storage mode (single, raid1, raid1-3disk)
mount_root_filesystem() {
local filesystem="$1"
local storage_mode="$2"
@@ -123,7 +139,9 @@ mount_root_filesystem() {
*)
if [ "$storage_mode" = "raid1" ]; then
run_visible_cmd mount -o "noatime,discard=async" /dev/mapper/cryptroot-primary "${MOUNT_POINT}"
run_visible_cmd mount -o "noatime,discard=async" /dev/mapper/cryptroot-1 "${MOUNT_POINT}"
elif [ "$storage_mode" = "raid1-3disk" ]; then
run_visible_cmd mount -o "noatime,discard=async" /dev/mapper/cryptroot-1 "${MOUNT_POINT}"
else
run_visible_cmd mount -o "noatime,discard=async" /dev/mapper/cryptroot "${MOUNT_POINT}"
fi
@@ -152,6 +170,9 @@ format_and_mount_filesystems() {
format_efi_partition "$EFI_PARTITION"
if [ "$storage_mode" = "raid1" ]; then
format_efi_partition "$EFI_PARTITION_2"
elif [ "$storage_mode" = "raid1-3disk" ]; then
format_efi_partition "$EFI_PARTITION_2"
format_efi_partition "$EFI_PARTITION_3"
fi
# Format and mount root

View File

@@ -135,14 +135,51 @@ setup_encryption_raid1() {
# Setup first disk
setup_luks_encryption "$root_partition_1" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition_1" "$ENCRYPTION_PASSWORD" "cryptroot-primary"
open_luks_container "$root_partition_1" "$ENCRYPTION_PASSWORD" "cryptroot-1"
LUKS_UUID=$(get_luks_uuid "$root_partition_1")
# Setup second disk
setup_luks_encryption "$root_partition_2" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition_2" "$ENCRYPTION_PASSWORD" "cryptroot-secondary"
open_luks_container "$root_partition_2" "$ENCRYPTION_PASSWORD" "cryptroot-2"
LUKS_UUID_2=$(get_luks_uuid "$root_partition_2")
# Clear password from memory
unset ENCRYPTION_PASSWORD
}
# Setup encryption for RAID1 3-disk mode
# Arguments:
# $1 - first root partition path
# $2 - second root partition path
# $3 - third root partition path
# Sets:
# LUKS_UUID - UUID of the first LUKS container
# LUKS_UUID_2 - UUID of the second LUKS container
# LUKS_UUID_3 - UUID of the third LUKS container
setup_encryption_raid1_3disk() {
local root_partition_1="$1"
local root_partition_2="$2"
local root_partition_3="$3"
if ! prompt_encryption_password; then
exit 1
fi
# Setup first disk
setup_luks_encryption "$root_partition_1" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition_1" "$ENCRYPTION_PASSWORD" "cryptroot-1"
LUKS_UUID=$(get_luks_uuid "$root_partition_1")
# Setup second disk
setup_luks_encryption "$root_partition_2" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition_2" "$ENCRYPTION_PASSWORD" "cryptroot-2"
LUKS_UUID_2=$(get_luks_uuid "$root_partition_2")
# Setup third disk
setup_luks_encryption "$root_partition_3" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition_3" "$ENCRYPTION_PASSWORD" "cryptroot-3"
LUKS_UUID_3=$(get_luks_uuid "$root_partition_3")
# Clear password from memory
unset ENCRYPTION_PASSWORD
}

View File

@@ -162,9 +162,42 @@ select_raid1_disks() {
return 0
}
# Select and configure disks for RAID1 3-disk installation
# Sets:
# INSTALL_DISK - first disk path
# INSTALL_DISK_2 - second disk path
# INSTALL_DISK_3 - third disk path
# EFI_PARTITION, EFI_PARTITION_2, EFI_PARTITION_3 - EFI partition paths
# ROOT_PARTITION, ROOT_PARTITION_2, ROOT_PARTITION_3 - root partition paths
select_raid1_3disk_disks() {
show_disk_info
if ! select_disk "Please enter the path to the FIRST disk for RAID1 (e.g. /dev/sda)." INSTALL_DISK; then
return 1
fi
if ! select_disk "Enter the path to the SECOND disk for RAID1 (e.g. /dev/sdb). This must be a DIFFERENT disk." INSTALL_DISK_2; then
return 1
fi
if ! select_disk "Enter the path to the THIRD disk for RAID1 (e.g. /dev/sdc). This must be a DIFFERENT disk." INSTALL_DISK_3; then
return 1
fi
if ! validate_disks_different "$INSTALL_DISK" "$INSTALL_DISK_2" "$INSTALL_DISK_3"; then
return 1
fi
if ! require_confirmation "Last warning: Are you sure you want to install Arch Linux in RAID1 3-disk mode to '$INSTALL_DISK', '$INSTALL_DISK_2', and '$INSTALL_DISK_3'? All data on ALL THREE disks will be wiped."; then
return 1
fi
return 0
}
# Partition disks based on storage mode
# Arguments:
# $1 - storage mode (single or raid1)
# $1 - storage mode (single, raid1, or raid1-3disk)
partition_disks() {
local storage_mode="$1"
@@ -180,6 +213,25 @@ partition_disks() {
EFI_PARTITION_2="$EFI_PARTITION"
ROOT_PARTITION_2="$ROOT_PARTITION"
EFI_PARTITION="$primary_efi"
ROOT_PARTITION="$primary_root"
elif [ "$storage_mode" = "raid1-3disk" ]; then
wipe_disk "$INSTALL_DISK"
wipe_disk "$INSTALL_DISK_2"
wipe_disk "$INSTALL_DISK_3"
create_gpt_partitions "$INSTALL_DISK"
local primary_efi="$EFI_PARTITION"
local primary_root="$ROOT_PARTITION"
create_gpt_partitions "$INSTALL_DISK_2"
EFI_PARTITION_2="$EFI_PARTITION"
ROOT_PARTITION_2="$ROOT_PARTITION"
create_gpt_partitions "$INSTALL_DISK_3"
EFI_PARTITION_3="$EFI_PARTITION"
ROOT_PARTITION_3="$ROOT_PARTITION"
EFI_PARTITION="$primary_efi"
ROOT_PARTITION="$primary_root"
else

View File

@@ -54,18 +54,38 @@ create_boot_entry_raid1() {
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options rd.luks.name=${luks_uuid_1}=cryptroot-primary rd.luks.name=${luks_uuid_2}=cryptroot-secondary rd.luks.options=${luks_uuid_1}=discard rd.luks.options=${luks_uuid_2}=discard root=/dev/mapper/cryptroot-primary
options rd.luks.name=${luks_uuid_1}=cryptroot-1 rd.luks.name=${luks_uuid_2}=cryptroot-2 rd.luks.options=${luks_uuid_1}=discard rd.luks.options=${luks_uuid_2}=discard root=/dev/mapper/cryptroot-1
EOF
}
# Create boot entry for RAID1 3-disk installation
# Arguments:
# $1 - first LUKS UUID
# $2 - second LUKS UUID
# $3 - third LUKS UUID
create_boot_entry_raid1_3disk() {
local luks_uuid_1="$1"
local luks_uuid_2="$2"
local luks_uuid_3="$3"
run_cmd_in_chroot sh -c "cat > /boot/loader/entries/arch.conf" <<EOF
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options rd.luks.name=${luks_uuid_1}=cryptroot-1 rd.luks.name=${luks_uuid_2}=cryptroot-2 rd.luks.name=${luks_uuid_3}=cryptroot-3 rd.luks.options=${luks_uuid_1}=discard rd.luks.options=${luks_uuid_2}=discard rd.luks.options=${luks_uuid_3}=discard root=/dev/mapper/cryptroot-1
EOF
}
# Create appropriate boot entry based on storage mode
# Arguments:
# $1 - storage mode (single, raid1)
# $1 - storage mode (single, raid1, raid1-3disk)
create_boot_entry() {
local storage_mode="$1"
if [ "$storage_mode" = "raid1" ]; then
create_boot_entry_raid1 "$LUKS_UUID" "$LUKS_UUID_2"
elif [ "$storage_mode" = "raid1-3disk" ]; then
create_boot_entry_raid1_3disk "$LUKS_UUID" "$LUKS_UUID_2" "$LUKS_UUID_3"
else
create_boot_entry_single "$LUKS_UUID"
fi