diff options
author | Dieter Plaetinck <dieter@plaetinck.be> | 2009-07-27 21:58:53 +0200 |
---|---|---|
committer | Dieter Plaetinck <dieter@plaetinck.be> | 2009-07-27 21:58:53 +0200 |
commit | 1d167075bcae974d98024e6457d3a6e881114976 (patch) | |
tree | 768bf0b585070d9d09865f3ee0a0660dcc959da5 /src/core/libs | |
parent | 2c1c32e721cd98d3c931226242eaec1a3af8268e (diff) | |
parent | 4754e1f0f956e0227ad0c9c280e303e6d314fac8 (diff) |
merge in Gerhards grub refactorings
Diffstat (limited to 'src/core/libs')
-rw-r--r-- | src/core/libs/lib-blockdevices-filesystems.sh | 43 | ||||
-rw-r--r-- | src/core/libs/lib-ui-interactive.sh | 279 |
2 files changed, 257 insertions, 65 deletions
diff --git a/src/core/libs/lib-blockdevices-filesystems.sh b/src/core/libs/lib-blockdevices-filesystems.sh index fa31095..a4bc534 100644 --- a/src/core/libs/lib-blockdevices-filesystems.sh +++ b/src/core/libs/lib-blockdevices-filesystems.sh @@ -827,3 +827,46 @@ get_blockdevice_size () [ $unit = GiB ] && BLOCKDEVICE_SIZE=$((bytes/2**30)) [ $unit = GB ] && BLOCKDEVICE_SIZE=$((bytes/10**9)) } + + +# $1 blockdevice (ex: /dev/md0 or /dev/sda1) +# return true when blockdevice is an md raid, otherwise return a unset value +mdraid_is-raid () +{ + local israid + if [ -z $1 ]; then + # Don't call mdadm on empty blockdevice parameter! + israid="" + elif [ "$(mdadm --query $1 | cut -d':' -f2)" == " is not an md array" ]; then + israid="" + else + israid=true + fi + echo $israid +} + +# $1 md raid blockdevice (ex: /dev/md0) +# return the array member device which is slave 0 in the given array +# ex: /dev/md0 is an array with /dev/sda1, /dev/sdb1, +# so we would return /dev/sda1 as slave 0 +# +# This procedure is used to determine the grub value for root, ex: (hd0,0) +mdraid_slave0 () +{ + echo "/dev/"$(ls -ldgGQ /sys/class/block/$(basename $1)/md/rd0 | cut -d'"' -f4 | cut -d'-' -f2) +} + +# $1 md raid blockdevice (ex: /dev/md0) +# return a list of array members from given md array +# ex: /dev/md0 has slaves: "/dev/sda1 /dev/sdb2 /dev/sdc2" +mdraid_all-slaves () +{ + local slave= + local slaves= + for slave in $(ls /sys/class/block/$(basename $1)/slaves/); do + slaves=$slaves"/dev/"$slave" " + done + echo $slaves +} + + diff --git a/src/core/libs/lib-ui-interactive.sh b/src/core/libs/lib-ui-interactive.sh index de4681e..f765d59 100644 --- a/src/core/libs/lib-ui-interactive.sh +++ b/src/core/libs/lib-ui-interactive.sh @@ -851,33 +851,207 @@ interactive_install_bootloader () { bl=`tr '[:upper:]' '[:lower:]' <<< "$ANSWER_OPTION"` [ "$bl" != grub ] && return 0 - interactive_install_grub + GRUB_OK=0 + interactive_grub } -interactive_install_grub() { +interactive_grub() { get_grub_map local grubmenu="$var_TARGET_DIR/boot/grub/menu.lst" [ ! -f $grubmenu ] && show_warning "No grub?" "Error: Couldn't find $grubmenu. Is GRUB installed?" && return 1 + debug FS "starting interactive_grub" # try to auto-configure GRUB... debug 'UI-INTERACTIVE' "install_grub \$PART_ROOT $PART_ROOT \$GRUB_OK $GRUB_OK" - if get_device_with_mount '/' && [ "$GRUB_OK" != '1' ] ; then - GRUB_OK=0 - PART_ROOT=$ANSWER_DEVICE - grubdev=$(mapdev $PART_ROOT) - local _rootpart="${PART_ROOT}" - local _uuid="$(getuuid ${PART_ROOT})" - # attempt to use a UUID if the root device has one - if [ -n "${_uuid}" ]; then - _rootpart="/dev/disk/by-uuid/${_uuid}" - fi - # look for a separately-mounted /boot partition + if get_device_with_mount '/' && [ "$GRUB_OK" != '1' ] ; then + GRUB_OK=0 + PART_ROOT=$ANSWER_DEVICE + # look for a separately-mounted /boot partition + # This could be used better, maybe we use a better variable name cause + # we use this later in many things in workflow. + # Currently we have bootdev as a device if we have a seperate /boot or empty + # if no seperate /boot. Where our /boot realy lives is important later + # to build the grub: root (hdx,y) part. + # So maybe we set a flag variable like: sepboot=true|false and set bootdev to either + # the partition with seperate /boot or to $PART_ROOT. + # So that bootdev is always our real partition with /boot.... bootdev=$(mount | grep $var_TARGET_DIR/boot | cut -d' ' -f 1) - if [ "$grubdev" != "" -o "$bootdev" != "" ]; then - subdir= - [ -n "$bootdev" ] && grubdev=$(mapdev $bootdev) || subdir="/boot" + # check if bootdev or PART_ROOT is on a md raid array + # This dialog is only shown when we detect / or /boot on a raid device. + if [ -n "$(mdraid_is-raid $bootdev)" -o -n "$(mdraid_is-raid $PART_ROOT)" ]; then + ask_yesno "Do you have your system installed on software raid?\nAnswer 'YES' to install grub to another hard disk." no + if [ $? -eq 0 ]; then + onraid=true + debug FS "onraid is selected" + fi + fi + # Create and edit the grub menu.lst + interactive_grub_menulst + + DEVS=$(finddisks 1 _) + DEVS="$DEVS $(findpartitions 1 _)" + if [ "$DEVS" = "" ]; then + notify "No hard drives were found" + return 1 + fi + # copy initial grub files into installed system + cp -a $var_TARGET_DIR/usr/lib/grub/i386-pc/* $var_TARGET_DIR/boot/grub/ + sync + # freeze xfs filesystems to enable grub installation on xfs filesystems + for xfsdev in $(blkid -t TYPE=xfs -o device); do + mnt=$(mount | grep $xfsdev | cut -d' ' -f 3) + if [ $mnt = "$var_TARGET_DIR/boot" -o $mnt = "$var_TARGET_DIR/" ]; then + /usr/sbin/xfs_freeze -f $mnt > /dev/null 2>&1 + fi + done + + if [ ! $onraid ]; then + # Set boot partition to the device where our /boot lives. + [ -z $bootdev ] && bootpart=$PART_ROOT || bootpart=$bootdev + ask_option no "Boot device selection" "Select the boot device where the GRUB bootloader will be installed (usually the MBR and not a partition)." required $DEVS || return 1 + bootdev=$ANSWER_OPTION + boothd=$(echo $bootdev | cut -c -8) + interactive_grub_install $bootpart $bootdev $boothd + if [ $? -eq 0 ]; then + GRUB_OK=1 + fi + else + # Raid special + # The bootpart and bootdev should not be changed when setup grub on all raid array members. + # Instead the device is mapped via grub parameter device + # So a grub setup on MBR sda/sdb with /boot on sda1/sdb1 should always be done like: + # device (hd0) /dev/sd(a|b) + # root (hd0,0) + # setup (hd0) + + # get md device either if we use separate /boot or not. + [ -z $bootdev ] && local md=$PART_ROOT || local md=$bootdev + + local ask_str="By default grub bootloader will get installed in MBR of each harddisks from your BOOT array "$md". Otherwise selct No." + ask_yesno "$ask_str" yes + if [ $? -eq 0 ]; then + slaves=$(mdraid_all-slaves $md) + for slave in $slaves; do + boothd=$(echo $slave | cut -c -8) + bootpart=$(mdraid_slave0 $md) + bootdev=$(echo $bootpart | cut -c -8) + interactive_grub_install $bootpart $bootdev $boothd + if [ $? -eq 0 ]; then + GRUB_OK=1 + fi + done + else + # This part needs more attention... User could select here only + # a other blockdevice to install grub into... But our grub rootdevice + # is not selectable, cause it is determined either from PART_ROOT or + # bootdev. + # Maybe better we leave the user alone and poke him to use a grub + # shell if he want do something unusefull and not install grub in + # aech MBR of affected HD in raid array.... + USERHAPPY=0 + while [ "$USERHAPPY" = 0 ] + do + ask_option no "Boot device selection" "Select the boot device where the GRUB bootloader will be installed." required $DEVS DONE _ + [ $? -gt 0 ] && USERHAPPY=1 && break + [ "$ANSWER_OPTION" == DONE ] && USERHAPPY=1 && break + bootdev=$ANSWER_OPTION + boothd=$(echo $bootdev | cut -c -8) + bootpart=$(mdraid_slave0 $md) + bootdev=$(echo $bootpart | cut -c -8) + interactive_grub_install $bootpart $bootdev $boothd + if [ $? -eq 0 ]; then + GRUB_OK=1 + fi + done + fi - # keep the file from being completely bogus + if [ "$bootpart" = "" ]; then + if [ "$PART_ROOT" = "" ]; then + ask_string "Enter the full path to your root device" "/dev/sda3" || return 1 + bootpart=$ANSWER_STRING + else + bootpart=$PART_ROOT + fi + boothd=$(echo $bootpart | cut -c -8) + interactive_grub_install $bootpart $bootdev $boothd + if [ $? -eq 0 ]; then + GRUB_OK=1 + fi + fi + fi + # unfreeze xfs filesystems + for xfsdev in $(blkid -t TYPE=xfs -o device); do + mnt=$(mount | grep $xfsdev | cut -d' ' -f 3) + if [ $mnt = "$var_TARGET_DIR/boot" -o $mnt = "$var_TARGET_DIR/" ]; then + /usr/sbin/xfs_freeze -u $mnt > /dev/null 2>&1 + fi + done + + if [ "$GRUB_OK" == "1" ]; then + notify "GRUB was successfully installed." + else + notify "GRUB was NOT successfully installed." + return 1 + fi + return 0 + fi +} + +interactive_grub_menulst() { + get_device_with_mount '/' || return 1 + local _rootpart=$ANSWER_DEVICE + local _uuid="$(getuuid ${_rootpart})" + # attempt to use a UUID if the root device has one + if [ -n "${_uuid}" ]; then + _rootpart="/dev/disk/by-uuid/${_uuid}" + fi + + # Determine what is the device that acts as grub's root + # This is the blockdevice where /boot lives, normally a seperate partition. + # + # Special handling: on md raid arrays + # md raid could not work directly with grub. To get grub's root device we + # parse the slave 0 in the md array to get a real blockdevice (/dev/sdXY) + # + # We get at last in grubdev the blockdevice in grub-legacy notation (ex: (hd0,0) + # + # We do may things double here and in interactive_grub_install + # Better way would be to determine/ask neccassary things once and then + # fill (and present) menu.lst to user. If user mean there is something + # wrong with menu.lst settings (wrong boot device or wrong root=/device) + # he better should re-run the interactive grub install and select correct + # settings. + debug FS "Grub _rootpart: ${_rootpart}" + debug FS "Grub bootdev: "$bootdev + # No seperate /boot partition + if [ -z $bootdev ]; then + # Special handling on md raid + if [ $onraid ]; then + grubdev=$(mapdev $(mdraid_slave0 ${_rootpart})) + debug FS "onraid no sep boot slave0: "$(mdraid_slave0 ${_rootpart}) + debug FS "onraid no sep boot grubdev: "$grubdev + else + # No raid + grubdev=$(mapdev ${_rootpart}) + debug FS "no sep boot grubdev: "$grubdev + fi + # Without seperate /boot partiton we have to specify this path + subdir="/boot" + # with seperate /boot partition + else + # Special handling on md raid + if [ $onraid ]; then + grubdev=$(mapdev $(mdraid_slave0 $bootdev)) + debug FS "onraid with sep boot slave0: "$(mdraid_slave0 $bootdev) + debug FS "onraid with sep boot grubdev: "$grubdev + else + # No raid + grubdev=$(mapdev $bootdev) + debug FS "onraid with sep boot grubdev: "$grubdev + fi + fi + # Now that we have our grub-legacy root device (grubdev). + # keep the file from being completely bogus if [ "$grubdev" = "DEVICE NOT FOUND" ]; then notify "Your root boot device could not be autodetected by setup. Ensure you adjust the 'root (hd0,0)' line in your GRUB config accordingly." grubdev="(hd0,0)" @@ -933,8 +1107,6 @@ initrd $subdir/kernel26-fallback.img #makeactive #chainloader +1 EOF - fi - fi helptext= grep -q '^/dev/mapper' $TMP_FSTAB && helptext=" /dev/mapper/ users: Pay attention to the kernel line!" @@ -944,71 +1116,48 @@ EOF interactive_get_editor || return 1 fi $EDITOR $grubmenu +} - DEVS=$(finddisks 1 _) - DEVS="$DEVS $(findpartitions 1 _)" - if [ "$DEVS" = "" ]; then - notify "No hard drives were found" - return 1 - fi - ask_option no "Boot device selection" "Select the boot device where the GRUB bootloader will be installed (usually the MBR and not a partition)." required $DEVS || return 1 - ROOTDEV=$ANSWER_OPTION - infofy "Installing the GRUB bootloader..." - cp -a $var_TARGET_DIR/usr/lib/grub/i386-pc/* $var_TARGET_DIR/boot/grub/ - sync - # freeze xfs filesystems to enable grub installation on xfs filesystems - for xfsdev in $(blkid -t TYPE=xfs -o device); do - mnt=$(mount | grep $xfsdev | cut -d' ' -f 3) - if [ $mnt = "$var_TARGET_DIR/boot" -o $mnt = "$var_TARGET_DIR/" ]; then - /usr/sbin/xfs_freeze -f $mnt > /dev/null 2>&1 - fi - done - # look for a separately-mounted /boot partition - bootpart=$(mount | grep $var_TARGET_DIR/boot | cut -d' ' -f 1) - if [ "$bootpart" = "" ]; then - if [ "$PART_ROOT" = "" ]; then - ask_string "Enter the full path to your root device" "/dev/sda3" || return 1 - bootpart=$ANSWER_STRING - else - bootpart=$PART_ROOT - fi - fi - ask_yesno "Do you have your system installed on software raid?\nAnswer 'YES' to install grub to another hard disk." no - if [ $? -eq 0 ]; then - ask_option no "Boot partition device selection" "Please select the boot partition device, this cannot be autodetected!\nPlease redo grub installation for all partitions you need it!" required $DEVS || return 1 - bootpart=$ANSWER_OPTION - fi - bootpart=$(mapdev $bootpart) - bootdev=$(mapdev $ROOTDEV) +interactive_grub_install () { + debug FS "interactive_grub_install called. P1 = $1, P2 = $2, P3 = $3" + # $1 = bootpart + # $2 = bootdev + # $3 = boothd + # To install grub we have to know: + # The bootpart - This is were /boot could be found + # The bootdev - This is were grub gets installed, usally the MBR + # The boothd - Only on md raid setups this differs from bootdev + # These values get parsed either from values we have already or from + # user input. Later they will converted to grub-legacy notation. + + # Convert to grub-legacy notation + local bootpart=$(mapdev $1) if [ "$bootpart" = "" ]; then notify "Error: Missing/Invalid root device: $bootpart" return 1 fi + local bootdev=$(mapdev $2) if [ "$bootpart" = "DEVICE NOT FOUND" -o "$bootdev" = "DEVICE NOT FOUND" ]; then notify "GRUB root and setup devices could not be auto-located. You will need to manually run the GRUB shell to install a bootloader." return 1 fi + local boothd=$3 + debug FS "bootpart: $bootpart" + debug FS "bootdev: $bootdev" + debug FS "boothd: $boothd" + #return 0 + $var_TARGET_DIR/sbin/grub --no-floppy --batch >/tmp/grub.log 2>&1 <<EOF +device $bootdev $boothd root $bootpart setup $bootdev quit EOF cat /tmp/grub.log >$LOG - # unfreeze xfs filesystems - for xfsdev in $(blkid -t TYPE=xfs -o device); do - mnt=$(mount | grep $xfsdev | cut -d' ' -f 3) - if [ $mnt = "$var_TARGET_DIR/boot" -o $mnt = "$var_TARGET_DIR/" ]; then - /usr/sbin/xfs_freeze -u $mnt > /dev/null 2>&1 - fi - done - if grep "Error [0-9]*: " /tmp/grub.log >/dev/null; then notify "Error installing GRUB. (see $LOG for output)" return 1 fi - notify "GRUB was successfully installed." - GRUB_OK=1 - return 0 } |