Magellan Linux

Contents of /trunk/grubby/grubby-bls

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3142 - (show annotations) (download)
Tue Jul 7 11:15:41 2020 UTC (3 years, 9 months ago) by niro
File size: 16774 byte(s)
Use /boot/loader/entries as BLS directory also on EFI systems
1 #!/bin/bash
2 #
3 # grubby wrapper to manage BootLoaderSpec files
4 #
5 #
6 # Copyright 2018 Red Hat, Inc. All rights reserved.
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 readonly SCRIPTNAME="${0##*/}"
22
23 CMDLINE_LINUX_DEBUG=" systemd.log_level=debug systemd.log_target=kmsg"
24 LINUX_DEBUG_VERSION_POSTFIX="_with_debugging"
25 LINUX_DEBUG_TITLE_POSTFIX=" with debugging"
26
27 declare -a bls_file
28 declare -a bls_title
29 declare -a bls_version
30 declare -a bls_linux
31 declare -a bls_initrd
32 declare -a bls_options
33 declare -a bls_id
34
35 [[ -f /etc/sysconfig/kernel ]] && . /etc/sysconfig/kernel
36 [[ -f /etc/os-release ]] && . /etc/os-release
37 read MACHINE_ID < /etc/machine-id
38 arch=$(uname -m)
39
40 if [[ $arch = 's390' || $arch = 's390x' ]]; then
41 bootloader="zipl"
42 else
43 bootloader="grub2"
44 fi
45
46 print_error() {
47 echo "$1" >&2
48 exit 1
49 }
50
51 if [[ ${#} = 0 ]]; then
52 print_error "no action specified"
53 fi
54
55 get_bls_value() {
56 local bls="$1" && shift
57 local key="$1" && shift
58
59 echo "$(grep "^${key}[ \t]" "${bls}" | sed -e "s,^${key}[ \t]*,,")"
60 }
61
62 set_bls_value() {
63 local bls="$1" && shift
64 local key="$1" && shift
65 local value="$1" && shift
66
67 sed -i -e "s,^${key}.*,${key} ${value}," "${bls}"
68 }
69
70 append_bls_value() {
71 local bls="$1" && shift
72 local key="$1" && shift
73 local value="$1" && shift
74
75 old_value="$(get_bls_value ${bls} ${key})"
76 set_bls_value "${bls}" "${key}" "${old_value}${value}"
77 }
78
79 get_bls_values() {
80 count=0
81 for bls in $(ls -vr ${blsdir}/*.conf 2> /dev/null); do
82 bls_file[$count]="${bls}"
83 bls_title[$count]="$(get_bls_value ${bls} title)"
84 bls_version[$count]="$(get_bls_value ${bls} version)"
85 bls_linux[$count]="$(get_bls_value ${bls} linux)"
86 bls_initrd[$count]="$(get_bls_value ${bls} initrd)"
87 bls_options[$count]="$(get_bls_value ${bls} options)"
88 bls_id[$count]="$(get_bls_value ${bls} id)"
89
90 count=$((count+1))
91 done
92 }
93
94 get_default_index() {
95 local default=""
96 local index="-1"
97 local title=""
98 local version=""
99 if [[ $bootloader = "grub2" ]]; then
100 default="$(grep '^saved_entry=' ${env} | sed -e 's/^saved_entry=//')"
101 else
102 default="$(grep '^default=' ${zipl_config} | sed -e 's/^default=//')"
103 fi
104
105 if [[ -z $default ]]; then
106 index=0
107 elif [[ $default =~ ^[0-9]+$ ]]; then
108 index="$default"
109 fi
110
111 # GRUB2 and zipl use different fields to set the default entry
112 if [[ $bootloader = "grub2" ]]; then
113 title="$default"
114 else
115 version="$default"
116 fi
117
118 for i in ${!bls_file[@]}; do
119 if [[ $title = ${bls_title[$i]} || $version = ${bls_version[$i]} ||
120 $i -eq $index ]]; then
121 echo $i
122 return
123 fi
124 done
125 }
126
127 display_default_value() {
128 case "$display_default" in
129 kernel)
130 echo "${bls_linux[$default_index]}"
131 exit 0
132 ;;
133 index)
134 echo "$default_index"
135 exit 0
136 ;;
137 title)
138 echo "${bls_title[$default_index]}"
139 exit 0
140 ;;
141 esac
142 }
143
144 param_to_indexes() {
145 local param="$1"
146 local indexes=""
147
148 if [[ $param = "ALL" ]]; then
149 for i in ${!bls_file[@]}; do
150 indexes="$indexes $i"
151 done
152 echo -n $indexes
153 return
154 fi
155
156 if [[ $param = "DEFAULT" ]]; then
157 echo -n $default_index
158 return
159 fi
160
161 for i in ${!bls_file[@]}; do
162 if [[ $param = "${bls_linux[$i]}" ]]; then
163 indexes="$indexes $i"
164 fi
165
166 if [[ $param = "TITLE=${bls_title[$i]}" ]]; then
167 indexes="$indexes $i"
168 fi
169
170 if [[ $param = $i ]]; then
171 indexes="$indexes $i"
172 fi
173 done
174
175 if [[ -n $indexes ]]; then
176 echo -n $indexes
177 return
178 fi
179
180 echo -n "-1"
181 }
182
183 display_info_values() {
184 local indexes=($(param_to_indexes "$1"))
185
186 for i in ${indexes[*]}; do
187 echo "index=$i"
188 echo "kernel=${bls_linux[$i]}"
189 echo "args=\"${bls_options[$i]}\""
190 echo "initrd=${bls_initrd[$i]}"
191 echo "title=${bls_title[$i]}"
192 done
193 exit 0
194 }
195
196 mkbls() {
197 local kernel=$1 && shift
198 local kernelver=$1 && shift
199 local datetime=$1 && shift
200
201 local debugname=""
202 local flavor=""
203
204 if [[ $kernelver == *\+* ]] ; then
205 local flavor=-"${kernelver##*+}"
206 if [[ $flavor == "-debug" ]]; then
207 local debugname="with debugging"
208 local debugid="-debug"
209 fi
210 fi
211
212 cat <<EOF
213 title ${NAME} (${kernelver}) ${VERSION}${debugname}
214 version ${kernelver}${debugid}
215 linux ${kernel}
216 initrd /initramfs-${kernelver}.img
217 options \$kernelopts
218 id ${ID}-${datetime}-${kernelver}${debugid}
219 grub_users \$grub_users
220 grub_arg --unrestricted
221 grub_class kernel${flavor}
222 EOF
223 }
224
225 remove_bls_fragment() {
226 local indexes=($(param_to_indexes "$1"))
227
228 if [[ $indexes = "-1" ]]; then
229 print_error "The param $1 is incorrect"
230 fi
231
232 for i in ${indexes[*]}; do
233 rm -f "${bls_file[$i]}"
234 done
235
236 get_bls_values
237 }
238
239 add_bls_fragment() {
240 local kernel="$1" && shift
241 local title="$1" && shift
242 local options="$1" && shift
243 local initrd="$1" && shift
244 local extra_initrd="$1" && shift
245
246 if [[ $kernel = *"vmlinuz-"* ]]; then
247 kernelver="${kernel##*/vmlinuz-}"
248 else
249 kernelver="${kernel##*/}"
250 fi
251
252 if [[ ! -d "/lib/modules/${kernelver}" || ! -f "/boot/vmlinuz-${kernelver}" ]] &&
253 [[ $bad_image != "true" ]]; then
254 print_error "The ${kernelver} kernel isn't installed in the machine"
255 fi
256
257 if [[ -z $title ]]; then
258 print_error "The kernel title must be specified"
259 fi
260
261 if [[ ! -d $blsdir ]]; then
262 install -m 700 -d "${blsdir}"
263 fi
264
265 bls_target="${blsdir}/${MACHINE_ID}-${kernelver}.conf"
266 kernel_dir="/lib/modules/${kernelver}"
267 if [[ -f "${kernel_dir}/bls.conf" ]]; then
268 cp -aT "${kernel_dir}/bls.conf" "${bls_target}" || exit $?
269 else
270 if [[ -d $kernel_dir ]]; then
271 datetime="$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")"
272 else
273 datetime=0
274 fi
275 mkbls "${kernel}" "${kernelver}" "${datetime}" > "${bls_target}"
276 fi
277
278 if [[ -n $title ]]; then
279 set_bls_value "${bls_target}" "title" "${title}"
280 fi
281
282 if [[ -n $options ]]; then
283 set_bls_value "${bls_target}" "options" "${options}"
284 fi
285
286 if [[ -n $initrd ]]; then
287 set_bls_value "${bls_target}" "initrd" "${initrd}"
288 fi
289
290 if [[ -n $extra_initrd ]]; then
291 append_bls_value "${bls_target}" "initrd" "${extra_initrd}"
292 fi
293
294 if [[ $MAKEDEBUG = "yes" ]]; then
295 arch="$(uname -m)"
296 bls_debug="$(echo ${bls_target} | sed -e "s/\.${arch}/-debug.${arch}/")"
297 cp -aT "${bls_target}" "${bls_debug}"
298 append_bls_value "${bls_debug}" "title" "${LINUX_DEBUG_TITLE_POSTFIX}"
299 append_bls_value "${bls_debug}" "version" "${LINUX_DEBUG_VERSION_POSTFIX}"
300 append_bls_value "${bls_debug}" "options" "${CMDLINE_LINUX_DEBUG}"
301 blsid="$(get_bls_value ${bls_debug} "id" | sed -e "s/\.${arch}/-debug.${arch}/")"
302 set_bls_value "${bls_debug}" "id" "${blsid}"
303 fi
304
305 get_bls_values
306
307 if [[ $make_default = "true" ]]; then
308 set_default_bls "TITLE=${title}"
309 fi
310
311 exit 0
312 }
313
314 update_args() {
315 local args=$1 && shift
316 local remove_args=($1) && shift
317 local add_args=($1) && shift
318
319 for arg in ${remove_args[*]}; do
320 args="$(echo $args | sed -e "s,$arg[^ ]*,,")"
321 done
322
323 for arg in ${add_args[*]}; do
324 if [[ $arg = *"="* ]]; then
325 value=${arg##*=}
326 key=${arg%%=$value}
327 exist=$(echo $args | grep "${key}=")
328 if [[ -n $exist ]]; then
329 args="$(echo $args | sed -e "s,$key=[^ ]*,$key=$value,")"
330 else
331 args="$args $key=$value"
332 fi
333 else
334 exist=$(echo $args | grep $arg)
335 if ! [[ -n $exist ]]; then
336 args="$args $arg"
337 fi
338 fi
339 done
340
341 echo ${args}
342 }
343
344 update_bls_fragment() {
345 local indexes=($(param_to_indexes "$1")) && shift
346 local remove_args=$1 && shift
347 local add_args=$1 && shift
348 local initrd=$1 && shift
349
350 for i in ${indexes[*]}; do
351 if [[ -n $remove_args || -n $add_args ]]; then
352 local new_args="$(update_args "${bls_options[$i]}" "${remove_args}" "${add_args}")"
353 set_bls_value "${bls_file[$i]}" "options" "${new_args}"
354 fi
355
356 if [[ -n $initrd ]]; then
357 set_bls_value "${bls_file[$i]}" "initrd" "${initrd}"
358 fi
359 done
360 }
361
362 set_default_bls() {
363 local index=($(param_to_indexes "$1"))
364
365 if [[ $bootloader = grub2 ]]; then
366 grub2-editenv "${env}" set saved_entry="${bls_title[$index]}"
367 else
368 local default="${bls_version[$index]}"
369 local current="$(grep '^default=' ${zipl_config} | sed -e 's/^default=//')"
370 if [[ -n $current ]]; then
371 sed -i -e "s,^default=.*,default=${default}," "${zipl_config}"
372 else
373 echo "default=${default}" >> "${zipl_config}"
374 fi
375 fi
376 }
377
378 remove_var_prefix() {
379 if [[ -n $remove_kernel && $remove_kernel =~ ^/ ]]; then
380 remove_kernel="/${remove_kernel##*/}"
381 fi
382
383 if [[ -n $initrd ]]; then
384 initrd="/${initrd##*/}"
385 fi
386
387 if [[ -n $extra_initrd ]]; then
388 extra_initrd=" /${extra_initrd##*/}"
389 fi
390
391 if [[ -n $kernel ]]; then
392 kernel="/${kernel##*/}"
393 fi
394
395 if [[ -n $update_kernel && $update_kernel =~ ^/ ]]; then
396 update_kernel="/${update_kernel##*/}"
397 fi
398 }
399
400 print_usage()
401 {
402 cat <<EOF
403 Usage: grubby [OPTION...]
404 --add-kernel=kernel-path add an entry for the specified kernel
405 --args=args default arguments for the new kernel or new arguments for kernel being updated)
406 --bad-image-okay don't sanity check images in boot entries (for testing only)
407 -c, --config-file=path path to grub config file to update ("-" for stdin)
408 --copy-default use the default boot entry as a template for the new entry being added; if the default is not a linux image, or if the kernel referenced by the default image does not exist, the
409 first linux entry whose kernel does exist is used as the template
410 --default-kernel display the path of the default kernel
411 --default-index display the index of the default kernel
412 --default-title display the title of the default kernel
413 --env=path path for environment data
414 --grub2 configure grub2 bootloader
415 --info=kernel-path display boot information for specified kernel
416 --initrd=initrd-path initrd image for the new kernel
417 -i, --extra-initrd=initrd-path auxiliary initrd image for things other than the new kernel
418 --make-default make the newly added entry the default boot entry
419 -o, --output-file=path path to output updated config file ("-" for stdout)
420 --remove-args=STRING remove kernel arguments
421 --remove-kernel=kernel-path remove all entries for the specified kernel
422 --set-default=kernel-path make the first entry referencing the specified kernel the default
423 --set-default-index=entry-index make the given entry index the default entry
424 --title=entry-title title to use for the new kernel entry
425 --update-kernel=kernel-path updated information for the specified kernel
426 --zipl configure zipl bootloader
427 -b, --bls-directory path to directory containing the BootLoaderSpec fragment files
428
429 Help options:
430 -?, --help Show this help message
431
432 EOF
433 }
434
435 OPTS="$(getopt -o c:i:o:b:? --long help,add-kernel:,args:,bad-image-okay,\
436 config-file:,copy-default,default-kernel,default-index,default-title,env:,\
437 grub2,info:,initrd:,extra-initrd:,make-default,output-file:,remove-args:,\
438 remove-kernel:,set-default:,set-default-index:,title:,update-kernel:,zipl,\
439 bls-directory:,add-kernel:,add-multiboot:,mbargs:,mounts:,boot-filesystem:,\
440 bootloader-probe,debug,devtree,devtreedir:,elilo,efi,extlinux,grub,lilo,\
441 output-file:,remove-mbargs:,remove-multiboot:,silo,yaboot -n ${SCRIPTNAME} -- "$@")"
442
443 [[ $? = 0 ]] || exit 1
444
445 eval set -- "$OPTS"
446
447 while [ ${#} -gt 0 ]; do
448 case "$1" in
449 --help|-h)
450 print_usage
451 exit 0
452 ;;
453 --add-kernel)
454 kernel="${2}"
455 shift
456 ;;
457 --args)
458 args="${2}"
459 shift
460 ;;
461 --bad-image-okay)
462 bad_image=true
463 ;;
464 --config-file|-c)
465 zipl_config="${2}"
466 shift
467 ;;
468 --copy-default)
469 copy_default=true
470 ;;
471 --default-kernel)
472 display_default="kernel"
473 ;;
474 --default-index)
475 display_default="index"
476 ;;
477 --default-title)
478 display_default="title"
479 ;;
480 --env)
481 env="${2}"
482 shift
483 ;;
484 --grub2)
485 bootloader="grub2"
486 ;;
487 --info)
488 display_info="${2}"
489 shift
490 ;;
491 --initrd)
492 initrd="${2}"
493 shift
494 ;;
495 --extra-initrd|-i)
496 extra_initrd=" /${2}"
497 shift
498 ;;
499 --make-default)
500 make_default=true
501 ;;
502 --output-file|-o)
503 output_file="${2}"
504 shift
505 ;;
506 --remove-args)
507 remove_args="${2}"
508 shift
509 ;;
510 --remove-kernel)
511 remove_kernel="${2}"
512 shift
513 ;;
514 --set-default)
515 set_default="${2}"
516 shift
517 ;;
518 --set-default-index)
519 set_default="${2}"
520 shift
521 ;;
522 --title)
523 title="${2}"
524 shift
525 ;;
526 --update-kernel)
527 update_kernel="${2}"
528 shift
529 ;;
530 --zipl)
531 bootloader="zipl"
532 ;;
533 --bls-directory|-b)
534 blsdir="${2}"
535 shift
536 ;;
537 --add-kernel|--add-multiboot|--mbargs|--mounts|--boot-filesystem|\
538 --bootloader-probe|--debug|--devtree|--devtreedir|--elilo|--efi|\
539 --extlinux|--grub|--lilo|--output-file|--remove-mbargs|--silo|\
540 --remove-multiboot|--slilo|--yaboot)
541 echo
542 echo "${SCRIPTNAME}: the option \"${1}\" was deprecated" >&2
543 echo "Try '${SCRIPTNAME} --help' to list supported options" >&2
544 echo
545 exit 1
546 ;;
547 --)
548 shift
549 break
550 ;;
551 *)
552 echo
553 echo "${SCRIPTNAME}: invalid option \"${1}\"" >&2
554 echo "Try '${SCRIPTNAME} --help' for more information" >&2
555 echo
556 exit 1
557 ;;
558 esac
559 shift
560 done
561
562 if [[ -z $blsdir ]]; then
563 blsdir="/boot/loader/entries"
564 fi
565
566 if [[ -z $env ]]; then
567 env="/boot/grub2/grubenv"
568 fi
569
570 if [[ -z $zipl_config ]]; then
571 zipl_config="/etc/zipl.conf"
572 fi
573
574 get_bls_values
575
576 default_index="$(get_default_index)"
577
578 if [[ -n $display_default ]]; then
579 display_default_value
580 fi
581
582 if [[ -n $display_info ]]; then
583 display_info_values "${display_info}"
584 fi
585
586 if [[ $bootloader = grub2 ]]; then
587 remove_var_prefix
588 fi
589
590 if [[ -n $kernel ]]; then
591 if [[ $copy_default = "true" ]]; then
592 opts="${bls_options[$default_index]}"
593 if [[ -n $args ]]; then
594 opts="${opts} ${args}"
595 fi
596 else
597 opts="${args}"
598 fi
599
600 add_bls_fragment "${kernel}" "${title}" "${opts}" "${initrd}" \
601 "${extra_initrd}"
602 fi
603
604 if [[ -n $remove_kernel ]]; then
605 remove_bls_fragment "${remove_kernel}"
606 fi
607
608 if [[ -n $update_kernel ]]; then
609 update_bls_fragment "${update_kernel}" "${remove_args}" "${args}" "${initrd}"
610 fi
611
612 if [[ -n $set_default ]]; then
613 set_default_bls "${set_default}"
614 fi
615
616 exit 0

Properties

Name Value
svn:executable *