#!/bin/sh -euf # Copyright 2013-2014 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 PROG="setup-scripts-bootloader-conf" VER="1.0" srcdir="$(readlink -ev -- ${0%/*})" PATH="/usr/share/setup-scripts:$srcdir:$PATH" if [ -f "$srcdir/setup-scripts-sh-functions" ]; then . "$srcdir/setup-scripts-sh-functions" . "$srcdir/installerfw-sh-functions" else . /usr/share/setup-scripts/setup-scripts-sh-functions . /usr/share/setup-scripts/installerfw-sh-functions fi # This is a small trick which I use to make sure my scripts are portable - # check if 'dash' is present, and if yes - use it. if can_switch_to_dash; then exec dash -euf -- "$srcdir/$PROG" "$@" exit $? fi # Preparation stuff common for all subcommands prepare() { # Get the installer framework environment installerfw_restore_env rootdir="$(installerfw_mnt_prefix "/")" bootdir="$(installerfw_mnt_prefix "/boot")" if installerfw_is_efi_boot_system; then boot="gummiboot" else boot="extlinux" fi } # # ----------------------------------------------------------------------------- # The "add" subcommand # ----------------------------------------------------------------------------- # show_add_usage() { cat <<-EOF Usage: $PROG add [options] Add bootloader entries for kernel . Options: -f, --force if bootloader entries for already exist in bootloader's config file(s) - re-write them, if does not exist - do not fail -h, --help show this text and exit EOF } show_add_usage_fail() { IFS= printf "%s\n\n" "$PROG: error: $*" >&2 show_add_usage >&2 exit 1 } add_subcommand() { if [ "$#" -eq 0 ]; then show_add_usage exit 0 fi local tmp tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` || show_add_usage_fail "cannot parse command-line options" eval set -- "$tmp" local force= while true; do case "$1" in -f|--force) force="-f" ;; -h|--help) show_add_usage exit 0 ;; --) shift; break ;; *) show_add_usage_fail "unrecognized option \"$1\"" ;; esac shift done if [ "$#" -lt 1 ]; then show_add_usage_fail "please, specify the kernel" fi if [ "$#" -gt 1 ]; then show_add_usage_fail "too many arguments: \"$1\"" fi prepare local kernel="$1" local kernel_path="$bootdir/$kernel" if ! [ -f "$kernel_path" ] && [ -z "$force" ]; then fatal "cannot find kernel \"$kernel_path\"" \ "(use -f to ignore this error)" fi # Get root partition PARTUUID installerfw_get_part_info "/" "PARTUUID" "root_partuuid" [ -n "$root_partuuid" ] || \ fatal "cannot find PARTUUID of the root partition" # Get kernel options local options="${INSTALLERFW_KERNEL_OPTS:-} root=PARTUUID=$root_partuuid" # Get OS name local os_name= get_os_name "os_name" # Add the default bootloader entry setup-$boot-conf $verbose --bootdir "$bootdir" add $force \ "$kernel" "$os_name" "$kernel" "$options" # Add the debug bootloader entry. If there is the "quiet" option, # create a non-quiet configuration. local verbose_opts="$(printf "%s" "$options" | LC_ALL=C \ sed -e "s/[[:blank:]]\+quiet[[:blank:]]\+/ / s/^quiet[[:blank:]]\+// s/[[:blank:]]\+quiet$// s/^quiet$//")" local debug_opts="$verbose_opts ignore_loglevel log_buf_len=2M" local debug_opts="$debug_opts initcall_debug" setup-$boot-conf $verbose --bootdir "$bootdir" add \ $force "$kernel-debug" "Debug $os_name" \ "$kernel" "$verbose_opts" # Add the clone bootloader entry, but only if the cloning tool is # installed if [ -f "$rootdir/usr/sbin/setup-scripts-clone" ]; then clone_opts="$options systemd.unit=scripts-clone.service" clone_opts="$clone_opts scripts-clone-target=autodetect" setup-$boot-conf $verbose --bootdir "$bootdir" add \ $force "$kernel-clone" "Clone $os_name" \ "$kernel" "$clone_opts" fi # Use default gummiboot-splash file local splash_path="$rootdir/usr/share/gummiboot/splash.bmp" # Add a splash entry for fastboot testing and disable fbcon if [ "$boot" = "gummiboot" ] && [ -f "$splash_path" ]; then splash_opts="$options i915.fastboot=1 fbcon=map:9" setup-$boot-conf $verbose --bootdir "$bootdir" add \ $force --splash "$splash_path" "$kernel-splash" \ "Splash $os_name" "$kernel" "$splash_opts" fi } # # ----------------------------------------------------------------------------- # The "remove" subcommand # ----------------------------------------------------------------------------- # show_remove_usage() { cat <<-EOF Usage: $PROG remove [options] Delete bootloader entries for kernel (only those which were previously created with "$PROG add"). Options: -f, --force do not fail if does not have corresponding bootloader entries -h, --help show this text and exit EOF } show_remove_usage_fail() { IFS= printf "%s\n\n" "$PROG: error: $*" >&2 show_remove_usage >&2 exit 1 } remove_subcommand() { if [ "$#" -eq 0 ]; then show_remove_usage exit 0 fi local tmp tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` || show_remove_usage_fail "cannot parse command-line options" eval set -- "$tmp" local force= while true; do case "$1" in -f|--force) force="-f" ;; -h|--help) show_remove_usage exit 0 ;; --) shift; break ;; *) show_remove_usage_fail "unrecognized option \"$1\"" ;; esac shift done if [ "$#" -lt 1 ]; then show_add_usage_fail "please, specify the kernel" fi if [ "$#" -gt 1 ]; then show_remove_usage_fail "too many arguments: \"$1\"" fi local kernel="$1" prepare # Get the current default entry local default="$(setup-$boot-conf $verbose --bootdir "$bootdir" \ default $force)" [ $? -eq 0 ] || \ fatal "cannot get the default kernel, setup-$boot-conf failed" local default_kernel="$(printf "%s" "$default" | LC_ALL=C \ sed -n -e 's/^kernel: \(.\+\)$/\1/p')" if [ -n "$default_kernel" ]; then verbose "current default boot kernel is " \ "\"$default_kernel\"" else verbose "did not find the default kernel," \ "setup-$boot-conf returned: $default" fi # Remove the kernel setup-$boot-conf $verbose --bootdir "$bootdir" \ remove $force "$kernel" || \ fatal "setup-$boot-conf failed to remove" \ "entry \"$kernel\"" setup-$boot-conf $verbose --bootdir "$bootdir" \ remove $force "$kernel-debug" || \ fatal "setup-$boot-conf failed to remove" \ "entry \"$kernel-verbose\"" # The "clone" entry does not necessary exist, so use --force setup-$boot-conf $verbose --bootdir "$bootdir" \ remove --force "$kernel-clone" || \ fatal "setup-$boot-conf failed to remove" \ "entry \"$kernel-clone\"" # Ditto for "splash" setup-$boot-conf $verbose --bootdir "$bootdir" \ remove --force "$kernel-splash" || \ fatal "setup-$boot-conf failed to remove" \ "entry \"$kernel-splash\"" # If this is not the default kernel, we are done [ "$kernel" = "$default_kernel" ] || return 0 # We've just removed the default kernel, find the kernel with the # latest version and make it to be the default verbose "removed the default kernel, find the newest available" local newest_kernel="$(get_newest_kernel "$bootdir" "$kernel")" if [ -z "$newest_kernel" ]; then verbose "no more kernels, set the kernel to none" setup-$boot-conf $verbose --bootdir "$bootdir" \ default --force "" else verbose "new default kernel is \"$newest_kernel\"" setup-$boot-conf $verbose --bootdir "$bootdir" \ default "$newest_kernel" fi if [ "$?" -ne 0 ]; then fatal "cannot set default kernel, \"setup-$boot-conf\" failed" fi } # # ----------------------------------------------------------------------------- # The "default" subcommand # ----------------------------------------------------------------------------- # show_default_usage() { cat <<-EOF Usage: $PROG default [options] Set the default boot kernel to . If is omited, print the current default boot kernel name. Options: -f, --force do not fail if doesn't exist -h, --help show this text and exit EOF } show_default_usage_fail() { IFS= printf "%s\n\n" "$PROG: error: $*" >&2 show_default_usage >&2 exit 1 } default_subcommand() { local tmp tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` || show_default_usage_fail "cannot parse command-line options" eval set -- "$tmp" local force= while true; do case "$1" in -f|--force) force="-f" ;; -h|--help) show_default_usage exit 0 ;; --) shift; break ;; *) show_default_usage_fail "unrecognized option \"$1\"" ;; esac shift done if [ "$#" -gt 1 ]; then show_default_usage_fail "too many arguments: \"$1\"" fi prepare local kernel="${1:-}" local kernel_path="$bootdir/$kernel" if [ -n "$kernel" ] && ! [ -f "$kernel_path" ] && [ -z "$force" ]; then fatal "cannot find kernel \"$kernel_path\"" \ "(use -f to ignore this error)" fi setup-$boot-conf $verbose --bootdir "$bootdir" default $force "$kernel" } # # ----------------------------------------------------------------------------- # show_usage() { cat <<-EOF Usage: $PROG [options] [options] This program adds or removes a kernel to/from the bootloader configuration file(s). This is a Tizen specific program and it currently supports only 2 bootloader types - extlinux and gummiboot. Each new kernel gets 2 boot menu entries - the default and verbose, and both of these are removed by the "remove" subcommand. The supported subcommands are: add - add bootloader entries for a kernel remove - remove bootloader entries for a kernel default - get or set the default boot kernel Run "$PROG " to see subcommand-specific help. Options: --version show the program version and exit -v, --verbose be verbose -h, --help show this text and exit EOF } show_usage_fail() { IFS= printf "%s\n\n" "$PROG: error: $*" >&2 show_usage >&2 exit 1 } verbose= while [ -n "${1:-""}" ] && [ -z "${1##-*}" ]; do case "$1" in --version) printf "%s\n" "$VER" exit 0 ;; -v|--verbose) verbose="-v" ;; -h|--help) show_usage exit 0 ;; --) shift; break ;; *) show_usage_fail "unrecognized option \"$1\"" ;; esac shift done if [ "$#" -eq 0 ]; then show_usage exit 0 fi # Parse subcommands subcommand="$1"; shift case "$subcommand" in add) add_subcommand "$@" break ;; remove) remove_subcommand "$@" break ;; default) default_subcommand "$@" break ;; *) show_usage_fail "unrecognized subcommand \"$subcommand\"" ;; esac