coreos / bootupd Goto Github PK
View Code? Open in Web Editor NEWBootloader updater
License: Apache License 2.0
Bootloader updater
License: Apache License 2.0
Today we have a singular /boot/bootupd-state.json
. It seems better to at least also store state alongside its content, so we'd have e.g. /boot/efi/EFI/bootupd.json
as well as serializing a bit of our metadata into the BIOS partition, etc.
This would allow us to better detect situations where e.g. we happen to find an ESP from a different drive than the one holding /boot
. The additional storage cost here would be minimal.
Raspberry Pi requires a bunch of files to be available in the root of the ESP partition (traditionally mounted as /boot/efi
on Fedora) in order to boot. In the case of Fedora, this means the firmware, uboot, device trees and probably more. This is the content of /boot/efi
on Fedora Server for aarch64:
$ ls /boot/efi
bcm2710-rpi-2-b.dtb* bcm2710-rpi-cm3.dtb* bcm2711-rpi-400.dtb* bcm2711-rpi-cm4-io.dtb* bcm2712-rpi-5-b.dtb* bootcode.bin* fixup4cd.dat* fixup4x.dat* fixup_db.dat* rpi-u-boot.bin* start4.elf* start_db.elf*
bcm2710-rpi-3-b.dtb* bcm2710-rpi-zero-2.dtb* bcm2711-rpi-4-b.dtb* bcm2711-rpi-cm4s.dtb* bcm2712-rpi-cm5-cm4io.dtb* config.txt* fixup4.dat* fixup_cd.dat* fixup_x.dat* start4cd.elf* start4x.elf* start.elf*
bcm2710-rpi-3-b-plus.dtb* bcm2710-rpi-zero-2-w.dtb* bcm2711-rpi-cm4.dtb* bcm2712d0-rpi-5-b.dtb* bcm2712-rpi-cm5-cm5io.dtb* EFI/ fixup4db.dat* fixup.dat* overlays/ start4db.elf* start_cd.elf* start_x.elf*
However, bootupd
currently only manages the /boot/efi/EFI
directory, so there's no way to put these files under /boot/efi
without any kind of post-processing run after bootupd backend install
.
It would be nice if we could get another piece of information when running an update. Right now:
[core@dustymabe ~]$ sudo bootupctl update
Updated EFI: grub2-efi-aa64-1:2.06-88.fc37.aarch64,shim-aa64-15.6-2.aarch64
It would be nice when looking at issues later to also know what version the update started at.. i.e. something like:
[core@dustymabe ~]$ sudo bootupctl update
Initial Installed: grub2-efi-aa64-1:2.06-2.fc34.aarch64,shim-aa64-15.4-4.aarch64
Updated EFI: grub2-efi-aa64-1:2.06-88.fc37.aarch64,shim-aa64-15.6-2.aarch64
Say e.g. I have a SeaBIOS or whatever… there likely still needs support by the vendor for the upgrade to work?
As with fwupd/LVFS there is a big documentation on all that stuff: https://fwupd.org/lvfs/docs/vendors
Here I see none of that. I mean if it is just a client… okay, but then link to the server component or so? Or spec?
After all, without having actual update files/upgrades from the vendors the whole project is kinda not… working… (I don’t dare to say useless), because well… you cannot upgrade anything without updates.
If something like this would be documented, one could go to some vendor and say “Hey, there is this cool project called bootupd for updating your BIOS, don’t you want to support it too?” and in an ideal world, they’d say “Of course, we'll add that right away!”.
ANyway, one could and probably should try, especially when a vendor explicitly supports Linux.
On a fresh Fedora Silverblue Rawhide installation:
root@fedora:~# bootupctl status
Running as unit: bootupd.service
This is likely due to something we missed in #663.
We should likely call systemd-run
with --pty
or --pipe
: https://www.freedesktop.org/software/systemd/man/latest/systemd-run.html#--pty
e2e-update.sh
is failing:
[2022-05-11T01:14:00.815Z] + env COSA_DIR=/home/jenkins/agent/workspace/bootupd_PR-332 ./tests/e2e-update/e2e-update.sh
[2022-05-11T01:14:00.815Z] fatal: unsafe repository ('/home/jenkins/agent/workspace/bootupd_PR-332' is owned by someone else)
[2022-05-11T01:14:00.815Z] To add an exception for this directory, call:
[2022-05-11T01:14:00.815Z]
[2022-05-11T01:14:00.815Z] git config --global --add safe.directory /home/jenkins/agent/workspace/bootupd_PR-332
script returned exit code 128
From discussion on fedora-devel list; we should definitely use systemd inhibitors when we're in the process of doing an update.
When build image, we install bootloader for uefi firmware when running bootupctl backend install
(see https://github.com/coreos/coreos-assembler/blob/main/src/create_disk.sh#L407), for BIOS/PReP bootloader will call grub2-install
(from cosa container). This is not consistent and convenient.
What we want to do is add an option (for example -bios, or -noefi, etc) to cover BIOS/PReP firmware if run bootupctl backend install
. See related issue coreos/coreos-assembler#3156
See rhinstaller/anaconda#5508 (comment) and previous
Basically during an installation process we should really fix things so that we find the EFI vendor for the shim/grub we're going to install (from /usr/lib/bootupd/updates/EFI
), verify its presence in the real ESP, and then target that.
I think it's a useful exercise to early on flesh out what the UX will look like. Let's discuss that here and then add something in the README?
Some bootstrapping questions:
rpm-ostree status
on rpm-ostree-based systems?We don't need to answer everything completely, but discussing these will make it easier to think about how bootupd fits in.
The current released bootupd is a little bit old. It results the following issue on aarch64 EFI machine. The HD(1,GPT,0d31c6ab-e0cb-40d1-bd9a-047b6c62203c,0x800,0x32000)/\EFI\fedora\shimx64.efi
does not make sense.
Running bootupctl to install bootloader
BootCurrent: 0001
Timeout: 0 seconds
BootOrder: 0001,0004,0000
Boot0000* EFI Network AcpiEx(VMBus,,)/VenHw(9b17e5a2-0891-42dd-b653-80b5c22809ba,635161f83edfc546913ff2d2f965ed0e17521e7c5a411e7c5217415a7c1e5217)/MAC(000000000000,0)/IPv4(0.0.0.0,0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)
Boot0002* EFI SCSI Device AcpiEx(VMBus,,)/VenHw(9b17e5a2-0891-42dd-b653-80b5c22809ba,d96361baa104294db60572e2ffb1dc7f1a78b3f8821e1848a1c363d806ec15bb)/SCSI(0,1)
Boot0003* EFI SCSI Device AcpiEx(VMBus,,)/VenHw(9b17e5a2-0891-42dd-b653-80b5c22809ba,d96361baa104294db60572e2ffb1dc7f1a78b3f8821e1848a1c363d806ec15bb)/SCSI(0,2)
Boot0004* Fedora HD(1,GPT,0d31c6ab-e0cb-40d1-bd9a-047b6c62203c,0x800,0x32000)/\EFI\fedora\shimaa64.efi
Boot0001* fedora HD(1,GPT,0d31c6ab-e0cb-40d1-bd9a-047b6c62203c,0x800,0x32000)/\EFI\fedora\shimx64.efi
Installed: grub.cfg
Installed: "fedora/grub.cfg"
Installation complete!
The main
fixed this issue already.
On Fedora IoT (unmodified) and Silverblue (own spin) I get error: connecting to /run/bootupd.sock: ENOENT: No such file or directory
when executing sudo bootupctl status
. I don't update IoT automaticallly, Silverblue is supposed to compose daily.
NOK: Silverblue https://pagure.io/fork/goshansp/workstation-ostree-config
[hp@green ~]$ sudo bootupctl status
error: connecting to /run/bootupd.sock: ENOENT: No such file or directory
[hp@green ~]$ rpm -qa bootupd
bootupd-0.2.8-3.fc37.x86_64
[hp@green ~]$ rpm-ostree status
State: idle
Deployments:
● goshansp:fedora/37/x86_64/silverblue
Version: goshansp-37.20230327.1 (2023-03-27T14:21:50Z)
Commit: 67fefc484b8a3732e809881108060a4ee3a9cccc99eefc4eb6afb7c9f6cf08ac
NOK: IoT
[hp@rpi01 ~]$ sudo bootupctl status
error: connecting to /run/bootupd.sock: ENOENT: No such file or directory
[hp@rpi01 ~]$ rpm -qa bootupd
bootupd-0.2.8-3.fc37.aarch64
[hp@rpi01 ~]$ rpm-ostree status
State: idle
Deployments:
● fedora-iot:fedora/stable/aarch64/iot
Version: 37.20230330.0 (2023-03-30T13:39:02Z)
BaseCommit: 6a3886990fb729818409d884e083f6581a311627d208f00e9dfe9664bad9c1ee
GPGSignature: Valid signature by ACB5EE4E831C74BB7C168D27F55AD3FB5323552A
LayeredPackages: bootupd git python-pip python3-libgpiod
OK: On the FCOS fedora:fedora/x86_64/coreos/next 38.20230322.1.0
with bootupd-0.2.9-1.fc38.x86_64
it is working fine.
I currently assume that the issue is present on stable / 0.2.8
and has been fixed in next / 0.2.9
.
fwupd comes as a UEFI binary today, so bootupd would actually take care of updating fwupd itself.
At the moment to schedule an update fwupd
/usr/libexec/fwupd/efi/fwupdx64.efi.signed
binary to EFI/fedora/fwupdx64.efi
EFI/fedora/fw/fwupd-{guid}.cap
...so we don't actually care if fwupdx64.efi
is old or insecure or whatever, as it's going to be overwritten on next firmware update anyway. We could even mount->rm EFI/fedora/fwupdx64.efi
-> unmount on next startup if that helps, although I'm not sure it's a helpful thing to do.
We did used to install into the ESP fro the rpm %install phase, but various distros don't automount the ESP (perhaps sensibly) and so we stopped doing that.
If I've massively misunderstood the problem, apologies.
Hi!
When I run the command bootupctl adopt-and-update
on Fedora Silverblue 38 (build with unified core) shows the next error.
# bootupctl adopt-and-update
error: internal error: Failed adopt and update: applying filesystem changes: removing fedora/BOOTIA32.CSV: No such file or directory (os error 2)
Seems to look for 32-bit binaries. If I run it multiple times, the file to remove changes.
# bootupctl adopt-and-update
error: internal error: Failed adopt and update: applying filesystem changes: removing fedora/mmia32.efi: No such file or directory (os error 2)
# bootupctl adopt-and-update
error: internal error: Failed adopt and update: applying filesystem changes: removing BOOT/BOOTIA32.EFI: No such file or directory (os error 2)
I search the files in /boot/efi/EFI/fedora
but I don't find it (all 64-bit binaries).
# ls -l /boot/efi/EFI/fedora/
total 7404
-rwx------. 1 root root 110 Aug 18 2022 BOOTX64.CSV
drwx------. 2 root root 4096 Aug 18 2022 fonts
drwx------. 2 root root 4096 Apr 21 09:14 fw
-rwx------. 1 root root 64368 Dec 31 1979 fwupdx64.efi
-rwx------. 1 root root 144 Aug 18 2022 grub.cfg
-r-x------. 1 root root 3530048 Apr 24 09:23 grubx64.efi
-r-x------. 1 root root 857248 Apr 24 09:23 mmx64.efi
-r-x------. 1 root root 946712 Apr 24 09:23 shim.efi
-r-x------. 1 root root 946712 Apr 24 09:23 shimx64.efi
-rwx------. 1 root root 1204496 Aug 18 2022 shimx64-fedora.efi
This is the output of strace bootupctl adopt-and-update
# strace bootupctl adopt-and-update
execve("/usr/bin/bootupctl", ["bootupctl", "adopt-and-update"], 0x7ffc1eefb488 /* 22 vars */) = 0
brk(NULL) = 0x557a2ef1f000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffeae8fd960) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=62543, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 62543, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f42e1768000
close(3) = 0
openat(AT_FDCWD, "/lib64/libssl.so.3", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0555, st_size=677520, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f42e1766000
mmap(NULL, 665584, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f42e16c3000
mmap(0x7f42e16e1000, 380928, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e000) = 0x7f42e16e1000
mmap(0x7f42e173e000, 106496, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7b000) = 0x7f42e173e000
mmap(0x7f42e1758000, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x94000) = 0x7f42e1758000
close(3) = 0
openat(AT_FDCWD, "/lib64/libcrypto.so.3", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0555, st_size=4439200, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 4350968, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f42e1200000
mmap(0x7f42e12ad000, 2506752, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xad000) = 0x7f42e12ad000
mmap(0x7f42e1511000, 757760, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x311000) = 0x7f42e1511000
mmap(0x7f42e15ca000, 368640, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3c9000) = 0x7f42e15ca000
mmap(0x7f42e1624000, 9208, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f42e1624000
close(3) = 0
openat(AT_FDCWD, "/lib64/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0555, st_size=145112, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 143784, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f42e169f000
mmap(0x7f42e16a2000, 110592, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f42e16a2000
mmap(0x7f42e16bd000, 16384, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e000) = 0x7f42e16bd000
mmap(0x7f42e16c1000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x21000) = 0x7f42e16c1000
mmap(0x7f42e16c2000, 424, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f42e16c2000
close(3) = 0
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 }\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
newfstatat(3, "", {st_mode=S_IFREG|0555, st_size=2236192, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 1961264, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f42e1021000
mmap(0x7f42e1047000, 1433600, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f42e1047000
mmap(0x7f42e11a5000, 315392, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x184000) = 0x7f42e11a5000
mmap(0x7f42e11f2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1d0000) = 0x7f42e11f2000
mmap(0x7f42e11f8000, 32048, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f42e11f8000
close(3) = 0
openat(AT_FDCWD, "/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0555, st_size=107416, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 102408, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f42e1685000
mmap(0x7f42e1688000, 61440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f42e1688000
mmap(0x7f42e1697000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12000) = 0x7f42e1697000
mmap(0x7f42e169d000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f42e169d000
mmap(0x7f42e169e000, 8, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f42e169e000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f42e1683000
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f42e1680000
arch_prctl(ARCH_SET_FS, 0x7f42e1680800) = 0
set_tid_address(0x7f42e1680ad0) = 4288
set_robust_list(0x7f42e1680ae0, 24) = 0
rseq(0x7f42e1681120, 0x20, 0, 0x53053053) = 0
mprotect(0x7f42e11f2000, 16384, PROT_READ) = 0
mprotect(0x7f42e169d000, 4096, PROT_READ) = 0
mprotect(0x7f42e16c1000, 4096, PROT_READ) = 0
mprotect(0x7f42e15ca000, 356352, PROT_READ) = 0
mprotect(0x7f42e1758000, 40960, PROT_READ) = 0
mprotect(0x557a2d909000, 69632, PROT_READ) = 0
mprotect(0x7f42e17a9000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7f42e1768000, 62543) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 0 (Timeout)
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f42e105eba0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSEGV, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x557a2d88d7d0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f42e105eba0}, NULL, 8) = 0
rt_sigaction(SIGBUS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGBUS, {sa_handler=0x557a2d88d7d0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f42e105eba0}, NULL, 8) = 0
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f42e1775000
mprotect(0x7f42e1775000, 4096, PROT_NONE) = 0
sigaltstack({ss_sp=0x7f42e1776000, ss_flags=0, ss_size=8192}, NULL) = 0
getrandom("\x83\x5d\xbe\x4c\x31\xc8\x39\xf6", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x557a2ef1f000
brk(0x557a2ef40000) = 0x557a2ef40000
openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
newfstatat(3, "", {st_mode=S_IFREG|0444, st_size=0, ...}, AT_EMPTY_PATH) = 0
read(3, "557a2d716000-557a2d733000 r--p 0"..., 1024) = 1024
read(3, "f42e1200000 rw-p 00000000 00:00 "..., 1024) = 1024
read(3, "ib64/libz.so.1.2.13\n7f42e169e000"..., 1024) = 1024
read(3, " /usr/lib64/libssl.so.3.0."..., 1024) = 1024
close(3) = 0
sched_getaffinity(4288, 32, [0 1 2 3 4 5 6 7]) = 8
getrandom("\xfe\xc8\x84\xa9\x77\xe2\x80\xa6\xe2\x55\x66\x1f\xac\x81\x3b\x71", 16, GRND_INSECURE) = 16
ioctl(2, TCGETS, {c_iflag=ICRNL|IXON|IUTF8, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|OPOST|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE, ...}) = 0
socket(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/run/bootupd.sock"}, 20) = 0
getpid() = 4288
getuid() = 0
getgid() = 0
sendmsg(3, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="bootupd-hello\n", iov_len=14}], msg_iovlen=1, msg_control=[{cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS, cmsg_data={pid=4288, uid=0, gid=0}}], msg_controllen=32, msg_flags=0}, MSG_CMSG_CLOEXEC) = 14
sendto(3, "\3\0\0\0", 4, MSG_CMSG_CLOEXEC, NULL, 0) = 4
recvfrom(3, "\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\3\0\0\0\0\0\0\0EFI\36"..., 1048576, MSG_CMSG_CLOEXEC, NULL, NULL) = 85
sendto(3, "\1\0\0\0\3\0\0\0\0\0\0\0EFI", 15, MSG_CMSG_CLOEXEC, NULL, 0) = 15
recvfrom(3, "\1\0\0\0x\0\0\0\0\0\0\0Failed adopt and upd"..., 1048576, MSG_CMSG_CLOEXEC, NULL, NULL) = 132
close(3) = 0
write(2, "error: ", 7error: ) = 7
write(2, "internal error: Failed adopt and"..., 136internal error: Failed adopt and update: applying filesystem changes: removing BOOT/BOOTIA32.EFI: No such file or directory (os error 2)) = 136
write(2, "\n", 1
) = 1
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x7f42e1775000, 12288) = 0
exit_group(1) = ?
+++ exited with 1 +++
To install bootupd
I imported bootupd.yaml
to the treefile of workstation-ostree-config/silverblue.yaml
.
....
arch-include:
x86_64: bootupd.yaml
And this is the package info.
# rpm -qi bootupd
Name : bootupd
Version : 0.2.9
Release : 1.fc38
Architecture: x86_64
Install Date: Fri 21 Apr 2023 10:15:59 AM -03
Group : Unspecified
Size : 2219204
License : ASL 2.0
Signature : RSA/SHA256, Fri 20 Jan 2023 09:45:36 PM -03, Key ID 809a8d7ceb10b464
Source RPM : rust-bootupd-0.2.9-1.fc38.src.rpm
Build Date : Fri 20 Jan 2023 06:15:16 PM -03
Build Host : buildhw-x86-07.iad2.fedoraproject.org
Packager : Fedora Project
Vendor : Fedora Project
URL : https://crates.io/crates/bootupd
Bug URL : https://bugz.fedoraproject.org/rust-bootupd
Summary : Bootloader updater
Description :
Bootloader updater
Thanks!
Since Linux v6.0 the vfat filesystem has support for renameat2(..., RENAME_EXCHANGE)
:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=da87e1725ae2
So bootupd
could instead of applying the diff files one by one to the destination dir, it could create a temporary dir that is a copy of the existing ESP, apply the diff to that temp dir and finally do an atomic rename exchange of the two directories.
That way, the update mechanism will be safer since it would only require a single renameat2()
system call.
Right now we don't update the static configs, but we should.
Hi bootupd team,
I love the idea behind bootc so I've been trying to create a bootc image based on archlinux.
As part of creating a bootc image bootupd backend generate-metadata
is called but this fails on arch linux as there is not rpm binary.
Is there a way I can work around this dependency? I am happy to hack around this in my image as it is just a proof of concept but not sure what to do
Also the readme suggest bootupd should be OS agnostic but looking for rpm
means it is not really agnostic :-( are there plans to remove this dependency?
We have a lot of layers of abstraction predicated on the idea that there are multiple things to update, but we only update UEFI today.
In practice we also should update the BIOS MBR since there are reasons to do so sometimes, and it helps finish the story.
Splitting this thread from #8 (comment)
For rpm-ostree systems we should support a flow like:
$ rpm-ostree upgrade # queue a pending deployment
$ bootupctl update --from-pending
(or possibly bootupctl update
does that by default if it detects a pending deployment; not sure)
This flow would be used by orchestrator systems like zincati/MCO.
Unfortunately, neither Silverblue/Kinoite or IoT use unified-core
mode in rpm-ostree yet. It's planned but we haven't been able to complete the testing and F37 and before won't likely switch either.
We would need bootupd to be able to work in those cases as well to be able to add bootupd to them and allow users to update their bootloaders.
See: coreos/fedora-coreos-tracker#1441
See: fedora-silverblue/issue-tracker#434
See: fedora-silverblue/issue-tracker#120
It's probably due to the Fedora 35 update, likely need to revise our pinned grub builds.
To fix issues with Fedora Atomic desktops, I'm considering backporting the bootupd inclusion to Fedora 39:
While thinking about that, I wondered if it would be able to create layered images with bootupd included in a layer.
Is it safe to run /usr/bin/bootupctl backend generate-update-metadata
from a container layer?
FROM quay.io/fedora-ostree-desktops/kinoite:40
RUN rpm-ostree install bootupd \
&&\
/usr/bin/bootupctl backend generate-update-metadata \
&& \
ostree container commit
I'll do some testing.
Today we handle the case where bootupd was used to create the disk image in the first place.
We also want to handle "adoption" - e.g. with an existing CoreOS system, ideally all the way back to an RHCOS 4.1 bootimage, we should be able to successfully update it to the latest EFI (and in the future, BIOS).
Example flow:
$ bootupctl status
Component EFI:
Not installed via bootupd
Detected known state: CoreOS disk image aleph א version: 32.20200922.dev.3
$ bootupctl adopt
Component EFI:
Version: coreos-aleph-32.20200922.dev.3
Upgrade: Available: <version in ostree>
$ bootupctl update
Updated to <version in ostree>
See https://github.com/coreos/fedora-coreos-tracker/blob/master/internals/README-internals.md#aleph-version for more information on the aleph.
Handling systems without aleph is uglier, but I think in practice there aren't too many bootimages for OpenSHift 4.1 and 4.2 that will be in widespread use - we could hardcode them, or just punt and say "unknown" and offer bootupctl adopt --force
and track it as an "unknown" version.
Should create a new release according to https://bugzilla.redhat.com/show_bug.cgi?id=2268505#c27 to test for #665.
Right now we're just missing s390x, which adds messy architecture conditionals to our code.
The way zipl works is somewhat UKI-like as far as I understand things in that it needs to be run for each kernel update, and it merges together the kernel/initramfs. The ostree/zipl glue is basically just running zipl
after an update to the BLS configs.
So I think the bootupd support for s390x is basically just "detect and no-op" effectively - almost.
Except for one detail: on the first install to a disk, there's a magic command that needs to be run called "chreipl".
As noted in the README.md today rpm -q shim-x64
is a lie. Ultimately what we want to do I think is:
manifest-bootloader.yaml
rpm-ostree compose tree
run to coreos-assembler using that manifest, writing to a separate refcreate_disk.sh
to use that (we only need that ref if doing a disk image build note!), including passing data from that ref to /usr/libexec/bootupd generate-update-metadata
This would mean that rpm -q shim-x64
would say it's not installed, which is correct - from the perspective of rpm and rpm-ostree. It's not tracked by that system, it's tracked by bootupd. Instead the single source of truth for versioning would then be bootupctl status
.
I am pretty sure at one point we did the "auto-exit on idle" pattern but it doesn't look like we are today. We should just to conserve resources.
Let's depend on tokio and add an idle timeout in the daemon.
Currently, running bootupctl backend install
will fail to unmount the EFI partition after it completes. The bootupd.service
unit has MountFlags=slave
, but that doesn't apply to image building tools like cosa running the command directly.
[2021-06-11T06:02:01.420Z] cargo build --release
[2021-06-11T06:02:01.420Z] make: cargo: No such file or directory
[2021-06-11T06:02:01.420Z] make: *** [Makefile:25: all] Error 127
This started in late April. See #184 for one attempt to fix it.
There were some format cleanups between 0.1.2 and 0.2.0¹ - current bootupd will barf trying to update those. I think we need a backcompat reader, or perhaps the simplest is to just delete earlier data and treat it the same as an adoption case.
To rephrase the current state is confusing because we handle updating non-bootupd systems and bootupd 0.2.0 systems but not bootupd 0.1.
¹ Also 0.1.3 which is ~equivalent but it's less confusing if we just talk about 0.2.x
I think we should be confident enough in our process that bootupctl update
should detect the FCOS case and update it transparently.
I'm not fully sure how #34 managed to pass CI, but rebasing my other PR I noticed that master
is currently failing to build for me (it was fine yesterday) with:
error[E0599]: no method named `metadata_optional` found for reference `&openat::Dir` in the current scope
--> src/filetree.rs:184:37
|
184 | if let Some(meta) = dir.metadata_optional(path)? {
| ^^^^^^^^^^^^^^^^^ method not found in `&openat::Dir`
error: aborting due to previous error
I browsed the extension trait on docs.rs and tried tweaking the callsite for a bit now, but I still can't figure out why method resolution is failing.
Basically to test upgrades, we're downgrading to an older grub build which is broken. We're just testing that the synthetic process of changing files actually works, but we're not currently testing rebooting into it.
Instead, we should download the working RPM and tweak it by:
This project was designed to be distribution independent; that's in theory. In practice today it is tied to both ostree and rpm (though the rpm part is definitely written in an attempted-to-be pluggable way).
But I think it will make more sense to fold this into https://github.com/containers/bootc - we're not going to have non-ostree support anytime soon, and if we do it should work in the same way as bootc. Also, I think we want bootc bootloader update
e.g.
Also, the two projects are similarly named and it will be less confusing to just have bootc, not bootc and bootupd.
Follow-up to #127 (specifically #127 (comment)). We need to update the EFI in all the devices matching the appropriate GUID, not just the one which wins the /dev/disk/by-partlabel/EFI-SYSTEM
race.
Hi!
Currently, running bootupctl validate
or bootupctl update
on Fedora Siverblue 36 doesn't work.
$ sudo bootupctl update
error: internal error: Could not find "/dev/disk/by-partlabel/EFI-SYSTEM"
$ ls -l /dev/disk/by-partlabel/
total 0
lrwxrwxrwx. 1 root root 15 Sep 28 09:08 'EFI\x20System\x20Partition' -> ../../nvme0n1p1
There is a option to specified the EFI partition or is a expected behavior?
Thanks!
It'd be nice to be able to convert Fedora ostree+Anaconda users to bootupd --with-static-configs
.
When installing a bootable container image via Anaconda and using a kickstart file with bootloader
command that also specifies a boot timeout (--timeout
parameter), the specified value is ignored and a predefined one from static GRUB configuration files is used. Using a predefined value makes likely perfect sense in the common scenarios, but somewhat breaks the user experience with Anaconda which provides, among many other configuration options, a possibility to set up an arbitrary timeout value.
We had a live discussion about this. A whole lot came up there, but there was some consensus to try to solve the "targeted" problem of just updating UEFI on x86_64.
I lean a bit towards unwinding some of the complexity in bootupd and doing it here (maybe the daemon mode was a mistake, but it is socket activated and auto-exiting today).
Anyways, the proposal is a more minimal PoC that explicitly only handles CoreOS case:
/usr/lib/ostree-boot/efi
plus the original rpm -q shim-x64
etc. for that data/boot/efi
bootupd status
to show whether or not things are up to dateopenat is deprecated and less secure, and pulls in less maintained deps.
Bootupd would write the new bootloader in a new place (B), set BootNext to a new boot entry with this bootloader. And then on reboot would check that the boot succeeded and would do the reverse for the next update (use A).
Similar to ostree and rpm-ostree we should have a RELEASE.md documenting how to do a release process here.
When I run bootc install to-existing-root
test on aarch64 bare metal server, the bootupd changed boot order to left the bootc system boot first. To re-install a new system, I have to re-configure the boot order to enable network boot first.
Installing image: docker://quay.io/redhat_emp1/*****:u2d2
Digest: sha256:1103ab6499bb1bf0f11632bb5afbf7f34e1dd02170127a8c3191de409635188a
Initializing ostree layout
Initializing sysroot
ostree/deploy/default initialized as OSTree stateroot
Deploying container image
Loading usr/lib/ostree/prepare-root.conf
Deployment complete
Running bootupctl to install bootloader
BootCurrent: 0005
Timeout: 6 seconds
BootOrder: 0005,0003,0004,0001,0000,0002,0006,0009
Boot0000 fedora
Boot0001* UEFI: Built-in EFI Shell
Boot0002 redhat
Boot0003* UEFI: PXE IPv4 Intel(R) Network D8:5E:D3:8F:A5:04
Boot0004* UEFI: PXE IPv4 Intel(R) Network D8:5E:D3:8F:A5:05
Boot0006 Fedora
Boot0009 Gemini
Boot0005* redhat
Installed: grub.cfg
Installed: "redhat/grub.cfg"
Installation complete!
In Fedora and derivatives there's a policy I think of writing SELinux policies for things that are systemd .service
s.
We happen to have a .socket
and .service
units but we aren't really a service today. The socket actually denies non-root from connecting.
I think we should just delete those units and where we want to run things under systemd, we do it dynamically via systemd-run
e.g.
The primary goal of this is to get this project off the list of things that need a SELinux policy.
But I think it'd be a good cleanup anyways.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.