From 16e2c85922848adb1c21a46a6cc23846ef94b951 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 23 Jan 2014 07:40:58 +0100 Subject: Enable RAID root system. Quoting /usr/share/doc/cryptsetup/README.keyctl : The current state for dm-crypt in Linux is that it is single threaded, thus every dm-crypt mapping only uses a single core for crypto operations. To use the full power of your many-core processor it is thus necessary to split the dm-crypt device. For Linux software raid arrays the easiest segmentation is to just put the dm-crypt layer below the software raid layer. However, this seems no longer true since 2.6.38, cf. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=714806 https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c029772125594e31eb1a5ad9e0913724ed9891f2 http://kernelnewbies.org/Linux_2_6_38#head-49f5f735853f8cc7c4d89e5c266fe07316b49f4c Therefore encrypting the array (instead of assembling an array of encrypted disks) shouldn't cause a performance cost. Also, it makes the ramdisk much easier to configure :-) --- include/partition.sh | 121 +++++++++++++++++++++++++++++++-------- src/fripost-partman-udeb/base.sh | 16 ++++++ 2 files changed, 112 insertions(+), 25 deletions(-) diff --git a/include/partition.sh b/include/partition.sh index 5418341..1d5b4c3 100755 --- a/include/partition.sh +++ b/include/partition.sh @@ -19,40 +19,111 @@ set -ue . /lib/fripost-partman/base.sh -device=/dev/sda -# Umount existing mountpoints -for mp in $(sed -nr "s#^$device\S*\s+(\S+).*#\1#p" /proc/mounts); do - umount "$mp" +#device=/dev/sda +device='/dev/sda /dev/sdb' # space-separated form mutiple disks (raid) +raidLevel=1 # raid level (leave empty for no raid) +raidActiveDev=2 # number active devices in the array + + +n=0 +for d in $device; do + n=$(( $n + 1 )) + wait_for_device $d + + # Umount existing mountpoints + for mp in $(sed -nr "s#^$d\S*\s+(\S+).*#\1#p" /proc/mounts); do + umount "$mp" + done + + # Wipe the disk + fripost_wipe $d + + # Create a disk label + /sbin/parted -s $d mklabel gpt + log "Created disklabel GPT for device $d" + + # Don't make an array of these partitions, but keep the alignment + # regardless (at the expense of loosing some megabytes) + + # Create a EFI partition if needed; otherwise, create a partition needed + # to put GRUB on GPT disklabels. + if [ -d /proc/efi -o -d /sys/firmware/efi ]; then + size=256M + name=efi + if [ $n -eq 1 ]; then + anna-install dosfstools-udeb + part_efi=$( fripost_mkpart $d $name $size +boot ) + fripost_mkfs vfat $part_efi -F 32 + else + fripost_mkpart $d $name $size + fi + else + size=8M + name=bios_grub + if [ $n -eq 1 ]; then + fripost_mkpart $d $name $size +bios_grub + else + fripost_mkpart $d $name $size + fi + fi done -# Wipe the disk -fripost_wipe $device - db_get fripost/encrypt encrypt=$RET -# Create a disk label -/sbin/parted -s $device mklabel gpt -log "Created disklabel GPT for device $device" - -# Create a EFI partition if needed; otherwise, create a partition needed -# to put GRUB on GPT disklabels. -if [ -d /proc/efi -o -d /sys/firmware/efi ]; then - anna-install dosfstools-udeb - part_efi=$( fripost_mkpart $device efi 256M +boot ) - fripost_mkfs vfat $part_efi -F 32 -else - fripost_mkpart $device bios_grub 8M +bios_grub -fi -db_set grub-installer/bootdev $device + +# Install GRUB on the first device in case of an array +db_set grub-installer/bootdev "${device%% *}" db_fset grub-installer/bootdev seen true +part_boot= +part_system= # Create boot and system partitions -part_boot=$( fripost_mkpart $device boot 64M ) -part_system=$( fripost_mkpart $device system 100% ) -/sbin/parted -s $device align-check opt ${part_system#$device} \ - || fatal "$part_system is not aligned" +for d in $device; do + pb=$( fripost_mkpart $d boot 64M ) + ps=$( fripost_mkpart $d system 100% ) + part_boot="${part_boot:+$part_boot }$pb" + part_system="${part_system:+$part_system }$ps" + /sbin/parted -s $d align-check opt ${ps#$d} \ + || fatal "$ps is not aligned" +done + +# Create an array on top of that +if [ ${raidLevel:-} -a ${raidActiveDev:-} ]; then + [ -d /dev/md ] || mkdir /dev/md + /sbin/modprobe -v md_mod + [ -e /proc/mdstat ] || fail "/proc/mdstat missing" + + log "Creating RAID device /dev/md/boot with $part_boot" + mdadm --create /dev/md/boot \ + -f -R -l raid$raidLevel -n $raidActiveDev \ + $part_boot + part_boot=/dev/md/boot + wait_for_device $part_boot + + log "Creating RAID device /dev/md/system with $part_system" + mdadm --create /dev/md/system \ + -f -R -l raid$raidLevel -n $raidActiveDev \ + $part_system + part_system=/dev/md/system + wait_for_device $part_system + + # They were only meant to preserve alignment accross physical + # devices. + log "Remove dummy partitions" + for d in ${device#* }; do + # efi and bios_grub are only installed on the first disk + fripost_rmpart $d efi || true + fripost_rmpart $d bios_grub || true + done + + # Note that we're assembling the array *before* encryption rather + # than the otherway around. dm_crypt being now multi-threaded, the + # order shouldn't impact performances (and that order is + # significantly simpler to configure). +fi + if [ $encrypt = true ]; then diff --git a/src/fripost-partman-udeb/base.sh b/src/fripost-partman-udeb/base.sh index b6770f8..976cfb6 100644 --- a/src/fripost-partman-udeb/base.sh +++ b/src/fripost-partman-udeb/base.sh @@ -586,3 +586,19 @@ getIPv4() { $ip -4 address show dev "$if" scope global \ | sed -nr '/^\s+inet\s([[:xdigit:].:]{3,39}).*/ {s//\1/p;q}' } + + + +############################################################################## +# Remove a partition from a device +# +# Usage: fripost_rmpart device partition + +fripost_rmpart () { + local device="$1" part="$2" + n=$( /sbin/parted -sm "$device" p + | sed -nr "/^[0-9].*:$part:[^:]*;$/ s/:.*//p" ) + [ "$n" ] || return + log "Removing partition $n ($part) from $device" + /sbin/parted -sm "$device" rm "$n" +} -- cgit v1.2.3