aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2014-01-23 07:40:58 +0100
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 04:27:58 +0200
commit16e2c85922848adb1c21a46a6cc23846ef94b951 (patch)
tree740413af17c446acf4478ed7e176caa881bdcf9e
parentba40cbca9650e1ddaa8357c21b5de31cc376c481 (diff)
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 :-)
-rwxr-xr-xinclude/partition.sh121
-rw-r--r--src/fripost-partman-udeb/base.sh16
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"
+}