arch/pkg/de-p1st-installer/lib/block-device.sh

164 lines
5.0 KiB
Bash

#
# lsblk
#
# -d, --nodeps Do not print holder devices or slaves.
# -p, --paths Print full device paths.
# -l, --list Produce output in the form of a list.
# -n, --noheadings
# -x, --sort column
function get_partitions(){
# $1 block-device
# return: the following variables:
# PARTITIONS (array with one partition per entry)
# Remove first line of output (which is just the block device $1 itself)
# with sed: sed 1d
PARTITIONS="$(lsblk -pln -o name "$1" | sed 1d)" || return $?
newline_separated_to_array PARTITIONS PARTITIONS || return $?
}
function get_block_devices() {
# return: the following variables:
# BLOCK_DEVICES (array with one entry for each block device)
# Get list of devices, one per line
BLOCK_DEVICES="$(lsblk -dplnx size -o name | grep -Ev "boot|rpmb|loop" | tac)" || return $?
newline_separated_to_array BLOCK_DEVICES BLOCK_DEVICES || return $?
}
function get_block_devices_with_size() {
# return: the following variables:
# BLOCK_DEVICE_SIZES (array with two entries for each block device: device path and device size)
# Get list of devices and their sizes, one pair per line
# Use sed to remove multiple white spaces: sed 's|\s\s*| |'
BLOCK_DEVICE_SIZES="$(lsblk -dplnx size -o name,size | grep -Ev "boot|rpmb|loop" | sed 's|\s\s*| |' | tac)" || return $?
newline_to_space BLOCK_DEVICE_SIZES || return $?
space_separated_to_array BLOCK_DEVICE_SIZES BLOCK_DEVICE_SIZES || return $?
}
function partition() {
# $1: target block device
# $2: uefi or bios
if [ "$#" -ne 2 ]; then
echo "partition requires two args!";
return 1
fi
for i in "$@"; do
if [ -z "$i" ]; then
echo "partition: all given args must not be empty";
return 1;
fi
done
# if BOOT_PART_SIZE not given, set to default value
BOOT_PART_SIZE="${BOOT_PART_SIZE:='261'}"
# if too small, print warning and exit
if [ "${BOOT_PART_SIZE}" -lt "261" ]; then
echo "BOOT_PART_SIZE should be larger than 260!";
return 1;
fi
# As our data partition is encrypted,
# we need a separate boot partition!
case "$2" in
uefi)
# EFI boot partition
#
# Create a partition with fat32 as the file system type and set the
# esp flag on it.
parted --script "$1" -- mklabel gpt \
mkpart ESP fat32 2Mib "${BOOT_PART_SIZE}MiB" \
set 1 esp on \
mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $?
get_partitions "$1" || return $?
BOOT_PART="${PARTITIONS[0]}"
LUKS_PART="${PARTITIONS[1]}"
;;
bios)
# > On a BIOS/GPT configuration, a BIOS boot partition is required. GRUB embeds its `core.img`
# > into this partition.
# > For parted set/activate the flag bios_grub on the partition.
#
# archwiki -> GRUB#GUID_Partition_Table_(GPT)_specific_instructions
# https://www.gnu.org/software/grub/manual/grub/html_node/BIOS-installation.html#BIOS-installation
parted --script "$1" -- mklabel gpt \
mkpart primary 1MiB 2MiB \
set 1 bios_grub on \
mkpart primary 2MiB "${BOOT_PART_SIZE}MiB" \
mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $?
get_partitions "$1" || return $?
BOOT_PART="${PARTITIONS[2]}"
LUKS_PART="${PARTITIONS[3]}"
;;
*)
echo "Expected uefi or bios but got $2 instead!"
return 1
;;
esac
echo "boot partition: ${BOOT_PART}"
echo "luks partition: ${LUKS_PART}"
}
function format() {
# $1: uefi or bios
# $2: boot partition
# $3: luks partition
# $4: luks passphrase
# $5: FS for data partition (opened luks partition): BTRFS, EXT4 or F2FS
# $6: name of variable to store path to data partition (/dev/mapper/$(basename "$3"))
# return:
# -> boot partition formatted
# -> luks partition formatted and opened at /dev/mapper/$(basename "$3")
# -> variable with name $6 assigned to path to data partition
echo "Wiping old signatures from partitions ..."
wipefs "${2}" || return $?
wipefs "${3}" || return $?
echo "Formatting boot partition $2 ..."
mkfs.fat -F32 "$2" || return $?
echo "Creating encrypted luks partition $3 ..."
printf "%s" "$4" | cryptsetup luksFormat --type luks1 \
--cipher aes-xts-plain64 --key-size 512 --hash sha512 \
--iter-time 3500 --use-random "$3" || return $?
local luks_name
luks_name=$(basename "$3")
local -n data_part=$6 || return $?
data_part="/dev/mapper/${luks_name}"
# open luks partition
printf "%s" "$4" | cryptsetup luksOpen "$3" "${luks_name}" || return $?
echo "Formatting the data partition ${data_part} ..."
case "$5" in
BTRFS)
mkfs.btrfs "${data_part}" || return $?
;;
EXT4)
# archwiki -> Ext4#Enabling_metadata_checksums
mkfs.ext4 -O metadata_csum "${data_part}" || return $?
;;
F2FS)
# archwiki -> F2FS#Creating_a_F2FS_file_system
# - requires f2fs-tools
# - compression: "-O compression" and when mounting the filesystem, specify compress_algorithm=(lzo|lz4|zstd|lzo-rle)
mkfs.f2fs -O extra_attr,inode_checksum,sb_checksum,compression "${data_part}" || return $?
;;
*)
echo "Filesystem $5 is not yet supported!"
return 1
;;
esac
}