#!/bin/sh # # Insert a list of installed kernels in a grub menu.lst file # Copyright 2001 Wichert Akkerman # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # Contributors: # Jason Thomas # David B.Harris # Marc Haber # Crispin Flowerday ## StartOPTIONS # name of file menu is stored in menufile="menu.lst" # directory's to look for the grub installation and the menu file grubdirs="/boot/grub /boot/boot/grub" # Default kernel options, overidden by the kopt statement in the menufile. kopt="root=/dev/hda1 ro" # Drive(in GRUB terms) where the kernel is located. If a seperate # partition, this would be mounted under /boot, overridden by the kopt statement in menufile groot="(hd0,0)" # should grub create the alternative boot options in the menu alternative="true" # should grub lock the alternative boot options in the menu lockalternative="false" # options to use with the alternative boot options altoptions="(recovery mode) single" # Default options to use in a new menu.lst . This will only be used if menu.lst # doesn't already exist. Only edit the lines between the two "EOF"s. The others are # part of the script. newtemplate=$(tempfile) cat > "$newtemplate" <&2 echo "$@" >&2 echo >&2 exit 1 } # Compares two version strings A and B # Returns -1 if AB # This compares version numbers of the form # 2.4.14-random > 2.4.14-ac10 > 2.4.14 > 2.4.14-pre2 > # 2.4.14-pre1 > 2.4.13-ac99 CompareVersions() { # First split the version number and remove any '.' 's or dashes v1=$(echo $1 | sed -e 's![^0-9]\+! & !g' -e 's![\.\-]!!g') v2=$(echo $2 | sed -e 's![^0-9]\+! & !g' -e 's![\.\-]!!g') # also convert ac -> 50, pre -> -50 and anything else to 99 v1=$(echo $v1 | sed -e 's!ac!50!g' -e 's!pre!-50!g' -e 's![^-0-9 ]\+!99!g') v2=$(echo $v2 | sed -e 's!ac!50!g' -e 's!pre!-50!g' -e 's![^-0-9 ]\+!99!g') result=0; v1finished=0; v2finished=0; while [ $result -eq 0 -a $v1finished -eq 0 -a $v2finished -eq 0 ]; do if [ "$v1" = "" ]; then v1comp=0; v1finished=1 else set -- $v1; v1comp=$1; shift; v1=$* fi if [ "$v2" = "" ]; then v2comp=0; v2finished=1 else set -- $v2; v2comp=$1; shift; v2=$* fi if [ $v1comp -gt $v2comp ]; then result=1 elif [ $v1comp -lt $v2comp ]; then result=-1 fi done # finally return the result echo $result } echo -n "Searching for GRUB installation directory ... " for d in $grubdirs ; do if [ -d "$d" ] ; then dir="$d" break fi done if [ -z "$dir" ] ; then abort "GRUB is not installed. To install grub, you may use the 'grub-install' command" else echo "found: $dir ." fi echo -n "Testing for an existing GRUB menu.list file... " # Test if our menu file exists if [ -f "$dir/$menufile" ] ; then menu="$dir/$menufile" unset newtemplate echo "found: $menu ." else # if not ask user if they want us to create one menu="$dir/$menufile" echo echo echo -n "Could not find $menu file. " echo -n "Would you like one generated for you? " echo -n "(y/N) " read answer case "$answer" in y* | Y*) cat "$newtemplate" > $menu unset newtemplate ;; *) abort "Not creating menu.lst as you wish" ;; esac fi # Extract the kernel options to use tmp=$(sed -ne 's/# kopt=\(.*\)/\1/p' $menu) [ -z "$tmp" ] || kopt="$tmp" # Extract the grub root tmp=$(sed -ne 's/# groot=\(.*\)/\1/p' $menu) [ -z "$tmp" ] || groot="$tmp" # Extract the old recovery value tmp=$(sed -ne 's/# recovery=\(.*\)/\1/p' $menu) [ -z "$tmp" ] || alternative="$tmp" # Extract the alternative value tmp=$(sed -ne 's/# alternative=\(.*\)/\1/p' $menu) [ -z "$tmp" ] || alternative="$tmp" # Extract the lockalternative value tmp=$(sed -ne 's/# lockalternative=\(.*\)/\1/p' $menu) [ -z "$tmp" ] || lockalternative="$tmp" # Generate the menu options we want to insert buffer=$(tempfile) echo $start >> $buffer echo "## lines between the AUTOMAGIC KERNELS LIST markers will be modified" >> $buffer echo "## by the debian update-grub script except for the default optons below" >> $buffer echo >> $buffer echo "## DO NOT UNCOMMENT THEM, Just edit them to your needs" >> $buffer echo >> $buffer echo "## ## Start Default Options ##" >> $buffer echo "## default kernel options" >> $buffer echo "## e.g. kopt=\"root=/dev/hda1 ro\"" >> $buffer echo "# kopt=$kopt" >> $buffer echo >> $buffer echo "## default grub root device" >> $buffer echo "## e.g. groot=(hd0,0)" >> $buffer echo "# groot=$groot" >> $buffer echo >> $buffer echo "## should update-grub create alternative boot options" >> $buffer echo "## e.g. alternative=true" >> $buffer echo "## alternative=false" >> $buffer echo "# alternative=$alternative" >> $buffer echo >> $buffer echo "## should update-grub lock alternative boot options" >> $buffer echo "## e.g. lockalternative=true" >> $buffer echo "## lockalternative=false" >> $buffer echo "# lockalternative=$lockalternative" >> $buffer echo >> $buffer echo "## altoption boot targets option" >> $buffer echo "## multiple altoptions lines are allowed" >> $buffer echo "## e.g. altoptions=(extra menu suffix) extra boot options" >> $buffer echo "## altoptions=(recovery mode) single" >> $buffer if ! grep -q "^# altoptions" $menu ; then echo "# altoptions=$altoptions" >> $buffer else grep "^# altoptions" $menu >> $buffer fi echo >> $buffer echo "## ## End Default Options ##" >> $buffer echo >> $buffer sortedKernels="" for kern in $(/bin/ls -1vr /boot/vmlinuz-*) ; do # found a kernel newerKernels="" for i in $sortedKernels ; do res=`CompareVersions "$kern" "$i"`; if [ "$kern" != "" -a $res -gt 0 ] ; then newerKernels="$newerKernels $kern $i" kern="" else newerKernels="$newerKernels $i" fi done if [ "$kern" != "" ] ; then newerKernels="$newerKernels $kern" fi sortedKernels="$newerKernels" done for kern in $sortedKernels ; do kernelName=$(basename $kern) kernelVersion=$(echo $kernelName | sed -e 's/vmlinuz-//') if mount | grep -qs "on /boot " > /dev/null 2>&1 ; then kernel=/$kernelName initrd=/initrd-$kernelVersion else kernel=/boot/$kernelName initrd=/boot/initrd-$kernelVersion fi echo "title Debian GNU/Linux, kernel $kernelVersion" >> $buffer echo "root $groot" >> $buffer echo "kernel $kernel $kopt" >> $buffer if [ -e /boot/initrd-$kernelVersion ]; then echo "initrd $initrd" >> $buffer fi echo "savedefault" >> $buffer echo >> $buffer # insert the alternative boot options if test ! x"$alternative" = x"false" ; then # for each altoptions line do this stuff sed -ne 's/# altoptions=\(.*\)/\1/p' $buffer | while read line; do descr=$(echo $line | sed -ne 's/\(([^)]*)\)[[:space:]]\(.*\)/\1/p') suffix=$(echo $line | sed -ne 's/\(([^)]*)\)[[:space:]]\(.*\)/\2/p') echo "title Debian GNU/Linux, kernel $kernelVersion $descr" >> $buffer # lock the alternative options if test x"$lockalternative" = x"true" ; then echo "lock" >> $buffer fi echo "root $groot" >> $buffer echo "kernel $kernel $kopt $suffix" >> $buffer if [ -e /boot/initrd-$kernelVersion ]; then echo "initrd $initrd" >> $buffer fi echo "savedefault" >> $buffer echo >> $buffer done fi done echo $end >> $buffer echo -n "Updating $menu ... " # Insert the new options into the menu if ! grep -q "^$start" $menu ; then cat $buffer >> $menu else umask 077 sed -e "/^$start/,/^$end/{ /^$start/r $buffer d } " $menu > $menu.new cat $menu.new > $menu rm -f $buffer $menu.new fi echo "done" echo if [ ! -z $answer ]; then cat <