#! /bin/sh #---------------------------------------------------------------------------- # /var/install/bin/update-bootloader - update boot configuration # # Creation : 2008-08-14 tb # Last Update: $Id$ # # Copyright (c) 2001-@@YEAR@@ the eisfair team, team(at)eisfar(dot)org # # 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 2 of the License, or # (at your option) any later version. #---------------------------------------------------------------------------- . /var/install/include/eislib do_debug="no" system="$(lsb_release -ds)" #----------------------------------------------------------------------------- # show help #----------------------------------------------------------------------------- show_help() { cat <<EOF Update boot configuration Usage: update-bootloader [OPTIONS] options: --generate-new create a new bootloader configuration --use-existing activate a existing bootloader configuration for a new initrd EOF } #----------------------------------------------------------------------------- # when running in vmware, issue this warning #----------------------------------------------------------------------------- print_vmware_warning() { if lscpu | grep -qi 'vmware' then echo mecho --warn 'Please stop this virtual machine and set' mecho --warn ' disk.EnableUUID = "TRUE"' mecho --warn 'in vmx file of this virtual machine.' mecho --warn 'Then install this package again.' echo fi } #----------------------------------------------------------------------------- # read a single value for a given key from lilo.conf #----------------------------------------------------------------------------- lookup_value_from_lilo_conf() { local key="${1}" local value=$(egrep "${key}[[:blank:]]+=" /etc/lilo.conf | grep -v '^#' | head -1 | cut -d'=' -f2- | sed 's#"##g' | sed 's#[#].*$##g' | sed -e 's#^[[:blank:]]*##g' -e 's#[[:blank:]]*$##g') echo "${value}" } #----------------------------------------------------------------------------- # read a single value for a given key from lilo.conf (apply filter) #----------------------------------------------------------------------------- lookup_value_from_lilo_conf_with_filter() { local key="${1}" local filter="${2}" local value=$(egrep "${key}[[:blank:]]+=" /etc/lilo.conf | grep -v '^#' | grep -v "${filter}" | head -1 | cut -d'=' -f2- | sed 's#"##g' | sed 's#[#].*$##g' | sed -e 's#^[[:blank:]]*##g' -e 's#[[:blank:]]*$##g') echo "${value}" } #----------------------------------------------------------------------------- # read a single value for a given key from lilo.conf if it is an id #----------------------------------------------------------------------------- lookup_id_from_lilo_conf() { local key="${1}" if egrep "${key}[[:blank:]]+=" /etc/lilo.conf | grep -v '^#' | head -1 | grep -q "/dev/disk/by-id/" then # device is converted to /dev/disk/by-id/ lookup_value_from_lilo_conf "${key}" fi } #----------------------------------------------------------------------------- # read a single value for a given key from lilo.conf if it is an uuid #----------------------------------------------------------------------------- lookup_uuid_from_lilo_conf() { local key="${1}" if egrep "${key}[[:blank:]]+=" /etc/lilo.conf | grep -v '^#' | head -1 | grep -q "UUID" then echo $(egrep "${key}[[:blank:]]+=" /etc/lilo.conf | grep -v '^#' | head -1 | grep "UUID" | cut -d'"' -f2) fi } #----------------------------------------------------------------------------- # lookup device for a given mount point or path #----------------------------------------------------------------------------- lookup_device_from_path() { local mountpoint="${1}" hex_dev_number=$(LANG=C; stat ${mountpoint} | grep Device: | cut -f 1 -d '/' | cut -f 2 -d ' ' | sed 's#h##g') if [ "${#hex_dev_number}" -lt "4" ] then hex_dev_number="0${hex_dev_number}" fi if [ "${#hex_dev_number}" -eq "4" ] then local major=$(printf "%d\n" "0x${hex_dev_number:0:2}") local minor=$(printf "%d\n" "0x${hex_dev_number:2:2}") else local major=$(printf "%d\n" "0x${hex_dev_number:0:3}") local minor=$(printf "%d\n" "0x${hex_dev_number:3:2}") fi for file in $(find /sys/dev/block -name "${major}:${minor}") do source ${file}/uevent echo "/dev/${DEVNAME}" done } #----------------------------------------------------------------------------- # read device file from link in /dev/disk/by_id/* #----------------------------------------------------------------------------- lookup_device_from_link() { local id="${1}" echo $(readlink "${id}" | sed 's#^\.\.\/\.\.\/#\/dev\/#g') } #----------------------------------------------------------------------------- # check if device is a virtual disk #----------------------------------------------------------------------------- is_disk_a_virtual_device() { echo "${1}" | grep -q "^/dev/xvd" return "${?}" } #----------------------------------------------------------------------------- # check if device is a softraid disk #----------------------------------------------------------------------------- is_disk_a_softraid_device() { echo "${1}" | grep -q '^/dev/md' return "${?}" } #----------------------------------------------------------------------------- # read list of disks in /dev/disk/by_id/* and lookup the id for the device #----------------------------------------------------------------------------- lookup_disk_id_from_list() { local link='' local disk_device="${1}" if [ ! -d /dev/disk/by-id ] then return fi local disk_list=$(ls /dev/disk/by-id/* | grep -v '\-part' | grep -v 'wwn' | grep -v 'nvme-nvme.') for link in ${disk_list} do local newdevice="$(lookup_device_from_link ${link})" if [ "${disk_device}" = "${newdevice}" ] then echo "${link}" return fi done } #----------------------------------------------------------------------------- # print disks in /dev/disk/by_id/* for debug purpose #----------------------------------------------------------------------------- print_disk_ids_from_list() { if [ ! -d /dev/disk/by-id ] then return fi local disk_list=$(ls /dev/disk/by-id/* | grep -v '\-part' | grep -v 'wwn' | grep -v 'nvme-nvme.') mecho --info "Entries in /dev/disk/by-id:" for link in ${disk_list} do local newdevice="$(lookup_device_from_link ${link})" echo " ${newdevice} --> ${link}" done } #----------------------------------------------------------------------------- # read list of uuids in /dev/disk/uuid/* and lookup the uuid for the device #----------------------------------------------------------------------------- lookup_volume_uuid_from_list() { local link='' local disk_device="${1}" if [ ! -d /dev/disk/by-uuid ] then return fi local uuid_list=$(ls /dev/disk/by-uuid/*) for link in ${uuid_list} do local newdevice="$(lookup_device_from_link ${link})" if [ "${disk_device}" = "${newdevice}" ] then link=$(echo ${link} | sed 's#/dev/disk/by-uuid/##g') echo "UUID=${link}" return fi done } #----------------------------------------------------------------------------- # print uuids in /dev/disk/by_uuid/* for debug purpose #----------------------------------------------------------------------------- print_volume_uuids_from_list() { if [ ! -d /dev/disk/by-uuid ] then return fi local uuid_list=$(ls /dev/disk/by-uuid/*) mecho --info "Entries in /dev/disk/by-uuid:" for link in ${uuid_list} do local newdevice="$(lookup_device_from_link ${link})" echo " ${newdevice} --> UUID=${link}" done } #----------------------------------------------------------------------------- # find suitable initrd name for kernel image #----------------------------------------------------------------------------- lookup_initrd_name() { local kernel="${1}" if [ "${kernel}" == "kernel" ] then echo "/boot/initrd.gz" return fi if [ "${kernel}" == "old-kernel" ] then echo "/boot/old-initrd.gz" return fi local kernel_name=$(echo ${kernel} | cut -d'-' -f2-) echo "/boot/initrd-${kernel_name}.gz" } #----------------------------------------------------------------------------- # inspect /boot for kernel images in correct order #----------------------------------------------------------------------------- lookup_kernel_images() { local kernels="kernel" local kernel if [ -L "/boot/kernel" ] then # new configuration (prefer versioned kernels over old-kernel) local versioned_kernels="$(ls /boot/kernel-* 2> /dev/null | sed 's#/boot/##g' | sort -r)" for kernel in ${versioned_kernels} do local initrd_name="$(lookup_initrd_name ${kernel})" if [ -f "${initrd_name}" ] then kernels="${kernels} ${kernel}" fi done if [ -f "/boot/old-kernel" ] then kernels="${kernels} old-kernel" fi else # old configuration (prefer old-kernel over versioned kernels) if [ -f "/boot/old-kernel" ] then kernels="${kernels} old-kernel" fi local versioned_kernels="$(ls /boot/kernel-* 2> /dev/null | sed 's#/boot/##g' | sort -r)" # only add kernel images with valid initrd for kernel in ${versioned_kernels} do local initrd_name="$(lookup_initrd_name ${kernel})" if [ -f "${initrd_name}" ] then kernels="${kernels} ${kernel}" fi done fi echo "${kernels}" } #----------------------------------------------------------------------------- # lookup name of kernel for label entry (max length = 15 characters) #----------------------------------------------------------------------------- lookup_kernel_name() { local kernel="${1}" if [ "${kernel}" == "old-kernel" ] then echo "oldeis" return fi if [ "${kernel}" == "kernel" ] then # enable this to make kernel appear with local version name # kernel_name=$(strings /boot/${kernel} | \ # egrep "^[0-9]+\.[0-9]+\.[0-9]+-eisfair-.*" | # head -1 | \ # cut -d' ' -f1) # echo "$(echo ${kernel_name} | sed "s#${system}-##g")" echo "eis" return fi local kernel_name=$(echo ${kernel} | cut -d'-' -f2-) echo "$(echo ${kernel_name} | sed "s#${system}-##g")" } #----------------------------------------------------------------------------- # add default append arguments, if not present #----------------------------------------------------------------------------- extend_append_args() { local append="${1}" if [ -z "${append}" ] then # append-zeile existiert nicht, setze raid=noautodetect, # setze consoleblank=600 (beim 5er Kernel ist default 0) append="raid=noautodetect consoleblank=600" else # zeile existiert if ! echo "${append}" | grep -q 'raid=noautodetect' then # setze raid=noautodetect wenn nicht vorhanden, # setze consoleblank=600 (beim 5er Kernel ist default 0) append="${append} raid=noautodetect" fi # zeile existiert if ! echo "${append}" | grep -q 'consoleblank=600' then # setze raid=noautodetect wenn nicht vorhanden, # setze consoleblank=600 (beim 5er Kernel ist default 0) append="${append} consoleblank=600" fi fi if ! mount -t devtmpfs | grep -q '/dev ' then # kein udev, alte base # Vorbereitung auf neue base mit udev if ! echo "${append}" | grep -q 'net.ifnames=0' then # net.ifnames=0 nicht gesetzt # notwendig fuer neue base mit udev append="${append} net.ifnames=0" fi fi echo "${append}" } #----------------------------------------------------------------------------- # write old disk section to lilo.conf #----------------------------------------------------------------------------- write_disk_section() { local disk_byid="${1}" local disk_dev="${2}" if [ -n "${disk_byid}" ] then echo "#disk = $disk" echo "disk = ${disk_byid}" else echo "disk = $disk" fi echo " bios = 0x80" echo "max-partitions = $maxpartitions" } #----------------------------------------------------------------------------- # write boot section to lilo.conf #----------------------------------------------------------------------------- write_boot_section() { local boot_byid="${1}" local boot_dev="${2}" local raid_extra_boot="${3}" if [ -n "${boot_byid}" ] then echo "#boot = ${boot_dev}" echo "boot = ${boot_byid}" else echo "boot = ${boot_dev}" fi if [ -n "${raid_extra_boot}" ] then echo "raid-extra-boot = mbr" fi } #----------------------------------------------------------------------------- # write kernel image to lilo.conf #----------------------------------------------------------------------------- write_kernel_image() { local kernel="${1}" local root_uuid="${2}" local root_partition="${3}" local vga="${4}" local append_args="${5}" echo "image = /boot/${kernel}" if [ -n "${root_uuid}" ] then echo " #root = ${root_partition}" echo " root = \"${root_uuid}\"" else echo " root = ${root_partition}" fi echo " label = $(lookup_kernel_name ${kernel})" echo " initrd = $(lookup_initrd_name ${kernel})" if [ -n "${vga}" ] then echo " vga = ${vga}" fi if [ -n "${append_args}" ] then echo " append = \"${append_args}\"" fi } #----------------------------------------------------------------------------- # execute lilo command and check result #----------------------------------------------------------------------------- execute_lilo() { if ! /sbin/lilo then mecho mecho --error "Something went wrong!" mecho if [ -f /etc/lilo.conf.OLD ] then mecho --info "Old /etc/lilo.conf was:" mecho "" mecho "$(cat /etc/lilo.conf.OLD)" mecho "" mecho --info "New generated /etc/lilo.conf was:" mecho "" mecho "$(cat /etc/lilo.conf)" mecho "" fi return 1 else if ! "${quiet:-false}" then mecho --warn "" mecho --warn "Note:" mecho --warn "A new /etc/lilo.conf was written containing standard sections" mecho --warn "according to a normal updated eisfair installation." mecho --warn "" mecho --warn "You will find your old boot configuration in /etc/lilo.conf.OLD." mecho --warn "You have to put your own boot options into /etc/lilo.conf manually" mecho --warn "before you reboot." mecho --warn "Do not forget to run 'lilo' on the command line afterwards if you" mecho --warn "changed /etc/lilo.conf!" mecho --warn "" return 0 fi fi } #----------------------------------------------------------------------------- # create config #----------------------------------------------------------------------------- create_config() { # read lilo configuration local max_partitions="$(lookup_value_from_lilo_conf 'max-partitions')" local disk_byid='' local disk_dev='' local boot_byid='' local boot_dev='' local root_uuid='' local root_dev='' local raid_extra_boot="$(lookup_value_from_lilo_conf 'raid-extra-boot')" local vga="$(lookup_value_from_lilo_conf_with_filter 'vga' 'normal')" local menu_scheme="$(lookup_value_from_lilo_conf 'menu-scheme')" local append_args="$(lookup_value_from_lilo_conf 'append')" if [ -z "${menu_scheme}" ] then menu_scheme='wr:bw:wr:Yr' fi if [ -n "${maxpartitions}" ] then # lookup boot disk device disk_dev="$(lookup_device_from_path '/boot')" if [ -z "${disk_dev}" ] then mecho --error "Failed to lookup boot disk device" exit 1 fi # do translation only if physical device is present if is_disk_a_virtual_device "${disk_dev}" || is_disk_a_softraid_device "${disk_dev}" then echo "device ${disk_dev} is not a physical disk," echo "not converting it to /dev/disk/by-id/." disk_byid='' else disk_dev="$(echo ${disk_dev%[1-9]})" disk_dev="$(echo ${disk_dev%[p]})" disk_byid="$(lookup_disk_id_from_list ${disk_dev})" if [ -z "${disk_byid}" ] then mecho --error "Cannot translate disk device ${disk_dev} to /dev/disk/by-id/!" echo print_disk_ids_from_list print_vmware_warning exit 1 fi fi fi # lookup boot device boot_dev="$(lookup_device_from_path '/boot')" if [ -z "${boot_dev}" ] then mecho --error "Failed to lookup block device for boot disk" exit 1 fi # do translation only if physical device is present if is_disk_a_virtual_device "${boot_dev}" || is_disk_a_softraid_device "${boot_dev}" then echo "boot device ${boot_dev} is not a physical disk," echo "not converting it to /dev/disk/by-id/." boot_byid='' else boot_dev="$(echo ${boot_dev%[1-9]})" boot_dev="$(echo ${boot_dev%[p]})" boot_byid="$(lookup_disk_id_from_list ${boot_dev})" if [ -z "${boot_byid}" ] then mecho --error "Cannot translate boot disk device ${boot_dev} to /dev/disk/by-id/!" echo print_disk_ids_from_list print_vmware_warning exit 1 fi fi # lookup root partition root_partition="$(lookup_device_from_path '/')" if [ -z "${root_partition}" ] then mecho --error "Failed to lookup block device for root partition" exit 1 fi root_uuid="$(lookup_volume_uuid_from_list ${root_partition})" if [ -z "${root_uuid}" ] then mecho --error "Cannot translate root disk partition ${root_partition} to /dev/disk/by-uuid/!" echo print_volume_uuids_from_list exit 1 fi # extra processing of values append_args="$(extend_append_args "${append_args}")" kernel_images="$(lookup_kernel_images)" if [ -z "${kernel_images}" ] then mecho --error "No kernel images found!" exit 1 fi # show values if [ "${do_debug}" = "yes" ] then if [ -n "${maxpartitions}" ] then echo -n "disk_byid = "; mecho --info "${disk_byid}" echo -n "disk_dev = "; mecho --info "${disk_dev}" fi echo -n "boot_byid = "; mecho --info "${boot_byid}" echo -n "boot_dev = "; mecho --info "${boot_dev}" echo -n "root_uuid = "; mecho --info "${root_uuid}" echo -n "root_partition = "; mecho --info "${root_partition}" echo -n "append_args = "; mecho --info "${append_args}" echo -n "raid_extra_boot = "; mecho --info "${raid_extra_boot}" echo -n "vga = "; mecho --info "${vga}" echo -n "menu_scheme = "; mecho --info "${menu_scheme}" echo -n "kernel_images = "; mecho --info "${kernel_images}" echo fi # backup old lilo config cp /etc/lilo.conf /etc/lilo.conf.OLD # write new config file { echo "#-----------------------------------------------------------------------------" echo "# /etc/lilo.conf - lilo bootloader configuration" echo "# created: ${EISDATE} ${EISTIME}" echo "#-----------------------------------------------------------------------------" echo echo "lba32" if [ -n "${maxpartitions}" ] then write_disk_section "${disk_byid}" "${disk_dev}" fi write_boot_section "${boot_byid}" "${boot_dev}" "${raid_extra_boot}" echo "read-only" echo "prompt" echo "timeout = 50" echo "vga = normal" echo "menu-scheme = ${menu_scheme}" for kernel in ${kernel_images} do write_kernel_image "${kernel}" \ "${root_uuid}" \ "${root_partition}" \ "${vga}" \ "${append_args}" done } > /etc/lilo.conf if [ ${?} -ne 0 ] then mecho --error "Failed to write to /etc/lilo.conf!" exit 1 fi if ! execute_lilo then # restore original lilo.conf if [ -f /etc/lilo.conf.OLD ] then cp /etc/lilo.conf.OLD /etc/lilo.conf rm -f /etc/lilo.conf.OLD fi exit 1 fi } #----------------------------------------------------------------------------- # main program #----------------------------------------------------------------------------- main() { while [ "${1:0:2}" = "--" ] do case "${1}" in --help) shift show_help exit 0 ;; --generate-new) shift create_config exit 0 ;; --use-existing) shift quiet=true execute_lilo exit 0 ;; *) echo "error: invalid switch \"${1}\"!" >&2 show_help exit 1 ;; esac done # this is only for older kernel that do not use the parameter # and it is depracated! if [ -z "${@}" ] then create_config else show_help exit 0 fi } #----------------------------------------------------------------------------- # call function main #----------------------------------------------------------------------------- main "${@}" #----------------------------------------------------------------------------- # end #-----------------------------------------------------------------------------