summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorDieter Plaetinck <dieter@plaetinck.be>2009-07-27 21:58:53 +0200
committerDieter Plaetinck <dieter@plaetinck.be>2009-07-27 21:58:53 +0200
commit1d167075bcae974d98024e6457d3a6e881114976 (patch)
tree768bf0b585070d9d09865f3ee0a0660dcc959da5 /src/core
parent2c1c32e721cd98d3c931226242eaec1a3af8268e (diff)
parent4754e1f0f956e0227ad0c9c280e303e6d314fac8 (diff)
merge in Gerhards grub refactorings
Diffstat (limited to 'src/core')
-rw-r--r--src/core/libs/lib-blockdevices-filesystems.sh43
-rw-r--r--src/core/libs/lib-ui-interactive.sh279
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
}