# kboot-mkconfig helper script. # Copyright (C) 2011 Antonio Ospite # # Inspired by the 10_linux script from grub # # This program 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 3 of the License, or # (at your option) any later version. # # This progra, 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 software. If not, see . prefix=/usr exec_prefix=${prefix} bindir=${exec_prefix}/bin libdir=${exec_prefix}/lib # TODO: remove this if the following find_linux_root_device() # is found to be reliable enough #LINUX_ROOT_DEVICE="$(readlink -f $(mount | grep ' / ' | cut -d ' ' -f 1))" if $(which gettext >/dev/null 2>/dev/null) ; then gettext="gettext" else gettext="echo" fi # One layer of quotation is eaten by "", the second by sed, and the third by # printf; so this turns ' into \'. Note that you must use the output of # this function in a printf format string. gettext_quoted () { $gettext "$@" | sed "s/'/'\\\\\\\\''/g" } # Run the first argument through gettext_quoted, and then pass that and all # remaining arguments to printf. This is a useful abbreviation and tends to # be easier to type. gettext_printf () { local format="$1" shift printf "$(gettext_quoted "$format")" "$@" } kboot_file_is_not_garbage () { if test -f "$1" ; then case "$1" in *.dpkg-*) return 1 ;; # debian dpkg README*) return 1 ;; # documentation esac else return 1 fi return 0 } version_test_gt () { local sedexp="s/[^-]*-//;s/[._-]\(pre\|rc\|test\|git\|old\|trunk\)/~\1/g" local a=`echo $1 | sed -e "$sedexp"` local b=`echo $2 | sed -e "$sedexp"` local cmp=gt if [ "x$b" = "x" ] ; then return 0 fi case $a:$b in *.old:*.old) ;; *.old:*) a=`echo -n $a | sed -e s/\.old$//` ; cmp=gt ;; *:*.old) b=`echo -n $b | sed -e s/\.old$//` ; cmp=ge ;; esac dpkg --compare-versions "$a" $cmp "$b" return $? } version_find_latest () { local a="" for i in $@ ; do if version_test_gt "$i" "$a" ; then a="$i" fi done echo "$a" } linux_find_root_device() { ROOT_DEVICE=$(mountpoint -d /) for devnode in $(find /dev); do # Get major and minor in decimal CURRENT_DEVICE=$(printf "%d:%d" $(stat --printf="0x%t 0x%T" "$devnode")) if [ $CURRENT_DEVICE = $ROOT_DEVICE ]; then ROOT_NODE="$devnode" break fi done echo "$ROOT_NODE" } linux_entry () { os="$1" version="$2" recovery="$3" args="$4" if ${recovery} ; then title="$(gettext_quoted "%s, with Linux %s (recovery mode)")" else title="$(gettext_quoted "%s, with Linux %s")" fi label="$(printf "${title}" "${os}" "${version}")" echo -n "'${label}'='${dirname}/${basename} " if test -n "${initrd}" ; then echo -n "initrd=${dirname}/${initrd}" fi echo " root=${linux_root_device_thisversion} ro ${args}'" } list_kernels () { list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* ; do if kboot_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` prepare_boot_cache= while [ "x$list" != "x" ] ; do linux=`version_find_latest $list` echo "Found linux image: $linux" >&2 basename=`basename $linux` dirname=`dirname $linux` # XXX: this relies on a binary shipped by GRUB, we just use ${dirname} for # now, check the ${dirname} entries if we need something like that later #rel_dirname=`make_system_path_relative_to_its_root $dirname` version=`echo $basename | sed -e "s,^[^0-9]*-,,g"` alt_version=`echo $version | sed -e "s,\.old$,,g"` # TODO: remove this too #linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" linux_root_device_thisversion=`linux_find_root_device` initrd= for i in "initrd.img-${version}" "initrd-${version}.img" \ "initrd-${version}" "initramfs-${version}.img" \ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ "initrd-${alt_version}" "initramfs-${alt_version}.img"; do if test -e "${dirname}/${i}" ; then initrd="$i" break fi done initramfs= for i in "config-${version}" "config-${alt_version}"; do if test -e "${dirname}/${i}" ; then initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${dirname}/${i}" | cut -f2 -d= | tr -d \"` break fi done if test -n "${initrd}" ; then echo "Found initrd image: ${dirname}/${initrd}" >&2 elif test -z "${initramfs}" ; then # "UUID=" magic is parsed by initrd or initramfs. Since there's # no initrd or builtin initramfs, it can't work here. linux_root_device_thisversion=${KBOOT_DEVICE} fi linux_entry "${OS}" "${version}" false \ "${KBOOT_CMDLINE_LINUX} ${KBOOT_CMDLINE_LINUX_DEFAULT}" if [ "x${KBOOT_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" true \ "single ${KBOOT_CMDLINE_LINUX}" fi list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` done }