Skip to content

Commit b0dc2a8

Browse files
committed
Add service to ensure systemd-boot installed
On systemd-boot systems, the bootloader is updated with `bootctl update` on every boot. Unfortunately, it doesn't currently work because `bootctl` considers systemd-boot to be installed if `/EFI/systemd` is non-empty in the ESP. The image builder only populates `/EFI/BOOT`, so systemd-boot is not considered installed. If `bootctl` does not consider systemd-boot to be installed, `eos-ensure-sd-boot` will check the `LoaderInfo` EFI variable to see if the current bootloader is systemd-boot. If so, it runs `bootctl install` so that the next time `bootctl update` runs, it will update the bootloader. https://phabricator.endlessm.com/T34703
1 parent b27e2f3 commit b0dc2a8

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \
2020
dist_systemdunit_DATA = \
2121
eos-config-journal.service \
2222
eos-enable-zram.service \
23+
eos-ensure-sd-boot.service \
2324
eos-firewall-localonly.service \
2425
eos-firstboot.service \
2526
eos-image-boot-dm-setup.service \
@@ -87,6 +88,7 @@ dist_polkitrules_DATA = \
8788
dist_sbin_SCRIPTS = \
8889
eos-config-journal \
8990
eos-enable-zram \
91+
eos-ensure-sd-boot \
9092
eos-firewall-localonly \
9193
eos-firstboot \
9294
eos-image-boot-dm-setup \

eos-ensure-sd-boot

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
3+
# eos-ensure-sd-boot: Ensure systemd-boot is installed
4+
#
5+
# Copyright © 2023 Endless OS Foundation LLC
6+
#
7+
# This program is free software; you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation; either version 2 of the License, or (at
10+
# your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful, but
13+
# WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
# General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with this program; if not, write to the Free Software
19+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20+
# 02110-1301, USA.
21+
22+
# Ensure systemd-boot is considered installed by bootctl (when
23+
# appropriate) so that bootctl update works.
24+
25+
set -e
26+
set -o pipefail
27+
28+
LOADER_INFO_VAR=LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
29+
LOADER_INFO_PATH="/sys/firmware/efi/efivars/$LOADER_INFO_VAR"
30+
31+
# Read the LoaderInfo EFI variable.
32+
get_loader_info() {
33+
[ -f "$LOADER_INFO_PATH" ] || return 0
34+
35+
# The LoaderInfo variable is a NUL terminated UTF-16 string. The
36+
# first 4 bytes of any EFI variable are attributes.
37+
dd if="$LOADER_INFO_PATH" ibs=1 skip=4 status=none \
38+
| iconv -f UTF16LE | tr -d '\0'
39+
}
40+
41+
# We only use systemd-boot on x86_64. If we add any other architectures
42+
# later, they'll install it correctly out of the box.
43+
arch=$(uname -m)
44+
if [ "$arch" != x86_64 ]; then
45+
exit 0
46+
fi
47+
48+
# If it's already considered installed, there's nothing to do.
49+
if bootctl --quiet is-installed; then
50+
exit 0
51+
fi
52+
53+
# Only make changes when the boot loader is systemd-boot.
54+
echo "Reading $LOADER_INFO_VAR EFI variable"
55+
loader_info=$(get_loader_info)
56+
if ! [[ $loader_info =~ ^systemd-boot ]]; then
57+
echo "Boot loader is not systemd-boot"
58+
exit 0
59+
fi
60+
61+
# Install systemd-boot but don't touch the EFI Boot* variables since we
62+
# assume those are already working.
63+
echo "Installing systemd-boot"
64+
bootctl --no-variables install
65+
66+
# Validate that systemd-boot is now considered installed.
67+
if ! bootctl --quiet is-installed; then
68+
echo "bootctl does not consider systemd-boot installed" >&2
69+
exit 1
70+
fi

eos-ensure-sd-boot.service

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[Unit]
2+
Description=Ensure systemd-boot is installed
3+
DefaultDependencies=no
4+
Conflicts=shutdown.target
5+
Wants=local-fs.target
6+
After=local-fs.target
7+
Before=sysinit.target
8+
9+
# Run before systemd-boot-update so that it doesn't run concurrently.
10+
Before=systemd-boot-update.service
11+
12+
# Only run on x86_64 UEFI as that's the only platform where systemd-boot
13+
# is used. Any other platforms added later will install systemd-boot
14+
# correctly out of the box.
15+
ConditionArchitecture=x86-64
16+
ConditionFirmware=uefi
17+
18+
[Service]
19+
Type=oneshot
20+
RemainAfterExit=yes
21+
ExecStart=/usr/sbin/eos-ensure-sd-boot
22+
23+
[Install]
24+
WantedBy=sysinit.target

0 commit comments

Comments
 (0)