#! /bin/sh # export DEBCONF_DEBUG=5 set -e . /usr/share/debconf/confmodule #set -x if [ "$1" ]; then ROOT="$1" chroot=chroot else ROOT= chroot= fi . /usr/share/grub-installer/functions.sh . /usr/share/grub-installer/otheros.sh newline=" " db_capb backup ARCH="$(archdetect)" info "architecture: $ARCH" SUBARCH="${ARCH#*/}" # XXX cjwatson 2019-03-25: This is all far too complicated and fragile, and # should be replaced with in-target or similar. # Ensure proc is mounted in all the $chroot calls; # needed for RAID+LVM for example initial_proc_contents="$(ls $ROOT/proc)" if [ -z "$initial_proc_contents" ]; then info "Mounting /proc into $ROOT" if [ "$(udpkg --print-os)" = "kfreebsd" ]; then mount -t linprocfs proc $ROOT/proc on_exit "umount '$ROOT/proc'" elif [ "$(udpkg --print-os)" = "hurd" ]; then mount -t proc none $ROOT/proc on_exit "umount '$ROOT/proc'" else mountvirtfs proc $ROOT/proc fi fi # On Linux, we need /run in the chroot to work around # https://bugs.debian.org/918590. if [ "$(udpkg --print-os)" = "linux" ] && [ ! -d "$ROOT/run/udev" ]; then info "Bind mounting /run into $ROOT" mount --bind /run $ROOT/run on_exit "umount '$ROOT/run'" fi get_serial_console() { # Get the last 'console=' entry (if none, the whole string is returned) local defconsole="$(sed -e 's/.*\(console=[^ ]*\).*/\1/' /proc/cmdline)" if echo "$defconsole" | grep -qe 'console=\(ttyS\|com\)'; then echo "$defconsole" fi } grub_serial_console() { #$1=output of get_serial_console local serconsole=${1##console=ttyS} serconsole=${serconsole##console=com} local unit=${serconsole%%,*} local options="" if echo $serconsole | grep -q ","; then options=${serconsole##*,} fi local speed=$(echo "$options" | sed -e 's/^\([0-9]*\).*$/\1/') # Take optional 1st (parity) and 2nd (word) characters after speed options=${options##${speed}} local parity=$(echo $options | sed 's/^\(.\?\).*$/\1/') local word=$(echo $options | sed 's/^.\?\(.\?\).*$/\1/') if [ -z "$speed" ]; then speed="9600" fi case "$parity" in n) parity="--parity=no" ;; e) parity="--parity=even" ;; o) parity="--parity=odd" ;; *) parity="" ;; esac if [ "$word" ]; then word="--word=$word" fi echo serial --unit=$unit --speed=$speed $word $parity --stop=1 } serial="$(get_serial_console)" grub_probe () { if [ "$is_grub_common_installed" != true ]; then apt-install grub-common is_grub_common_installed=true fi $chroot $ROOT grub-probe $@ } # Usage: convert os_device # Convert an OS device to the corresponding GRUB drive convert () { tmp_drive="$(grub_probe -d -t drive "$1")" || exit $? if [ "$partition_offset" != 0 ]; then tmp_part="$(echo "$tmp_drive" | sed 's%.*,\([0-9]*\)).*%\1%')" if [ "$tmp_part" ] && [ "$tmp_part" != "$tmp_drive" ]; then tmp_drive="$(echo "$tmp_drive" | sed "s%\(.*,\)[0-9]*\().*\)%\1`expr $tmp_part - $partition_offset`\2%")" fi fi echo "$tmp_drive" } # Convert a linux non-devfs disk device name into the hurd's syntax hurd_convert () { dr_type=$(expr "$1" : '.*\([hs]d\)[a-h][0-9]*') dr_letter=$(expr "$1" : '.*d\([a-h]\)[0-9]*') dr_part=$(expr "$1" : '.*d[a-h]\([0-9]*\)') case "$dr_letter" in a) dr_num=0 ;; b) dr_num=1 ;; c) dr_num=2 ;; d) dr_num=3 ;; e) dr_num=4 ;; f) dr_num=5 ;; g) dr_num=6 ;; h) dr_num=7 ;; esac echo "$dr_type${dr_num}s$dr_part" } # This should probably be rewritten using udevadm or similar. device_to_disk () { echo "$1" | \ sed 's:\(/dev/\(cciss\|ida\|rs\)/c[0-9]d[0-9][0-9]*\|/dev/mmcblk[0-9]\|/dev/nvme[0-9][0-9]*n[0-9][0-9]*\|/dev/\(ad\|ada\|da\|vtbd\|xbd\)[0-9]\+\|/dev/[hs]d[0-9]\+\|/dev/[a-z]\+\).*:\1:' } # Run update-grub in $ROOT update_grub () { local in_target if [ "$ROOT" = /target ]; then in_target='in-target' else in_target="log-output -t grub-installer $chroot $ROOT" fi if ! $in_target $update_grub; then error "Running '$update_grub' failed." 1>&2 db_input critical grub-installer/update-grub-failed || [ $? -eq 30 ] db_go || true db_progress STOP exit 1 fi } findfs () { if ! grub_probe -t device $1; then mount | grep "on $ROOT${1%/} " | tail -n1 | cut -d' ' -f1 fi } findfstype () { case "$(udpkg --print-os)" in hurd) fsysopts "$ROOT$1" | sed 's:^/hurd/\([^ ]*\)fs .*:\1:' ;; *) mount | grep "on $ROOT${1%/} " | tail -n1 | cut -d' ' -f5 ;; esac } # by-id mapping copied from grub-pc.postinst. cached_available_ids= available_ids() { local id path if [ "$cached_available_ids" ]; then echo "$cached_available_ids" return fi [ -d /dev/disk/by-id ] || return cached_available_ids="$( for path in /dev/disk/by-id/*; do [ -e "$path" ] || continue printf '%s %s\n' "$path" "$(readlink -f "$path")" done | sort -k2 -s -u | cut -d' ' -f1 )" echo "$cached_available_ids" } # Returns non-zero and no output if no mapping can be found. device_to_id() { local id for id in $(available_ids); do if [ "$(readlink -f "$id")" = "$(readlink -f "$1")" ]; then echo "$id" return 0 fi done # Fall back to the plain device name if there's no by-id link for it. if [ -e "$1" ]; then echo "$1" return 0 fi return 1 } devices_to_ids() { local device id ids ids= for device; do id="$(device_to_id "$device" || true)" if [ "$id" ]; then ids="${ids:+$ids, }$id" fi done echo "$ids" } rootfs=$(findfs /) bootfs=$(findfs /boot) [ -n "$bootfs" ] || bootfs="$rootfs" bootfstype=$(findfstype /boot) rootfstype="$(findfstype /)" [ -n "$bootfstype" ] || bootfstype=$rootfstype case $ARCH in powerpc/chrp|powerpc/chrp_rs6k|powerpc/chrp_ibm|powerpc/cell) ;; ppc64/chrp|ppc64/chrp_rs6k|ppc64/chrp_ibm|ppc64/cell) ;; powerpc/*|ppc64/*) offs=$(findfs /boot/grub) [ -n "$offs" ] || error "GRUB requires that the OF partition is mounted in /boot/grub" 1>&2 ;; esac # This code to set disc_offered was taken from lilo-installer rootfs_nodevfs=$(mapdevfs $rootfs) bootfs_nodevfs=$(mapdevfs $bootfs) prefix=$(device_to_disk "$bootfs") case $prefix in /dev/md) disc_offered_devfs="$bootfs" ;; /dev/mapper) disc_offered_devfs="$bootfs" ;; /dev/[hsv]d[a-z0-9]|/dev/[hsv]d[a-z0-9][a-z]*|/dev/xvd[a-z]|/dev/cciss/c[0-9]d[0-9]*|/dev/ida/c[0-9]d[0-9]*|/dev/rs/c[0-9]d[0-9]*|/dev/mmcblk[0-9]|/dev/nvme[0-9]*n[0-9]*|/dev/ad[0-9]*|/dev/da[0-9]*) disc_offered_devfs="$prefix" ;; *) disc_offered_devfs=$(echo "$bootfs_nodevfs" | sed "s:\(.*\)/.*:\1/disc:") ;; esac disc_offered=$(mapdevfs "$disc_offered_devfs") # Identify partition table of the disk containing our boot partition bootfslabel=$(partmap $disc_offered || echo unknown) frdev="" # Check if the boot file system is on multipath if type multipath >/dev/null 2>&1; then for frdisk in $(multipath -l 2>/dev/null | \ grep '^mpath[0-9]\+ ' | cut -d ' ' -f 1); do if echo "$disc_offered" | \ grep -q "^/dev/mapper/${frdisk}p[0-9]\+"; then frdev=/dev/mapper/$frdisk frbootpart=${disc_offered#$frdev} frgrubroot=${frbootpart#p} frtype=multipath break fi done if [ "$frdisk" ]; then # Create the device nodes for grub: apt-install dmsetup $chroot $ROOT dmsetup mknodes fi elif type lvdisplay >/dev/null 2>&1 && \ (lvdisplay "$disc_offered" | grep -q 'LV Name' 2>/dev/null || \ [ -e "$(dirname "$disc_offered")/control" ]); then # Don't set frdev/frdisk here, otherwise you'll end up in different # code paths below ... frtype=lvm fi info "Identified partition label for $bootfs: $bootfslabel" experimental_arch () { db_subst grub-installer/grub_not_mature_on_this_platform ARCH $ARCH db_input low grub-installer/grub_not_mature_on_this_platform || [ $? -eq 30 ] db_go || exit 10 db_get grub-installer/grub_not_mature_on_this_platform if [ "$RET" != true ]; then exit 10 fi } case $ARCH in arm64/efi) grub_package="grub-efi-arm64" ;; armhf/efi) grub_package="grub-efi-arm" ;; i386/mac|amd64/mac) # Note: depends on partman-efi to load the efivars module! if [ -d /sys/firmware/efi ]; then # This point can't be reached (yet). See debian/isinstallable. grub_package="grub-efi" else grub_package="grub-pc" fi ;; i386/efi|amd64/efi) if [ -f /var/lib/partman/ignore_uefi ]; then # $SUBARCH != "efi" if partman ignore_uefi flag is set # so this branch should not be reached grub_package="grub-pc" else grub_package="grub-efi" # Override the package choice if we can figure out the # right package to use directly if [ -f /sys/firmware/efi/fw_platform_size ] ; then SIZE=$(cat /sys/firmware/efi/fw_platform_size) if [ $SIZE -eq 64 ] ; then grub_package="grub-efi-amd64" elif [ $SIZE -eq 32 ] ; then grub_package="grub-efi-ia32" fi fi fi ;; i386/*|amd64/*) # Check for a Xen hypervisor without the hvm_callback_vector feature # available to the guest. HVM guests should still use grub-pc. if [ "$(cat /sys/hypervisor/type 2>/dev/null || true)" = xen ] && \ [ -e /sys/hypervisor/properties/features ] && \ [ "$((0x$(cat /sys/hypervisor/properties/features) & (1 << 8)))" = 0 ]; then grub_package="grub-xen" else grub_package="grub-pc" fi ;; ia64/*) grub_package="grub-efi-ia64" ;; loong64/*) grub_package="grub-efi-loong64" ;; powerpc/*|ppc64/*) grub_package="grub-ieee1275" ;; ppc64el/*) grub_package="grub-ieee1275" ;; riscv64/efi) grub_package="grub-efi-riscv64" ;; sparc/*|sparc64/*) grub_package="grub-ieee1275" ;; mipsel/loongson-2f) grub_package="grub-yeeloong" ;; *) grub_package="grub-pc" esac if [ -f /var/lib/partman/ignore_uefi ]; then # propagate partman ignore_uefi flag to the target system so that # os-prober performs legacy BIOS probes instead of EFI probes # when running update-grub in target chroot if [ ! -e $ROOT/var/lib/partman ]; then if mkdir -p $ROOT/var/lib/partman; then on_exit "rmdir '$ROOT/var/lib/partman'" else error "Failed to create directory $ROOT/var/lib/partman" exit 1 fi elif [ ! -d $ROOT/var/lib/partman ]; then error "$ROOT/var/lib/partman exists but is not a directory" exit 1 fi if [ ! -e $ROOT/var/lib/partman/ignore_uefi ]; then if touch $ROOT/var/lib/partman/ignore_uefi; then on_exit "rm '$ROOT/var/lib/partman/ignore_uefi'" else error "Failed to create file $ROOT/var/lib/partman/ignore_uefi" exit 1 fi elif [ ! -f $ROOT/var/lib/partman/ignore_uefi ]; then error "$ROOT/var/lib/partman/ignore_uefi exists but is not a regular file" exit 1 fi fi case "$frtype:$bootfstype:$bootfslabel:$grub_package" in multipath:*:*:*) # Multipath requires GRUB Legacy for now grub_package="grub" ;; *:*:*:grub-yeeloong | lvm:*:*:* | *:*:gpt:* | :ext4:*:grub | *:ufs:*:* | *:zfs:*:* | *:btrfs:*:* | *:*:*:grub-xen) # grub-legacy is not an option in these configurations ;; *:*:*:grub-pc) db_get grub-installer/grub2_instead_of_grub_legacy if [ "$RET" = false ]; then grub_package="grub" fi ;; esac case $ARCH:$grub_package in powerpc/chrp*:grub-ieee1275|ppc64/chrp*:grub-ieee1275|ppc64el/*:grub-ieee1275) # By default, use the first PReP partition found (prep-bootdev). # If available, prefer a PReP partition in the same device (disc_offered). # (the matching works on devices with/without disk-partition separator.) wipe_bootdev="$(/usr/lib/grub-installer/prep-bootdev)" for prep_p in $(/usr/lib/grub-installer/prep-bootdev -l); do if [ "${prep_p%[0-9]*}" = "${disc_offered%[0-9]*}" ]; then wipe_bootdev=$prep_p break fi done unset prep_p if [ -n "$wipe_bootdev" ]; then info "Wiping PReP partition $wipe_bootdev" log-output -t grub-installer dd if=/dev/zero of="$wipe_bootdev" bs=512 count="$(blockdev --getsz "$wipe_bootdev")" else info "WARNING: PReP partition not found." fi ;; esac case $grub_package in grub) grub_version="grub" menu_file="menu.lst" update_grub="update-grub" partition_offset=1 frgrubroot=$(($frgrubroot - 1)) ;; *) grub_version="grub2" menu_file="grub.cfg" update_grub="update-grub" partition_offset=0 ;; esac user_params=$(user-params) || true defopt_params="" kopt_params="" got_quiet="" for u_param in $user_params; do case "$u_param" in quiet) got_quiet=1 defopt_params=${defopt_params:+$defopt_params }$u_param ;; *) kopt_params=${kopt_params:+$kopt_params }$u_param ;; esac done if [ "$grub_version" = grub2 ]; then # Add user parameters to the menu file; some options are only added # to the default entry for a kernel instead of all entries. # We have to duplicate grub2's default for # GRUB_CMDLINE_LINUX_DEFAULT here. if [ -z "$got_quiet" ]; then defopt_params="quiet${defopt_params:+ $defopt_params}" fi # (quoting to deconfuse vim) $chroot $ROOT 'debconf-set-selections' </dev/null | grep -qE '^Boot[0-9A-F]{4}'; then ER_PRIO=low NV_PRIO=low else ER_PRIO=high NV_PRIO=high fi # Should we force a copy of grub-efi to be installed # to the removable media path too? Ask at low # priority, or can also be pre-seeded of course db_input $ER_PRIO grub-installer/force-efi-extra-removable || [ $? -eq 30 ] db_go || exit 10 db_get grub-installer/force-efi-extra-removable if [ "$RET" = true ]; then info "YES on force-efi-extra-removable" $chroot $ROOT 'debconf-set-selections' < /tmp/os-probed || true info "initial os-prober call found the following OSes:" info "$(cat /tmp/os-probed)" # Work out what probed OSes can be booted from grub if [ -s /tmp/os-probed ]; then other_os_list="" OLDIFS="$IFS" IFS="$newline" for os in $(cat /tmp/os-probed); do IFS="$OLDIFS" title=$(echo "$os" | cut -d: -f2) type=$(echo "$os" | cut -d: -f4) case "$type" in chain) : ;; linux) # Check for linux systems that we don't # know how to boot partition=$(echo "$os" | cut -d: -f1) if [ -z "$(linux-boot-prober $partition)" ]; then if [ -n "$unsupported_os_list" ]; then unsupported_os_list="$unsupported_os_list, $title" else unsupported_os_list="$title" fi if [ -n "$other_os_list" ]; then other_os_list="$other_os_list, $title" else other_os_list="$title" fi continue fi ;; hurd) : ;; *) if [ -n "$unsupported_os_list" ]; then unsupported_os_list="$unsupported_os_list, $title" else unsupported_os_list="$title" fi if [ -n "$other_os_list" ]; then other_os_list="$other_os_list, $title" else other_os_list="$title" fi continue ;; esac if [ -n "$supported_os_list" ]; then supported_os_list="$supported_os_list, $title" else supported_os_list="$title" fi IFS="$newline" done IFS="$OLDIFS" info "Supported os list: $supported_os_list" info "Unsupported os list: $unsupported_os_list" info "Complete list: $other_os_list" if [ -n "$unsupported_os_list" ]; then # Unsupported OS, jump straight to manual boot device question. state=2 else q=grub-installer/with_other_os db_subst $q OS_LIST "$supported_os_list" state=1 fi # We have found other OSes - ask the user (at a low priority) # if we should run os-prober at a low priority, with the # default set to yes info "Found other OSes, triggering question about os-prober, default yes" db_subst grub-installer/enable_os_prober_otheros_yes OS_LIST "$other_os_list" db_input low grub-installer/enable_os_prober_otheros_yes || [ $? -eq 30 ] db_go || exit 10 db_get grub-installer/enable_os_prober_otheros_yes if [ "$RET" = true ]; then info "YES on enable_os_prober_otheros_yes" info "Enabling os-prober" $chroot $ROOT 'debconf-set-selections' </dev/null && \ ! grub_probe -t fs -d "$default_bootdev" >/dev/null); then db_fget grub-installer/bootdev seen if [ "$RET" != true ]; then bootfs=$(findfs /boot) [ "$bootfs" ] || bootfs="$(findfs /)" disk=$(device_to_disk "$bootfs") db_set grub-installer/bootdev "$disk" state=2 fi fi ;; powerpc/chrp*:grub-ieee1275|ppc64/chrp*:grub-ieee1275|ppc64el/*:grub-ieee1275) # Hack to pick the right boot device. This should really be done in # grub-install instead, and will need to be done there in order to # support major GRUB upgrades properly, but this will tide us over # for now. bootdev="$wipe_bootdev" state=3 ;; powerpc/powermac_newworld:grub-ieee1275|ppc64/powermac_newworld:grub-ieee1275) bootdev="$(findfs /boot/grub)" state=3 ;; sparc/*:grub-ieee1275|sparc64/*:grub-ieee1275) bootfs=$(findfs /boot) [ "$bootfs" ] || bootfs="$(findfs /)" # see: https://github.com/esnowberg/grub2-sparc/wiki case $SUBARCH in *_gpt) # For GPT disk labels, grub-install uses the device as target disk=$(device_to_disk "$bootfs") db_set grub-installer/bootdev "$disk" ;; *) # For Sun disk labels, grub-install uses the boot partition as target db_set grub-installer/bootdev "$bootfs" ;; esac state=3 ;; *) # No need for install device selection on other platforms. bootdev=dummy state=3 ;; esac db_progress STEP 1 db_progress INFO grub-installer/progress/step_bootdev select_bootdev() { debug "select_bootdev: arg='$1'" local dev_list dev_descr grubdev devices disk_id dev descr local default_choice chosen result result="" default_choice="$1" # /dev/disk/by-id has multiple links for the same physical disk. # Let's trust grub-mkdevicemap to select the most suitable ones # and correctly handle systems with no /dev/disk/by-id. # Use disk id string as a shortcut way to describe it. # FIXME switch to grub-pc's far more elegant disk_descriptions() dev_list= dev_descr= devices="$($chroot $ROOT grub-mkdevicemap --no-floppy -m - | cut -f2)" for grubdev in $devices; do disk_id="$(device_to_id $grubdev)" dev="$(readlink -f "$disk_id")" dev_list="${dev_list:+$dev_list, }$dev" descr="$(echo $disk_id |sed -e 's+^.*/++' |sed -e 's+,+\\,+g')" if [ "$dev" = "$disk_id" ]; then dev_descr="${dev_descr:+$dev_descr, }$dev" else #/dev/sdX (id) dev_descr="${dev_descr:+$dev_descr, }$dev ($descr)" fi done debug "Bootdev Choices: '$dev_list'" debug "Bootdev Descriptions: '$dev_descr'" db_subst grub-installer/choose_bootdev DEVICES_LIST "$dev_list" db_subst grub-installer/choose_bootdev DESCRIPTIONS "$dev_descr" # set initial selection if [ -n "$default_choice" ] ; then chosen="$(readlink -f "$default_choice")" if [ -n "$chosen" ] ;then db_set grub-installer/choose_bootdev "$chosen" fi fi db_input high grub-installer/choose_bootdev || true if ! db_go; then log "Returning to menu" db_progress STOP exit 10 fi db_get grub-installer/choose_bootdev || true # Choices-C (not shown to user) can be set to 'manual' if [ "$RET" = "manual" ] ; then result="" else result="$(echo "$RET" | cut -d' ' -f1)" fi debug "select_bootdev: result='$result'" echo "$result" } if [ "$bootdev" != "dummy" ] && [ ! "$frdev" ]; then # check for a preseeded value db_get grub-installer/bootdev || true if [ -n "$RET" ] ; then bootdev="$RET" fi fi while : ; do debug "q='$q' state='$state' defbd='$default_bootdev' bd='$bootdev'" db_fget grub-installer/bootdev seen if [ "$RET" = true ] && db_get grub-installer/bootdev && [ "$RET" ] ; then if [ "$RET" = "default" ]; then bootdev=$default_bootdev else bootdev=$RET fi break elif [ "$state" = 1 ]; then db_input high $q || true if ! db_go; then # back up to menu db_progress STOP exit 10 fi db_get $q if [ "$RET" = true ]; then # default_bootdev can be guessed incorrectly. # If the user supplied a value for bootdev, # ask them to resolve any conflict. if [ "$bootdev" != "$default_bootdev" ] ; then bootdev="$(select_bootdev "$bootdev")" previous_state=1 fi if [ -e "$bootdev" ] ; then break else state=2 fi else # Exit to menu if /boot is on SATA RAID/multipath; we # don't support device selection in that case if [ "$frdev" ]; then db_progress STOP exit 10 fi state=2 fi elif [ "$state" = 2 ]; then if [ "$previous_state" != "1" ]; then bootdev="$(select_bootdev "$bootdev")" unset previous_state fi if [ ! -e "$bootdev" ]; then db_input critical grub-installer/bootdev || true fi if ! db_go; then if [ "$q" ]; then state=1 else # back up to menu db_progress STOP exit 10 fi else db_get grub-installer/bootdev bootdev=$RET if echo "$bootdev" | grep -qv '('; then mappedbootdev=$(mapdevfs "$bootdev") || true if [ -n "$mappedbootdev" ]; then bootdev="$mappedbootdev" fi fi break fi else break fi done db_progress STEP 1 db_subst grub-installer/progress/step_install_loader BOOTDEV "$bootdev" db_progress INFO grub-installer/progress/step_install_loader info "Installing grub on '$bootdev'" update_mtab if [ -z "$frdisk" ]; then # Install grub on each space separated disk in the list bootdevs="$bootdev" for bootdev in $bootdevs; do grub_install_params= if ! is_floppy "$bootdev"; then grub_install_params="$grub_install_params --no-floppy" fi db_get grub-installer/force-efi-extra-removable if [ "$RET" = true ]; then grub_install_params="$grub_install_params --force-extra-removable" fi db_get grub-installer/update-nvram if [ "$RET" = false ]; then grub_install_params="$grub_install_params --no-nvram" fi case $ARCH in powerpc/chrp_pegasos) # nvram is broken here grub_install_params="$grub_install_params --no-nvram" ;; powerpc/powermac_newworld|ppc64/powermac_newworld) grub_install_params="$grub_install_params --macppc-directory=/boot/grub --no-nvram" ;; sparc/*|sparc64/*) # see: https://github.com/esnowberg/grub2-sparc/wiki case $SUBARCH in *_gpt) # No additional parameters for installing GRUB # on disks with GPT disk labels : ;; *) grub_install_params="$grub_install_params --skip-fs-probe" ;; esac ;; esac if [ "$grub_version" = "grub" ] ; then grub_install_params="$grub_install_params --recheck" else # install even if it requires blocklists grub_install_params="$grub_install_params --force" fi CODE=0 case $ARCH:$grub_package in *:grub|*:grub-pc|*:grub-efi*|sparc/*:grub-ieee1275|sparc64/*:grub-ieee1275|powerpc/chrp*:grub-ieee1275|ppc64/chrp*:grub-ieee1275|ppc64el/*:grub-ieee1275) info "Running $chroot $ROOT grub-install $grub_install_params \"$bootdev\"" log-output -t grub-installer $chroot $ROOT grub-install $grub_install_params "$bootdev" || CODE=$? ;; powerpc/powermac_newworld:grub-ieee1275|ppc64/powermac_newworld:grub-ieee1275) info "Running $chroot $ROOT grub-install $grub_install_params" log-output -t grub-installer $chroot $ROOT grub-install $grub_install_params || CODE=$? ;; amd64/*:grub-xen) info "Running $chroot $ROOT grub-install --target=x86_64-xen $grub_install_params" log-output -t grub-installer $chroot $ROOT grub-install --target=x86_64-xen $grub_install_params || CODE=$? ;; i386/*:grub-xen) info "Running $chroot $ROOT grub-install --target=x86_64-xen $grub_install_params" log-output -t grub-installer $chroot $ROOT grub-install --target=x86_64-xen $grub_install_params || CODE=$? info "Running $chroot $ROOT grub-install --target=i386-xen $grub_install_params" log-output -t grub-installer $chroot $ROOT grub-install --target=i386-xen $grub_install_params || CODE=$? ;; *) info "Running $chroot $ROOT grub-install $grub_install_params" log-output -t grub-installer $chroot $ROOT grub-install $grub_install_params || CODE=$? ;; esac if [ "$CODE" = 0 ]; then info "grub-install ran successfully" case $ARCH:$grub_package in powerpc/powermac_newworld:grub-ieee1275|ppc64/powermac_newworld:grub-ieee1275) umount $bootdev $chroot $ROOT hmount $bootdev $chroot $ROOT hattrib -c UNIX -t tbxi :System:Library:CoreServices:BootX $chroot $ROOT hattrib -b :System:Library:CoreServices $chroot $ROOT humount mount $bootdev $ROOT/boot/grub ;; *) : ;; esac else case $ARCH:$grub_package in *:grub|*:grub-pc|*:grub-efi*|sparc/*:grub-ieee1275|sparc64/*:grub-ieee1275|powerpc/chrp*:grub-ieee1275|ppc64/chrp*:grub-ieee1275|ppc64el/*:grub-ieee1275) error "Running 'grub-install $grub_install_params \"$bootdev\"' failed." ;; *) error "Running 'grub-install $grub_install_params failed." ;; esac db_subst grub-installer/grub-install-failed BOOTDEV "$bootdev" db_input critical grub-installer/grub-install-failed || [ $? -eq 30 ] db_go || true db_progress STOP exit 1 fi done else # Semi-manual grub setup for Serial ATA RAID/multipath info "Boot partition is on a Serial ATA RAID disk or multipath device" info "Installing GRUB to $frdev; grub root is $disc_offered" case $(archdetect) in i386/*) stagedir=i386-pc ;; amd64/*) stagedir=x86_64-pc ;; *) error "Unsupported architecture for SATA RAID/multipath installation" exit 1 ;; esac if [ ! -d $ROOT/usr/lib/grub/$stagedir/ ]; then error "Grub stage files not available" exit 1 fi mkdir -p $ROOT/boot/grub cp $ROOT/usr/lib/grub/$stagedir/* $ROOT/boot/grub # TODO: Check for errors during this process! TERM=linux $chroot $ROOT \ grub --device-map=/dev/null >/var/log/grub-${frtype}.log 2>&1 &1 | \ grep "^Encrypted:" | cut -d' ' -f2) fi fi if [ "$password" ]; then echo "password --md5 $password" >/tmp/menu.lst.password # Add a line to menu.lst to use the given password # The line is appended after the commented example sed -i '/^# password/r /tmp/menu.lst.password' $ROOT/boot/grub/$menu_file # By default, menu.lst is world-readable, which is not so good if it # contains a password. chmod o-r $ROOT/boot/grub/$menu_file rm -f /tmp/menu.lst.password fi fi if [ "$grub_version" = grub ]; then # Add user parameters to menu.lst; some options are only added to # the default entry for a kernel instead of all entries. We can't do # this in the same place as the grub2 case because we need the menu # file to exist. if [ "$defopt_params" ]; then sed -i "s!^\(# defoptions=.*\)!\1 $defopt_params!" $ROOT/boot/grub/$menu_file fi if [ "$kopt_params" ]; then sed -i "s!^\(# kopt=.*\)!\1 $kopt_params!" $ROOT/boot/grub/$menu_file fi # In either case, update the Debian kernel entries if [ "$user_params" ]; then update_grub fi fi if [ "$serial" ] ; then # Modify menu.lst so _grub_ uses serial console. case $grub_package in grub) ( grub_serial_console $serial echo "terminal serial" cat $ROOT/boot/grub/$menu_file ) >$ROOT/boot/grub/$menu_file.new mv $ROOT/boot/grub/$menu_file.new $ROOT/boot/grub/$menu_file ;; grub-pc|grub-efi*) if grep -q "^GRUB_TERMINAL=" $ROOT/etc/default/grub; then sed -i $ROOT/etc/default/grub -e "s/^\(GRUB_TERMINAL\)=.*/\1=serial/g" else echo "GRUB_TERMINAL=serial" >> $ROOT/etc/default/grub fi if grep -q "^GRUB_SERIAL_COMMAND=" $ROOT/etc/default/grub ; then sed -i $ROOT/etc/default/grub -e "s/^\(GRUB_SERIAL_COMMAND\)=.*/\1=\"`grub_serial_console $serial`\"/g" else echo "GRUB_SERIAL_COMMAND=\"`grub_serial_console $serial`\"" >> $ROOT/etc/default/grub fi update_grub # propagate to grub.cfg ;; esac fi # Generate menu.lst additions for other OSes tmpfile=/tmp/menu.lst.extras OLDIFS="$IFS" IFS="$newline" no_floppy="" if $chroot $ROOT dpkg --compare-versions $grub_debian_version ge 1.96+20090609-1 ; then no_floppy="--no-floppy" fi # I don't think any of this is needed, as we have os-prober? for os in $(cat /tmp/os-probed); do IFS="$OLDIFS" title=$(echo "$os" | cut -d: -f2) shortname=$(echo "$os" | cut -d: -f3) type=$(echo "$os" | cut -d: -f4) case "$type" in chain) partition=$(mapdevfs $(echo "$os" | cut -d: -f1)) grubdrive=$(convert "$partition") || true if [ -n "$grubdrive" ]; then case $grub_version in grub) grub_write_chain ;; grub2) grub2_write_chain ;; esac fi ;; linux) partition=$(echo "$os" | cut -d: -f1) mappedpartition=$(mapdevfs "$partition") IFS="$newline" for entry in $(linux-boot-prober "$partition"); do IFS="$OLDIFS" bootpart=$(echo "$entry" | cut -d: -f2) mappedbootpart=$(mapdevfs "$bootpart") || true if [ -z "$mappedbootpart" ]; then mappedbootpart="$bootpart" fi label=$(echo "$entry" | cut -d : -f3) if [ -z "$label" ]; then label="$title" fi kernel=$(echo "$entry" | cut -d : -f4) initrd=$(echo "$entry" | cut -d : -f5) if echo "$kernel" | grep -q '^/boot/' && \ [ "$mappedbootpart" != "$mappedpartition" ]; then # separate /boot partition kernel=$(echo "$kernel" | sed 's!^/boot!!') initrd=$(echo "$initrd" | sed 's!^/boot!!') grubdrive=$(convert "$mappedbootpart") || true else grubdrive=$(convert "$mappedpartition") || true fi params="$(echo "$entry" | cut -d : -f6-) $serial" case $grub_version in grub) grub_write_linux ;; grub2) grub2_write_linux ;; esac IFS="$newline" done IFS="$OLDIFS" ;; hurd) partition=$(mapdevfs $(echo "$os" | cut -d: -f1)) grubdrive=$(convert "$partition") || true hurddrive=$(hurd_convert "$partition") || true # Use the standard hurd boilerplate to boot it. case $grub_version in grub) grub_write_hurd ;; grub2) grub2_write_hurd ;; esac ;; *) info "unhandled: $os" ;; esac IFS="$newline" done IFS="$OLDIFS" rm -f /tmp/os-probed if [ -s $tmpfile ] ; then case $grub_version in grub) grub_write_divider cat $tmpfile >> $ROOT/boot/grub/$menu_file ;; grub2) if ! $chroot $ROOT which os-prober >/dev/null 2>&1; then cat > $ROOT/etc/grub.d/30_otheros << EOF #!/bin/sh exec tail -n +3 \$0 EOF cat $tmpfile >> $ROOT/etc/grub.d/30_otheros chmod +x $ROOT/etc/grub.d/30_otheros update_grub # propagate 30_otheros to grub.cfg fi ;; esac rm -f $tmpfile fi case $ARCH in mipsel/loongson-2f) # Configure PMON to load GRUB by default. if [ ! -e $ROOT/boot.cfg ] && [ ! -e $ROOT/boot/boot.cfg ]; then pmon_partition="$(grub_probe -d -t drive "$bootfs" | \ sed 's/.*,//; s/[^0-9]//g')" if [ "$pmon_partition" ]; then pmon_partition=$(($pmon_partition - 1)) else pmon_partition=0 # fallback guess fi if [ "$rootfs" = "$bootfs" ]; then pmon_grub_path=/boot/grub.elf pmon_boot_cfg_path=$ROOT/boot.cfg else pmon_grub_path=/grub.elf pmon_boot_cfg_path=$ROOT/boot/boot.cfg fi cat > $pmon_boot_cfg_path <> $ROOT/etc/kernel-img.conf fi db_progress STEP 1 db_progress STOP