From 84193cef8b9a13cb39cb35abe80914640dbe3982 Mon Sep 17 00:00:00 2001 From: Dieter Plaetinck Date: Sun, 26 Jul 2009 17:59:02 +0200 Subject: useful get_anchestors_mount function which gives you the blockdevice for a filesystem + all its ancestors. also: automatically generate grub menu.lst kernel line for dm-crypt, lvm etc setups --- src/core/libs/lib-blockdevices-filesystems.sh | 38 +++++++++++++++++++++++++++ src/core/libs/lib-ui-interactive.sh | 34 ++++++++++++++++++------ 2 files changed, 64 insertions(+), 8 deletions(-) (limited to 'src/core/libs') diff --git a/src/core/libs/lib-blockdevices-filesystems.sh b/src/core/libs/lib-blockdevices-filesystems.sh index abf728f..88c4675 100644 --- a/src/core/libs/lib-blockdevices-filesystems.sh +++ b/src/core/libs/lib-blockdevices-filesystems.sh @@ -85,6 +85,44 @@ get_device_with_mount () { [ -n "$ANSWER_DEVICE" ] # set correct exit code } +# gives you a newline separated list of the blockdevice that hosts a certain filesystem, and below it, all underlying blockdevices supporting it, with also the blockdevice type. +# example: +# get_anchestors_mount ';/;' (suppose '/' is a filesystem on top of lvm on top of dm_crypt, you will get something like): +# /dev/mapper/cryptpool-cryptroot lvm-lv +# /dev/mapper/cryptpool lvm-vg +# /dev/mapper/sda2crypt+ lvm-pv +# /dev/mapper/sda2crypt dm_crypt +# /dev/sda2 raw +# $1 a "recognizer": a string that will match the filesystem section uniquely (using egrep), such as ';;' or other specific attributes of the hosted filesystem(s) +get_anchestors_mount () { + local buffer= + read block type leftovers <<< `egrep "$1" $TMP_BLOCKDEVICES 2>/dev/null` + [ -z "$type" ] && return 1 + buffer="$block $type" + if [ $type != 'raw' ] + then + if [ $type == lvm-lv ] + then + lv=`echo $block | sed 's/.*-//'` # /dev/mapper/cryptpool-cryptroot -> cryptroot. TODO: this may give unexpected behavior of LV has a '-' in its name + recognizer="lvm-lv;(yes|no);no_mountpoint;[^;]{1,};[^;]{1,};$lv;[^;]{1,}" + elif [ $type == lvm-vg ] + then + recognizer="lvm-vg;(yes|no);no_mountpoint;[^;]{1,};[^;]{1,};`basename $block`;[^;]{1,}" + elif [ $type == lvm-pv ] + then + # here we cheat a bit: we cannot match the FS section because usually we don't give a PV recognizable attributes, but since we name a PV as blockdevice + '+' we can match the blockdevice + recognizer="^${block/+/} .* lvm-pv;" + elif [ $type == dm_crypt ] + then + recognizer="dm_crypt;(yes|no);no_mountpoint;[^;]{1,};[^;]{1,};`basename $block`;[^;]{1,}" + fi + get_anchestors_mount "$recognizer" && buffer="$buffer +$ANSWER_DEVICES" + fi + ANSWER_DEVICES=$buffer + [ -n "$ANSWER_DEVICES" ] +} + # taken from setup script, modified for separator control # $1 set to 1 to echo a newline after device instead of a space (optional) diff --git a/src/core/libs/lib-ui-interactive.sh b/src/core/libs/lib-ui-interactive.sh index a7681e3..0ab2785 100644 --- a/src/core/libs/lib-ui-interactive.sh +++ b/src/core/libs/lib-ui-interactive.sh @@ -864,18 +864,42 @@ interactive_install_grub() { fi # remove default entries by truncating file at our little tag (#-*) sed -i -e '/#-\*/q' $grubmenu + + # handle dmraid/mdadm,lvm,dm_crypt etc. replace entries where needed automatically + # '/ on raw' and '/ on lvm on raw' (default) + kernel="kernel $subdir/vmlinuz26 root=${_rootpart} ro" + if get_anchestors_mount ';/;' + then + if echo "$ANSWERS_DEVICES" | sed -n '1p' | grep -q 'dm_crypt$' && echo "$ANSWERS_DEVICES" | sed -n '2p' | grep -q 'raw$' + then + # '/ on dm_crypt on raw' + raw_device=`echo "$ANSWERS_DEVICES" | sed -n '2p' | cut -d ' ' -f1` + kernel="kernel $subdir/vmlinuz26 root=$raw_device ro" + elif echo "$ANSWERS_DEVICES" | sed -n '1p' | grep -q 'lvm-lv$' && echo "$ANSWERS_DEVICES" | sed -n '4p' | grep -q 'dm_crypt$' && echo "$ANSWERS_DEVICES" | sed -n '5p' | grep -q 'raw$' + # / on lvm on dm_crypt on raw + lv_device=`echo "$ANSWERS_DEVICES" | sed -n '1p' | cut -d ' ' -f1` + vg_device=`echo "$ANSWERS_DEVICES" | sed -n '2p' | cut -d ' ' -f1` + crypt_device=`echo "$ANSWERS_DEVICES" | sed -n '4p' | cut -d ' ' -f1` + kernel="kernel $subdir/vmlinuz26 root=$lv_device cryptdevice=$crypt_device:`basename $vgdevice` ro" + elif echo "$ANSWERS_DEVICES" | sed -n '1p' | grep -q 'dm_crypt$' && echo "$ANSWERS_DEVICES" | sed -n '2p' | grep -q 'lvm-lv$' && echo "$ANSWERS_DEVICES" | sed -n '5p' | grep -q 'raw$' + # / on dm_crypt on lvm on raw + crypt_device=`echo "$ANSWERS_DEVICES" | sed -n '1p' | cut -d ' ' -f1` + lv_device=`echo "$ANSWERS_DEVICES" | sed -n '2p' | cut -d ' ' -f1` + kernel=" kernel $subdir/vmlinuz26 root=$crypt_device cryptdevice=$lv_device:root ro" + fi + fi cat >>$grubmenu < no substitution needed: specify physical device that hosts the encrypted / - # / on lvm -> root=/dev/mapper/- resume=/dev/mapper/- - # / on lvm on dm_crypt -> root=/dev/mapper/- cryptdevice=/dev/: - # / on dm_crypt on lvm -> specify the lvm device that hosts the encrypted / - # ... notify "Before installing GRUB, you must review the configuration file. You will now be put into the editor. After you save your changes and exit the editor, you can install GRUB." if [ -z "$EDITOR" ] -- cgit v1.2.3-54-g00ecf