Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 171 lines (141 sloc) 4.172 kB
#!/bin/bash
#
# kload - a syslinux.cfg parser for autoloading a kernel for kexec
#
bootloadercfg=/boot/syslinux/syslinux.cfg
error() {
local mesg=$1; shift
printf "==> ERROR: $mesg\n" "$@"
} >&2
die() {
error "$@"
exit 1
}
usage() {
cat <<EOF
usage: ${0##*/} <label> [rootoptions]
${0##*/} parses syslinux's bootloader configuration and automates the process
of loading a new kernel for kexec. If specified, any root options will override
the APPEND line of the config for a given kernel.
Options:
-a <append> add additional parameters to new kernel's cmdline
-f <file> use another config file (default: /boot/syslinux/syslinux.cfg)
-h display this help message.
-l display available kernels by label
EOF
exit 1
}
parse_config() {
awk -v action="$1" -v arg="$2" '
function longest(list, listlen,i, len, maxlen) {
maxlen = 0
listlen = length(list)
for(i in list) {
len = length(i)
if (len > maxlen) {
maxlen = len
}
}
return maxlen
}
function add_label(config, label, kernel, append, initrd) {
if (label && kernel && append) {
config[label] = kernel SUBSEP append SUBSEP initrd
}
}
function print_human(config, opts, len, label) {
if (length(config) == 0) {
print "==> ERROR: No kernel entries found in", FILENAME > "/dev/stderr"
return
}
len = longest(config)
printf "%-*s\t%s\n", len, "label", "kernel image [initrd]"
printf "%-*s\t%s\n", len, "", "options"
print "-------------------------------------------------------------"
for (label in config) {
if (config[label]) {
# opts[label] = <kernel> <append> [initrd]
split(config[label], opts, SUBSEP)
printf "%-*s\t%s", len, label, opts[1]
if(opts[3]) {
printf " [%s]", opts[3]
}
printf "\n%*s\t%s\n", len, "", opts[2]
}
}
}
function print_nullsep(config, label, opts) {
if (config[label]) {
split(config[label], opts, SUBSEP)
printf "%s\0%s\0%s\0", opts[1], opts[2], opts[3]
}
}
$1 == "LABEL" {
add_label(config, label, kernel, append, initrd)
label = $2
kernel = append = initrd = ""
}
label && $1 ~ /^(LINUX|KERNEL)$/ {
sub(/^[[:blank:]]*(LINUX|KERNEL) /, "")
kernel = $0
}
label && $1 == "APPEND" {
sub(/^[[:blank:]]*APPEND /, "")
gsub(/[[:blank:]]+/, " ")
append = append ? append " " $0 : $0
}
label && $1 == "INITRD" {
sub(/^[[:blank:]]*[^[:blank:]]+ /, "")
initrd = $0
}
END {
# if theres no line after the last section, we wont add the label
add_label(config, label, kernel, append, initrd)
if (action == "list") {
print_human(config)
} else if (action == "parse_one") {
print_nullsep(config, arg)
}
}
' "$bootloadercfg"
exit 0
}
runcmd() {
printf 'executing: %s\n' "$*"
if (( needsroot )); then
if sudo -v &>/dev/null && sudo -l &>/dev/null; then
sudo "$@"
else
printf '%s ' 'root'
su -c "$(printf '%q ' "$@")"
fi
else
"$@"
fi
}
# main()
while getopts ":a:f:hl" flag; do
case $flag in
a) optappend=$OPTARG ;;
f) bootloadercfg=$OPTARG ;;
h) usage ;;
l) list=1 ;;
:) die "option '-%s' requires an argument" "$OPTARG" ;;
?) die "invalid option -- '%s'" "$OPTARG" ;;
esac
done
shift $(( OPTIND - 1 ))
[[ -f $bootloadercfg ]] || die "unable to find bootloader config: %s" "$bootloadercfg"
(( list )) && { parse_config 'list'; exit 0; }
label=$1; shift
[[ $label ]] || die "no label specified (use -h for help)"
(( UID == 0 )) || needsroot=1
{
IFS= read -rd '' kernel
IFS= read -rd '' append
IFS= read -rd '' initrd
} < <(parse_config 'parse_one' "$label")
[[ -z $kernel || -z $append ]] && die "failed to find label \`%s'" "$label"
kexec_cmd=(kexec -l "/boot/${kernel##*/}" --append="${*:-$append} $optappend")
[[ $initrd ]] && kexec_cmd+=(--initrd="/boot/${initrd##*/}")
runcmd "${kexec_cmd[@]}"
Jump to Line
Something went wrong with that request. Please try again.