#!/bin/sh -eu . shell-error . shell-getopt . shell-var BOOTDEVICE= ROOTDIR= ADD_KERNELS='yes' KERNELS_GROUP='Details Menu' TEST= show_help() { cat <<-EOF Usage: $PROG [options] [extlinux options] [Options] -b, --boot=DEVICE specify the boot device; -r, --root=DIR use the system rooted at DIR; -d, --dry-run show what will be done and exit; -v, --verbose print a message for each action; -V, --version print program version and exit; -h, --help show this text and exit. Report bugs to authors. EOF exit } print_version() { cat <<-EOF $PROG version 2.0 Written by Alexey Gladkov. Copyright (C) 2010-2012 Alexey Gladkov This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. EOF exit } GETOPT_ALLOW_UNKNOWN=1 TEMP=`getopt -n $PROG -o b:,d,r:,v,V,h -l boot:,dry-run,root:,verbose,version,help -- "$@"` || show_help eval set -- "$TEMP" while :; do case "$1" in -b|--boot) shift BOOTDEVICE="$1" ;; -r|--root) shift ROOTDIR="${1%/}" ;; -d|--dry-run) TEST=message verbose=-v ;; -v|--verbose) verbose=-v ;; -V|--version) show_version ;; -h|--help) show_help ;; --) shift; break ;; esac shift done . "$ROOTDIR"/etc/sysconfig/extlinux boot_majmin="$(mountpoint -d "$ROOTDIR/boot")" ||: root_majmin="$(mountpoint -d "$ROOTDIR/")" ||: [ "$boot_majmin" = "$root_majmin" -o -L "$ROOTDIR/boot/boot" ] || fatal "$ROOTDIR/boot a separate partition, but there's no '/boot/boot' symlink" sysfs_path="$(readlink -ev "/sys/dev/block/$boot_majmin" 2>/dev/null)" || fatal "Unable to get sysfs path" [ -f "$sysfs_path/partition" ] || fatal "Boot device must be partition" read partition < "$sysfs_path/partition" dev="$(sed -n -e 's,^DEVNAME=,/dev/,p' "${sysfs_path%/*}/uevent")" partition_table="$(LANG=C parted -ms "$dev" print | grep ^/ |cut -d: -f6)" verbose "Partition table: $partition_table" case "$partition_table" in gpt) mbr_bin='gptmbr.bin' flag='legacy_boot' ;; msdos) mbr_bin='mbr.bin' flag='boot' ;; *) fatal "Unknown partition table: $partition_table" ;; esac bootflags="$(LANG=C parted -ms "$dev" print | grep "^$partition:" |cut -d: -f7)" [ -z "${bootflags##*$flag*}" ] || fatal "partiton not bootable" DEVNAME= dir="$(readlink -m "$ROOTDIR/")" while read dev mpoint dummy; do [ "$mpoint" = "$dir" -a "$dev" != 'rootfs' ] || continue DEVNAME="$dev" break done < /proc/mounts [ -n "$DEVNAME" ] || fatal "Unable to get device info '$ROOTDIR/'" UUID="$(blkid -o value -s UUID -c /dev/null "$DEVNAME")" cd "$ROOTDIR/boot/extlinux" if [ -z "$TEST" ]; then verbose "Replace 'root=@ROOTDEV@' by 'root=UUID=$UUID'" for f in extlinux.conf extlinux.conf.d/*.conf; do [ ! -f "$f" ] || sed -i -e "s#@ROOTDEV@#UUID=$UUID#ig" "$f" done fi rm $verbose -f -- extlinux.conf.d/kernels.conf if shell_var_is_yes "$ADD_KERNELS"; then verbose "Creating new extlinux.conf.d/kernels.conf ..." printf '# Generated by %s. Do not edit manually.\n' "$PROG" \ > extlinux.conf.d/kernels.conf if [ -n "$KERNELS_GROUP" ]; then cat >> extlinux.conf.d/kernels.conf <<-EOF MENU BEGIN MENU TITLE $KERNELS_GROUP EOF fi for f in "$ROOTDIR"/boot/vmlinuz*; do [ -f "$f" ] || continue vmlinuz="${f##*/}" version="${vmlinuz#vmlinuz}" initrd="initrd$version.img" [ -f "$ROOTDIR/boot/$initrd" ] || initrd= [ -n "$version" ] && label="Kernel ${version:+(${version#-})}" || label='Kernel image' cat <<-EOF LABEL ${vmlinuz##*/} MENU LABEL $label LINUX /boot/$vmlinuz${initrd:+ INITRD /boot/$initrd}${APPEND:+ APPEND $APPEND} EOF done >> extlinux.conf.d/kernels.conf if [ -n "$KERNELS_GROUP" ]; then cat >> extlinux.conf.d/kernels.conf <<-EOF MENU SEPARATOR LABEL return_main MENU LABEL ^Return to main Menu MENU EXIT MENU END EOF fi fi verbose "Creating new extlinux.conf.d/.index.conf ..." printf '# Generated by %s. Do not edit manually.\n' "$PROG" \ > extlinux.conf.d/.index.conf def_label= for f in extlinux.conf.d/*.conf; do [ -f "$f" ] || continue if [ -z "$def_label" ]; then while read name value; do case "$name" in [Ll][Aa][Bb][Ee][Ll]) def_label="$value" break ;; esac done < "$f" printf 'DEFAULT %s\n' "$def_label" fi printf 'INCLUDE %s\n' "$f" done >> extlinux.conf.d/.index.conf mode='install' if [ -b "$BOOTDEVICE" ]; then ldr="$(sha1sum < "$mbr_bin")" siz="$(stat -c '%s' "$mbr_bin")" mbr="$(dd ibs="$siz" count=1 if="$BOOTDEVICE" 2>/dev/null |sha1sum)" [ "$mbr" != "$ldr" ] || mode='update' verbose "Using $mode mode" fi if [ "$mode" = 'install' ]; then if [ -b "$BOOTDEVICE" ]; then verbose "installing master boot record: $BOOTDEVICE" $TEST dd if="$mbr_bin" of="$BOOTDEVICE" else message "WARNING: MBR not installed. BOOTDEVICE not specified." fi fi $TEST extlinux --$mode "$PWD" "$@"