diff -Naur grub-0.96.orig/util/grub-install.in grub-0.96/util/grub-install.in --- grub-0.96.orig/util/grub-install.in 2004-07-24 20:57:31.000000000 +0200 +++ grub-0.96/util/grub-install.in 2005-02-06 13:18:22.304449096 +0100 @@ -36,6 +36,7 @@ rootdir= grub_prefix=/boot/grub +install_drives= install_device= no_floppy= force_lba= @@ -211,6 +212,43 @@ echo "$tmp_fname" } +# Usage: is_raid1_device devicename +# Returns 0 if devicename is a raid1 md device, 1 if it is not. +is_raid1_device () { + case "$host_os" in + linux*) + level=`mdadm --query --detail $1 2>/dev/null | \ + awk '/Raid Level :/ {print $4}'` + if [ "$level" = "raid1" ]; then + return 0 + fi + ;; + esac + return 1 +} + +# Usage: find_real_devs device +# Returns space separated list of devices for linux if device is +# a raid1 device. In all other cases, the provided value is returned. +find_real_devs () { + source_device=$1 + case "$host_os" in + linux*) + if is_raid1_device $source_device ; then + list="" + for device in `mdadm --query --detail "${source_device}" | \ + awk '/\/dev\/[^(md)]/ {print $7}'` ; do + list="$list $device" + done + echo $list + return 0 + fi + ;; + esac + echo $source_device + return 0 +} + # Usage: find_device file # Find block device on which the file resides. find_device () { @@ -223,11 +261,35 @@ exit 1 fi - tmp_fname=`resolve_symlink $tmp_fname` + tmp_fname=`resolve_symlink $tmp_fname` echo "$tmp_fname" } + +dump_boot_block () { + sync + $grub_shell --batch $no_floppy --device-map=$device_map <$log_file +dump ${root_drive}${tmp} ${img_file} +quit +EOF +} + + +install_boot_block () { + # Before all invocations of the grub shell, call sync to make sure + # the raw device is in sync with any bufferring in filesystems. + sync + + # Now perform the installation. + $grub_shell --batch $no_floppy --device-map=$device_map <>$log_file +root $1 +setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $2 +quit +EOF +} + + # Check the arguments. for option in "$@"; do case "$option" in @@ -336,6 +398,10 @@ # Create a safe temporary file. test -n "$mklog" && log_file=`$mklog` + # Before all invocations of the grub shell, call sync to make sure + # the raw device is in sync with any bufferring in filesystems. + sync + $grub_shell --batch $no_floppy --device-map=$device_map <$log_file quit EOF @@ -359,23 +425,31 @@ case "$install_device" in /dev/*) install_device=`resolve_symlink "$install_device"` - install_drive=`convert "$install_device"` - # I don't know why, but some shells wouldn't die if exit is - # called in a function. - if test "x$install_drive" = x; then + for install_drive in `find_real_devs $install_device` ; do + install_drive=`convert $install_drive` + if [ "x$install_drive" = "x" ]; then + exit 1 + fi + install_drives="${install_drives} ${install_drive}" + done + unset install_drive + + if test "x$install_drives" = x ; then exit 1 fi ;; \([hf]d[0-9]*\)) - install_drive="$install_device" ;; + install_drives="$install_device" ;; [hf]d[0-9]*) # The GRUB format with no parenthesis. - install_drive="($install_device)" ;; + install_drives="($install_device)" ;; *) echo "Format of install_device not recognized." 1>&2 usage exit 1 ;; esac +unset install_device + # Get the root drive. root_device=`find_device ${rootdir}` bootdir_device=`find_device ${bootdir}` @@ -387,14 +461,7 @@ grub_prefix="/grub" fi -# Convert the root device to a GRUB drive. -root_drive=`convert "$root_device"` -if test "x$root_drive" = x; then - exit 1 -fi - -# Check if the root directory exists in the same device as the grub -# directory. +# Check if the root directory exists in the same device as the grub directory. grubdir_device=`find_device ${grubdir}` if test "x$grubdir_device" != "x$root_device"; then @@ -422,25 +489,33 @@ test -n "$mkimg" && img_file=`$mkimg` test -n "$mklog" && log_file=`$mklog` +# There's not a real root device, so just pick the first +if is_raid1_device $root_device ; then + root_device=`find_real_devs $root_device | awk '{print $1}'` +fi + +# Convert the root deviceto a GRUB drive. +root_drive=`convert "$root_device"` +if [ "x$root_drive" = x ]; then + exit 1 +fi + for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do count=5 tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"` while test $count -gt 0; do - $grub_shell --batch $no_floppy --device-map=$device_map <$log_file -dump ${root_drive}${tmp} ${img_file} -quit -EOF - if grep "Error [0-9]*: " $log_file >/dev/null; then - : - elif cmp $file $img_file >/dev/null; then - break - fi - sleep 1 - count=`expr $count - 1` + dump_boot_block $root_drive $img_file + if grep "Error [0-9]*: " $log_file >/dev/null; then + : + elif cmp $file $img_file >/dev/null; then + break + fi + sleep 1 + count=`expr $count - 1` done if test $count -eq 0; then - echo "The file $file not read correctly." 1>&2 - exit 1 + echo "The file $file not read correctly." 1>&2 + exit 1 fi done @@ -450,17 +525,22 @@ # Create a safe temporary file. test -n "$mklog" && log_file=`$mklog` -# Now perform the installation. -$grub_shell --batch $no_floppy --device-map=$device_map <$log_file -root $root_drive -setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $install_drive -quit -EOF +for install_drive in $install_drives; do + # Convert the root deviceto a GRUB drive. + root_drive=`convert "$root_device"` + if [ "x$root_drive" = x ]; then + exit 1 + fi + install_boot_block $root_drive $install_drive +done -if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then +if grep "Error [0-9]*: " $log_file >/dev/null ; then cat $log_file 1>&2 exit 1 fi +if test $debug = yes; then + cat $log_file 1>&2 +fi rm -f $log_file