3 # Copyright 2013 Intel Corporation
4 # Author: Artem Bityutskiy
7 PROG="setup-gummiboot-conf"
10 srcdir="$(readlink -ev -- ${0%/*})"
11 PATH="/usr/share/setup-ivi:$srcdir:$PATH"
13 . setup-ivi-sh-functions
15 # This is a small trick which I use to make sure my scripts are portable -
16 # check if 'dash' is present, and if yes - use it.
17 if can_switch_to_dash; then
18 exec dash -euf "$srcdir/$PROG" "$@"
22 # Common preparations for all subcommands.
25 verbose "Boot directory is $bootdir"
26 [ -d "$bootdir" ] || \
27 fatal "boot directory path \"$bootdir\" does not exist"
29 # The gummiboot configuration directory
30 conf_dir="$bootdir/loader"
31 # The gummiboot configuration file
32 conf_file="$conf_dir/loader.conf"
33 # The gummiboot kernel entries directory
34 entries_dir="$bootdir/loader/entries"
37 # Get a regular expression for matching gummiboot configuration file option
41 local opt="$(esc_regexp "$1")"
43 opt="$(case_insensitive_regexp "$opt")"
44 printf "%s" "\(^[[:blank:]]*$opt[[:blank:]]\+\)\([^[:blank:]]\+\)\([[:blank:]]*$\)"
47 # Create the default gummiboot configuration file.
48 create_default_conf_file()
50 verbose "creating the default configuration file \"$conf_file\""
52 mkdir -p $verbose "$conf_dir" >&2
53 cat > "$conf_file" <<-EOF
60 # Check wheter the gummiboot configuration file exist, and if not:
61 # o create the default one if --force option was specified
62 # o fail if no --force option was specified
63 check_and_create_default_conf_file()
65 if [ -s "$conf_file" ]; then
69 if [ -n "$force" ]; then
70 create_default_conf_file "$1"
72 fatal "cannot find the gummiboot configuration file" \
73 "(\"$conf_file\") (use -f to create the default" \
79 # -----------------------------------------------------------------------------
80 # The "add" subcommand
81 # -----------------------------------------------------------------------------
87 Usage: $PROG add [options] <entry> <title> <kernel> <options>
89 Add a new gummiboot entry. The mandatory arguments are:
91 <entry> - name of the gummiboot entry to add
92 (<bootdir>/loader/entries/<entry>.conf)
93 <title> - the title of the entry
94 <kernel> - name of the kernel binary to add the entry for
96 <options> - kernel boot options
99 -f, --force if the entry already exists - re-write it, if
100 <bootdir>/loader/loader.conf does not exist - create one,
101 if <bootdir>/<kernel> does not exist - do not fail
102 -h, --help show this text and exit
106 show_add_usage_fail()
108 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
115 if [ "$#" -eq 0 ]; then
121 tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
122 show_add_usage_fail "cannot parse command-line options"
137 *) show_add_usage_fail "unrecognized option \"$1\""
143 if [ "$#" -lt 4 ]; then
144 show_add_usage_fail "too little arguments"
146 if [ "$#" -gt 4 ]; then
147 show_add_usage_fail "too many arguments: \"$1\""
152 local entry="$1"; shift
153 local title="$1"; shift
154 local kernel="$1"; shift
155 local options="$1"; shift
156 local kernel_path="$bootdir/$kernel"
157 local entry_path="$entries_dir/${entry}.conf"
159 verbose "entry is \"$entry\""
160 verbose "title is \"$title\""
161 verbose "kernel is \"$kernel\""
162 verbose "options are \"$options\""
164 if [ -f "$entry_path" ] && [ -z "$force" ]; then
165 fatal "gummiboot entry \"$entry_path\" already exists" \
166 "(use -f to force re-creating it)"
169 if ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
170 fatal "cannot find kernel \"$kernel_path\"" \
171 "(use -f to ignore this error)"
174 # Make sure the gummiboot configuration file exists
175 check_and_create_default_conf_file "$entry"
177 # Find out the kernel version from its name
178 local kernel_version="$(printf "%s" "$kernel" | LC_ALL=C \
179 sed -e 's/[^[:digit:]]\+-\([[:digit:]]\+.*\)/\1/')"
180 [ -n "$kernel_version" ] || \
181 fatal "cannot fetch kernel version from \"$kernel\""
183 # Create the new entry
184 mkdir -p $verbose "$entries_dir" >&2
185 cat > "$entry_path" <<-EOF
188 version $kernel_version
193 if [ -n "$verbose" ]; then
194 verbose "contents of \"$entry_path\":"
195 cat "$entry_path" >&2
200 # -----------------------------------------------------------------------------
201 # The "remove" subcommand
202 # -----------------------------------------------------------------------------
208 Usage: $PROG remove [options] <entry>
210 Delete gummiboot entry <entry> (<bootdir>/loader/entries/<entry>.conf).
213 -f, --force do not fail if the entry doesn't exist
214 -h, --help show this text and exit
218 show_remove_usage_fail()
220 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
221 show_remove_usage >&2
227 if [ "$#" -eq 0 ]; then
233 tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
234 show_remove_usage_fail "cannot parse command-line options"
249 *) show_remove_usage_fail "unrecognized option \"$1\""
255 if [ "$#" -lt 1 ]; then
256 show_remove_usage_fail "too little arguments"
258 if [ "$#" -gt 1 ]; then
259 show_remove_usage_fail "too many arguments: \"$1\""
265 local entry_path="$entries_dir/${entry}.conf"
267 if ! [ -f "$entry_path" ] && [ -z "$force" ]; then
268 fatal "gummiboot entry \"$entry_path\" doesn't exist" \
269 "(use -f to ignore this error)"
272 rm -rf $verbose "$entry_path" >&2
273 verbose "removed $entry_path"
277 # -----------------------------------------------------------------------------
278 # The "default" subcommand
279 # -----------------------------------------------------------------------------
282 # Get the kernel name from a gummiboot entry
283 get_kernel_from_entry()
286 local entry="$entries_dir/$1.conf"
288 if [ -f "$entry" ]; then
289 local regexp="$(get_regexp "efi")"
290 local result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$entry")"
292 if [ -z "$result" ]; then
293 regexp="$(get_regexp "linux")"
294 result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$entry")"
296 [ -n "$result" ] || return 0
300 printf "%s" "${result##*/}"
306 Usage: $PROG default [options] <entry>
308 Set the default boot kernel to <entry>, which is the gummiboot entry name to
309 become the default (without the ".conf" suffix, like in
310 <bootdir>/loader/entries/<entry>.conf). If <entry> is omited, this command
311 prints the currently default entry name.
314 -f, --force if <bootdir>/loader/loader.conf does not exist - create the
315 default one, if <bootdir>/loader/entries/<entry>.conf does not
317 -h, --help show this text and exit
321 show_default_usage_fail()
323 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
324 show_default_usage >&2
331 tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
332 show_default_usage_fail "cannot parse command-line options"
347 *) show_default_usage_fail "unrecognized option \"$1\""
353 if [ "$#" -gt 1 ]; then
354 show_default_usage_fail "too many arguments: \"$1\""
359 local entry="${1:-}";
361 # Make sure the gummiboot configuration file exists
362 check_and_create_default_conf_file "$entry"
364 # Find the current default entry
365 local regexp="$(get_regexp "default")"
366 local default_entry="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$conf_file")"
368 if [ -z "$entry" ]; then
369 printf "%s\n" "entry: $default_entry"
370 printf "%s\n" "kernel: $(get_kernel_from_entry "$default_entry")"
374 local entry_path="$entries_dir/${entry}.conf"
375 if ! [ -f "$entry_path" ] && [ -z "$force" ]; then
376 fatal "cannot find the gummiboot entry \"$entry_path\"" \
377 "(use -f to ignore this error)"
380 if [ -z "$default_entry" ]; then
381 verbose "no default entry found, adding \"$entry\""
382 printf "%s" "default $entry" >> "$conf_file"
386 [ "$(printf "%s\n" "$default_entry" | wc -l)" -eq "1" ] || \
387 fatal "more than one default entry in \"$conf_file\""
389 # Escape special sed characters in "$entry" and replace the old default
390 # entry with the new one
391 local entry_esc="$(esc_sed_replacement "$entry")"
392 LC_ALL=C sed -i -e "s/$regexp/\1$entry_esc\3/" "$conf_file"
394 verbose "set the default boot kernel to \"$entry"\"
398 # -----------------------------------------------------------------------------
404 Usage: $PROG [options] <subcommand> [options] <arguments>
406 This program changes the gummiboot bootloader configuration. Supported
408 add - add a gummiboot entry for a kernel
409 remove - remove a gummiboot entry
410 default - get or set the default gummiboot entry
412 Run "$PROG <subcommand>" to see subcommand-specific help.
415 -b, --bootdir path to the boot directory (default is "/boot")
416 --version show the program version and exit
417 -v, --verbose be verbose
418 -h, --help show this text and exit
424 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
431 while [ -n "${1:-""}" ] && [ -z "${1##-*}" ]; do
435 # If there is no argument or it starts with "-", complain
436 if [ -z "${1:-""}" ] || [ -z "${1##-*}" ]; then
437 fatal "--bootdir requires an argument"
454 *) show_usage_fail "unrecognized option \"$1\""
462 if [ "$#" -eq 0 ]; then
468 subcommand="$1"; shift
470 case "$subcommand" in
476 remove_subcommand "$@"
480 default_subcommand "$@"
483 *) show_usage_fail "unrecognized subcommand \"$subcommand\""