]> git.pld-linux.org Git - packages/efi-boot-update.git/blame - efi-boot-update
--auto cmd-line option and ALLOW_AUTO flag added
[packages/efi-boot-update.git] / efi-boot-update
CommitLineData
7a63766a
JK
1#!/bin/sh
2
3_SCRIPT_NAME=efi-boot-update
7d8cd73a 4_SCRIPT_VERSION=0.1
7a63766a
JK
5
6. /etc/rc.d/init.d/functions
7
8usage () {
9
10 echo "Usage: $0 OPTIONS"
11 echo "Update EFI boot loaders"
12 echo
13 echo " --version Show version number"
14 echo " --help, -h This help message"
15 echo " --mount, -m Try to mount /boot/efi first"
16 echo " --verbose, -v Verbose output"
17 echo " --force Force file updates"
fe76538b 18 echo " --auto Automatic run from packages %post"
7a63766a
JK
19}
20
21msg () {
22 echo "efi-boot-update: $*" >&2
23}
24
25verbose () {
26 if is_yes "$VERBOSE" ; then
27 echo "efi-boot-update: $*" >&2
28 fi
29}
30
31verbose_cmd () {
32 if is_yes "$VERBOSE" ; then
33 echo "+$*" >&2
34 fi
35 "$@"
36}
37
38
39list_remove () {
40
41 for item in $1 ; do
42 if [ "$item" = "$2" ] ; then
43 continue
44 fi
45 echo -n "$item "
46 done
47}
48
49update_file () {
50 local cmd
51 local src
52 local dest
53 while [ -n "$1" ] ; do
54 case $1 in
55 --missingok)
56 shift
57 [ -e "$1" ] || return 0
58 ;;
59 --*)
60 msg "update_file: ignoring unknown option: $1"
61 shift
62 ;;
63 *)
64 break
65 ;;
66 esac
67 done
68 src="$1"; shift
69 dst="$2"; shift
70 if [ -n "$*" ] ; then
71 msg "update_file: unexpected arguments: $*"
72 return 1
73 fi
74 if [ "${dst#/}" = "${dst}" ] ; then
75 # relative path
76 dst="$DESTDIR/$dst"
77 fi
78 if is_yes "$FORCE_UPDATES" ; then
79 is_yes "$VERBOSE" && echo +cp --force --preserve=timestamps "$src" "$dst"
80 cp --force --preserve=timestamps "$src" "$dst"
81 else
82 is_yes "$VERBOSE" && echo +cp --update --preserve=timestamps "$src" "$dst"
83 cp --update --preserve=timestamps "$src" "$dst"
84 fi
85}
86
87get_efibootmgr_opts() {
88 local efi_disk
89 local efi_partnum
90 efi_disk=$(mount | awk '$3=="/boot/efi" {print $1}' 2>/dev/null)
91 EFIBOOTMGR_OPTS="--gpt"
92 if [ -n "$efi_disk" ] ; then
93 efi_partnum="$(echo $efi_disk|sed -e's;^.*[^0-9]\([0-9]\+\)$;\1;')"
94 efi_disk="$(echo $efi_disk|sed -e's;^\(.*\)[0-9]\+$;\1;')"
95 if [ -b "$efi_disk" -a -n "$efi_partnum" ] ; then
96 EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --disk $efi_disk"
97 EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --part $efi_partnum"
98 fi
99 fi
100 echo -n $EFIBOOTMGR_OPTS
101}
102
103find_bootmgr_entry () {
104
105 $EFIBOOTMGR | awk -v find="$1" '
106/^Boot[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\*?/ {
107 sub(/^Boot/,"");
108 sub(/\*/,"");
109 num=$1;
110 $1="";
111 gsub(/^[ \t]+|[ \t]+$/,"");
112 if ($0 == find) print num
113 }'
114}
115
116remove_bootmgr_entry () {
117 local bootnum
118 bootnum=$(find_bootmgr_entry "$1")
119 [ -n "$bootnum" ] || return 0
c1469194 120 verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --delete-bootnum -b "$bootnum"
7a63766a
JK
121 echo -n "$bootnum"
122}
123
124add_bootmgr_entry () {
125 local label=$1
126 local binary=$2
127 local args=$3
128 local bootnum
129 bootnum=$(find_bootmgr_entry "$label")
130
131 if [ "${binary#/}" = "${binary}" ] ; then
132 # relative path
133 binary="$DESTDIR/$binary"
134 fi
135 binary="${binary#/boot/efi}"
136 binary="$(echo -n "$binary"|sed -e's;/;\\;g')"
137
138 if [ -n "$bootnum" ] ; then
139 echo -n "$args" | verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet \
140 --bootnum "$bootnum" --loader "$binary" -@ -
141 else
142 echo -n "$args" | verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --create \
143 --quiet --label "$label" --loader "$binary" -@ -
144 bootnum="$(find_bootmgr_entry "$label")"
145 fi
146 echo -n "$bootnum"
147}
148
fff9d424
JK
149safe_string () {
150 echo -n "$*" | tr -c '[a-zA-Z0-9_]' '_'
151}
152
fe76538b 153ALLOW_AUTO="no"
7a63766a
JK
154FORCE_UPDATES="no"
155MOUNT_EFI_PARTITION="no"
156LABEL_PREFIX=""
7a63766a
JK
157VERBOSE="no"
158
159[ -e /etc/efi-boot/update.conf ] && . /etc/efi-boot/update.conf
160
fe76538b
JK
161AUTO_RUN=no
162
7a63766a
JK
163while [ -n "$*" ] ; do
164 local arg
165 arg="$1"
166 shift
167 case $arg in
168 --help|-h)
169 usage
170 exit 0
171 ;;
172 --version)
173 echo "$_SCRIPT_NAME $_SCRIPT_VERSION"
174 exit 0
175 ;;
176 --mount|-m)
177 MOUNT_EFI_PARTITION=yes
178 ;;
179 --verbose|-v)
180 VERBOSE=yes
181 ;;
182 --force)
183 FORCE_UPDATES="yes"
184 ;;
fe76538b
JK
185 --auto)
186 is_yes "$ALLOW_AUTO" || exit 0
187 AUTO_RUN=yes
188 ;;
7a63766a
JK
189 *)
190 usage >&2
191 exit 2
192 ;;
193 esac
194done
195
196if ! mountpoint -q /boot/efi ; then
197 mkdir -p /boot/efi
198 if is_yes "$MOUNT_EFI_PARTITION" ; then
199 # first try via fstab
200 if ! mount /boot/efi 2>/dev/null ; then
201 local efi_device
202 efi_device="$(/sbin/blkid -o device -l -t PARTUUID="54f69bcc-954d-4f97-8fef-80b359f9e4aa")"
203 if [ -z "$efi_device" ] ; then
204 msg "EFI system partition not found."
205 exit 1
206 fi
207 mount -t vfat "$efi_device" /boot/efi
208 fi
209 fi
210 if ! mountpoint -q /boot/efi ; then
211 msg "EFI system partition not mounted."
212 exit 1
213 fi
214fi
215
216if [ -x /usr/sbin/efibootmgr ] ; then
217 modprobe -q efivars
218 EFIBOOTMGR=/usr/sbin/efibootmgr
219 if ! $EFIBOOTMGR >/dev/null 2>&1 ; then
220 msg "efibootmgr does not work (efivars interface not available?)"
221 msg "won't update boot manager configuration"
222 EFIBOOTMGR=/bin/true
223 else
224 EFIBOOTMGR_OPTS="$(get_efibootmgr_opts)"
225 fi
226else
227 msg "efibootmgr missing, won't update the boot manager configuration"
228 EFIBOOTMGR=/bin/true
229fi
230
7a63766a
JK
231for bootloader_conf in /etc/efi-boot/update.d/*.conf ; do
232 if [ ! -e "$bootloader_conf" ] ; then
233 continue
234 fi
235 ENABLED=yes
236 CONFIG_NAME="$(basename "$bootloader_conf" .conf)"
237 LABEL="$CONFIG_NAME"
238 ARCH="$(uname -m)"
239 BINARY=""
240 ARGS=""
27eab27d
JK
241 install_files() {
242 /bin/true
243 }
7a63766a
JK
244
245 . "$bootloader_conf" || continue
246
247 LABEL="$LABEL_PREFIX$LABEL"
248
249 if ! is_yes "$ENABLED" ; then
07ca222f 250 remove_bootmgr_entry "$LABEL" >/dev/null
7a63766a
JK
251 continue
252 fi
253
5b02c492
JK
254 local efi_arch
255 if [[ "$ARCH" = i?86 || "$ARCH" = pentium[45] || "$ARCH" = "athlon" ]] ; then
256 # %ix86
f8b86fe2 257 efi_arch=ia32
5b02c492
JK
258 elif [[ "$ARCH" = "x86_64" || "$ARCH" = "amd64" || "$ARCH" = "ia32e" ]] ; then
259 # %x8664
260 efi_arch=x64
261 else
262 efi_arch="$ARCH"
263 fi
264 DESTDIR="/boot/efi/EFI/$(echo -n "$PLATFORM_DIR"|sed -e's/@ARCH@/'"$efi_arch"'/')"
7a63766a
JK
265 mkdir -p "$DESTDIR"
266
267 verbose "Updating $LABEL..."
268 install_files
269 if [ -n "$BINARY" ] ; then
270 bootnum="$(add_bootmgr_entry "$LABEL" "$BINARY" "$ARGS")"
fff9d424 271 eval "_$(safe_string ${CONFIG_NAME})_bootnum=\"$bootnum\""
7a63766a
JK
272 fi
273done
274
da8a0db5 275if [ -n "$ORDER" -a "$EFIBOOTMGR" != "/bin/true" ] ; then
7a63766a 276 # set up the configured boot order, not removing any existing entries
da8a0db5 277 tail="$($EFIBOOTMGR | awk '/^BootOrder:/ {gsub(/,/," ",$2); print $2}')"
7a63766a
JK
278 head=""
279 for config_name in $ORDER ; do
fff9d424 280 eval "bootnum=\$_$(safe_string ${config_name})_bootnum"
7a63766a 281 if [ -z "$bootnum" ] ; then
fff9d424 282 verbose "Cannot find '$config_name' config - won't add to boot order."
7a63766a
JK
283 continue
284 fi
285 tail="$(list_remove "$tail" "$bootnum")"
286 head="$head $bootnum"
287 done
288 bootorder="$(echo -n $head $tail | sed -e's/ /,/g')"
289 if [ -n "$bootorder" ] ; then
290 verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --bootorder "$bootorder"
291 fi
292fi
293
fe76538b
JK
294if ! is_yes "$ALLOW_AUTO" && ! is_yes "$AUTO_RUN"; then
295 msg "ALLOW_AUTO is not enabled in /etc/efi-boot/update.conf,"
296 msg "files will not be automatically updated on upgrades."
297fi
298
7a63766a 299# vi: ft=sh sw=4 sts=4 et
This page took 0.176514 seconds and 4 git commands to generate.