Magellan Linux

Contents of /trunk/grubby/grubby-bls

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3146 - (show annotations) (download)
Tue Jul 7 11:22:01 2020 UTC (3 years, 9 months ago) by niro
File size: 16996 byte(s)
Use ! instead of , as sed delimiter in grubby-bls script
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]}" || "/${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 update_grubcfg
239 }
240
241 add_bls_fragment() {
242 local kernel="$1" && shift
243 local title="$1" && shift
244 local options="$1" && shift
245 local initrd="$1" && shift
246 local extra_initrd="$1" && shift
247
248 if [[ $kernel = *"vmlinuz-"* ]]; then
249 kernelver="${kernel##*/vmlinuz-}"
250 prefix="vmlinuz-"
251 else
252 kernelver="${kernel##*/}"
253 fi
254
255 if [[ ! -f "/boot/${prefix}${kernelver}" ]] &&
256 [[ $bad_image != "true" ]]; then
257 print_error "The ${kernelver} kernel isn't installed in the machine"
258 fi
259
260 if [[ -z $title ]]; then
261 print_error "The kernel title must be specified"
262 fi
263
264 if [[ ! -d $blsdir ]]; then
265 install -m 700 -d "${blsdir}"
266 fi
267
268 bls_target="${blsdir}/${MACHINE_ID}-${kernelver}.conf"
269 kernel_dir="/lib/modules/${kernelver}"
270 if [[ -f "${kernel_dir}/bls.conf" ]]; then
271 cp -aT "${kernel_dir}/bls.conf" "${bls_target}" || exit $?
272 else
273 if [[ -d $kernel_dir ]]; then
274 datetime="$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")"
275 else
276 datetime=0
277 fi
278 mkbls "${kernel}" "${kernelver}" "${datetime}" > "${bls_target}"
279 fi
280
281 if [[ -n $title ]]; then
282 set_bls_value "${bls_target}" "title" "${title}"
283 fi
284
285 if [[ -n $options ]]; then
286 set_bls_value "${bls_target}" "options" "${options}"
287 fi
288
289 if [[ -n $initrd ]]; then
290 set_bls_value "${bls_target}" "initrd" "${initrd}"
291 fi
292
293 if [[ -n $extra_initrd ]]; then
294 append_bls_value "${bls_target}" "initrd" "${extra_initrd}"
295 fi
296
297 if [[ $MAKEDEBUG = "yes" ]]; then
298 arch="$(uname -m)"
299 bls_debug="$(echo ${bls_target} | sed -e "s/\.${arch}/-debug.${arch}/")"
300 cp -aT "${bls_target}" "${bls_debug}"
301 append_bls_value "${bls_debug}" "title" "${LINUX_DEBUG_TITLE_POSTFIX}"
302 append_bls_value "${bls_debug}" "version" "${LINUX_DEBUG_VERSION_POSTFIX}"
303 append_bls_value "${bls_debug}" "options" "${CMDLINE_LINUX_DEBUG}"
304 blsid="$(get_bls_value ${bls_debug} "id" | sed -e "s/\.${arch}/-debug.${arch}/")"
305 set_bls_value "${bls_debug}" "id" "${blsid}"
306 fi
307
308 get_bls_values
309
310 if [[ $make_default = "true" ]]; then
311 set_default_bls "TITLE=${title}"
312 fi
313
314 update_grubcfg
315
316 exit 0
317 }
318
319 update_args() {
320 local args=$1 && shift
321 local remove_args=($1) && shift
322 local add_args=($1) && shift
323
324 for arg in ${remove_args[*]}; do
325 args="$(echo $args | sed -e "s!$arg[^ ]*!!")"
326 done
327
328 for arg in ${add_args[*]}; do
329 if [[ $arg = *"="* ]]; then
330 value=${arg##*=}
331 key=${arg%%=$value}
332 exist=$(echo $args | grep "${key}=")
333 if [[ -n $exist ]]; then
334 args="$(echo $args | sed -e "s!$key=[^ ]*!$key=$value!")"
335 else
336 args="$args $key=$value"
337 fi
338 else
339 exist=$(echo $args | grep $arg)
340 if ! [[ -n $exist ]]; then
341 args="$args $arg"
342 fi
343 fi
344 done
345
346 echo ${args}
347 }
348
349 update_bls_fragment() {
350 local indexes=($(param_to_indexes "$1")) && shift
351 local remove_args=$1 && shift
352 local add_args=$1 && shift
353 local initrd=$1 && shift
354
355 for i in ${indexes[*]}; do
356 if [[ -n $remove_args || -n $add_args ]]; then
357 local new_args="$(update_args "${bls_options[$i]}" "${remove_args}" "${add_args}")"
358 set_bls_value "${bls_file[$i]}" "options" "${new_args}"
359 fi
360
361 if [[ -n $initrd ]]; then
362 set_bls_value "${bls_file[$i]}" "initrd" "${initrd}"
363 fi
364 done
365
366 update_grubcfg
367 }
368
369 set_default_bls() {
370 local index=($(param_to_indexes "$1"))
371
372 if [[ $bootloader = grub2 ]]; then
373 grub2-editenv "${env}" set saved_entry="${bls_title[$index]}"
374 else
375 local default="${bls_version[$index]}"
376 local current="$(grep '^default=' ${zipl_config} | sed -e 's/^default=//')"
377 if [[ -n $current ]]; then
378 sed -i -e "s,^default=.*,default=${default}," "${zipl_config}"
379 else
380 echo "default=${default}" >> "${zipl_config}"
381 fi
382 fi
383 }
384
385 remove_var_prefix() {
386 if [[ -n $remove_kernel && $remove_kernel =~ ^/ ]]; then
387 remove_kernel="/${remove_kernel##*/}"
388 fi
389
390 if [[ -n $initrd ]]; then
391 initrd="/${initrd##*/}"
392 fi
393
394 if [[ -n $extra_initrd ]]; then
395 extra_initrd=" /${extra_initrd##*/}"
396 fi
397
398 if [[ -n $kernel ]]; then
399 kernel="/${kernel##*/}"
400 fi
401
402 if [[ -n $update_kernel && $update_kernel =~ ^/ ]]; then
403 update_kernel="/${update_kernel##*/}"
404 fi
405 }
406
407 update_grubcfg()
408 {
409 if [[ $arch = 'ppc64' || $arch = 'ppc64le' ]]; then
410 grub2-mkconfig -o /boot/grub2/grub.cfg >& /dev/null
411 fi
412 }
413
414 print_usage()
415 {
416 cat <<EOF
417 Usage: grubby [OPTION...]
418 --add-kernel=kernel-path add an entry for the specified kernel
419 --args=args default arguments for the new kernel or new arguments for kernel being updated)
420 --bad-image-okay don't sanity check images in boot entries (for testing only)
421 -c, --config-file=path path to grub config file to update ("-" for stdin)
422 --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
423 first linux entry whose kernel does exist is used as the template
424 --default-kernel display the path of the default kernel
425 --default-index display the index of the default kernel
426 --default-title display the title of the default kernel
427 --env=path path for environment data
428 --grub2 configure grub2 bootloader
429 --info=kernel-path display boot information for specified kernel
430 --initrd=initrd-path initrd image for the new kernel
431 -i, --extra-initrd=initrd-path auxiliary initrd image for things other than the new kernel
432 --make-default make the newly added entry the default boot entry
433 -o, --output-file=path path to output updated config file ("-" for stdout)
434 --remove-args=STRING remove kernel arguments
435 --remove-kernel=kernel-path remove all entries for the specified kernel
436 --set-default=kernel-path make the first entry referencing the specified kernel the default
437 --set-default-index=entry-index make the given entry index the default entry
438 --title=entry-title title to use for the new kernel entry
439 --update-kernel=kernel-path updated information for the specified kernel
440 --zipl configure zipl bootloader
441 -b, --bls-directory path to directory containing the BootLoaderSpec fragment files
442
443 Help options:
444 -?, --help Show this help message
445
446 EOF
447 }
448
449 OPTS="$(getopt -o c:i:o:b:? --long help,add-kernel:,args:,bad-image-okay,\
450 config-file:,copy-default,default-kernel,default-index,default-title,env:,\
451 grub2,info:,initrd:,extra-initrd:,make-default,output-file:,remove-args:,\
452 remove-kernel:,set-default:,set-default-index:,title:,update-kernel:,zipl,\
453 bls-directory:,add-kernel:,add-multiboot:,mbargs:,mounts:,boot-filesystem:,\
454 bootloader-probe,debug,devtree,devtreedir:,elilo,efi,extlinux,grub,lilo,\
455 output-file:,remove-mbargs:,remove-multiboot:,silo,yaboot -n ${SCRIPTNAME} -- "$@")"
456
457 [[ $? = 0 ]] || exit 1
458
459 eval set -- "$OPTS"
460
461 while [ ${#} -gt 0 ]; do
462 case "$1" in
463 --help|-h)
464 print_usage
465 exit 0
466 ;;
467 --add-kernel)
468 kernel="${2}"
469 shift
470 ;;
471 --args)
472 args="${2}"
473 shift
474 ;;
475 --bad-image-okay)
476 bad_image=true
477 ;;
478 --config-file|-c)
479 zipl_config="${2}"
480 shift
481 ;;
482 --copy-default)
483 copy_default=true
484 ;;
485 --default-kernel)
486 display_default="kernel"
487 ;;
488 --default-index)
489 display_default="index"
490 ;;
491 --default-title)
492 display_default="title"
493 ;;
494 --env)
495 env="${2}"
496 shift
497 ;;
498 --grub2)
499 bootloader="grub2"
500 ;;
501 --info)
502 display_info="${2}"
503 shift
504 ;;
505 --initrd)
506 initrd="${2}"
507 shift
508 ;;
509 --extra-initrd|-i)
510 extra_initrd=" /${2}"
511 shift
512 ;;
513 --make-default)
514 make_default=true
515 ;;
516 --output-file|-o)
517 output_file="${2}"
518 shift
519 ;;
520 --remove-args)
521 remove_args="${2}"
522 shift
523 ;;
524 --remove-kernel)
525 remove_kernel="${2}"
526 shift
527 ;;
528 --set-default)
529 set_default="${2}"
530 shift
531 ;;
532 --set-default-index)
533 set_default="${2}"
534 shift
535 ;;
536 --title)
537 title="${2}"
538 shift
539 ;;
540 --update-kernel)
541 update_kernel="${2}"
542 shift
543 ;;
544 --zipl)
545 bootloader="zipl"
546 ;;
547 --bls-directory|-b)
548 blsdir="${2}"
549 shift
550 ;;
551 --add-kernel|--add-multiboot|--mbargs|--mounts|--boot-filesystem|\
552 --bootloader-probe|--debug|--devtree|--devtreedir|--elilo|--efi|\
553 --extlinux|--grub|--lilo|--output-file|--remove-mbargs|--silo|\
554 --remove-multiboot|--slilo|--yaboot)
555 echo
556 echo "${SCRIPTNAME}: the option \"${1}\" was deprecated" >&2
557 echo "Try '${SCRIPTNAME} --help' to list supported options" >&2
558 echo
559 exit 1
560 ;;
561 --)
562 shift
563 break
564 ;;
565 *)
566 echo
567 echo "${SCRIPTNAME}: invalid option \"${1}\"" >&2
568 echo "Try '${SCRIPTNAME} --help' for more information" >&2
569 echo
570 exit 1
571 ;;
572 esac
573 shift
574 done
575
576 if [[ -z $blsdir ]]; then
577 blsdir="/boot/loader/entries"
578 fi
579
580 if [[ -z $env ]]; then
581 env="/boot/grub2/grubenv"
582 fi
583
584 if [[ -z $zipl_config ]]; then
585 zipl_config="/etc/zipl.conf"
586 fi
587
588 get_bls_values
589
590 default_index="$(get_default_index)"
591
592 if [[ -n $display_default ]]; then
593 display_default_value
594 fi
595
596 if [[ -n $display_info ]]; then
597 display_info_values "${display_info}"
598 fi
599
600 if [[ $bootloader = grub2 ]]; then
601 remove_var_prefix
602 fi
603
604 if [[ -n $kernel ]]; then
605 if [[ $copy_default = "true" ]]; then
606 opts="${bls_options[$default_index]}"
607 if [[ -n $args ]]; then
608 opts="${opts} ${args}"
609 fi
610 else
611 opts="${args}"
612 fi
613
614 add_bls_fragment "${kernel}" "${title}" "${opts}" "${initrd}" \
615 "${extra_initrd}"
616 fi
617
618 if [[ -n $remove_kernel ]]; then
619 remove_bls_fragment "${remove_kernel}"
620 fi
621
622 if [[ -n $update_kernel ]]; then
623 update_bls_fragment "${update_kernel}" "${remove_args}" "${args}" "${initrd}"
624 fi
625
626 if [[ -n $set_default ]]; then
627 set_default_bls "${set_default}"
628 fi
629
630 exit 0

Properties

Name Value
svn:executable *