-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an ostree-admin-esp-upgrade subcommand to update the EFI System Partition #1873
Conversation
The copy_dir_recurse(), dirfd_copy_attributes_and_xattrs() and is_ro_mount() functions could be used in other places, so move them as libotutil helpers.
There's already a function to check if a path is a read-only mountpoint, so add a function to also check for mountpoints that are not read-only.
Can one of the admins verify this patch?
|
46930b2
to
092cd8f
Compare
The files in the EFI System Partition (ESP) are never updated by OSTree, users will always have the same ESP that was created during installation. This happens because the ESP uses a vfat filesystem which doesn't support symbolic links so the upgrade can't be atomic and part of the transaction. But since the ESP contains the bootloader components (shim, grub, etc) and other important EFI binaries like the ones used for firmware update, there should be a way to upgrade the ESP with the latest version of these files. These binaries are stored in the /usr/lib/ostree-boot/efi directory of a deployment, because rpm-ostree places there everything that is in /boot. Add a ostree-admin-esp-upgrade subcommand that just copies the content of /usr/lib/ostree-boot/efi to /boot/efi, so users can update the ESP and get the latest version of the files that are present in the current deployment. This sub-command only works on a system that was booted with EFI and has the ESP mounted in /boot/efi. Closes: ostreedev#1649
092cd8f
to
b9f2b65
Compare
bot, add author to whitelist |
In theory the code should probably be a library function but...eh. Not really worth it right now. I know it is probably next to impossible to make this truly transactional but can we at least do what the ostree core does and copy everything into temporary names, then Related to that, is there a safer order to update the components? For example, update shim first? I'm also wondering if what we really need to do is have the bootloader know how to do this rather than ostree, but as is it's fine for now. |
I mentioned this before I think also but soon at least FCOS is probably going to move away from installing the grub binaries into the ostree itself because they're only needed for Anaconda, and bloat the image. See coreos/coreos-assembler#556 So if we go that route...we'd need to e.g. publish a container or ostree ref or RPM or whatever that users could download to update the bootloader "out of band" - really quite similar to what LVFS is doing? |
Also thanks for working on this! |
Is there a nicer way for us to detect if we need to do this? I guess just doing a diff is the dumb/simple way but perhaps it'd be nicer to have a |
Ok, I didn't see that other
I thought that temporary files where already used when calling It doesn't do I tried to reuse
Yes, I also thought about that. We could determine the order in which the files need to be copied to reduce the risk of loosing power during the ESP upgrade and messing things up. As you mention, things could fail if for example grub is upgraded without upgrading shim first. My worry was that adding such logic would make the command less flexible. For example users can choose to not use shim at all and just have an EFI Boot Entry that points directly to the grub binary. Or someone could be using a different EFI bootloader, like sd-boot. In other words, I wondered if the command should be aware of the content of the ESP or just copy whatever was installed by packages in
The problem is that all these files are not owned by the same component. There are EFI binaries installed by at least the shim, grub2 and fwupd packages. So even if someday shim and grub could know how to update themselves, there are other EFI binaries like fwupdx64 that are managed by a user-space component (fwupd). |
Yes, but I understood that was only for the user-space tools (since the Unrelated, but in the pull you referenced I noticed that you are creating your own grub EFI binary. That will break Secure Boot since the image won't be signed.
As mentioned I don't think that's a requirement since we could keep the grub2 packages that have the bootloader even if the ones for the user-space tools are dropped. But yes, it would be good to explore having an out-of-band update mechanism for shim and grub that's similar to how we update the firmware with LVFS. |
That's a very interesting idea. So IIUC rpm-ostree could generate this So a different |
Looks like on vfat
What about writing new bootloader files to /boot/efi/.tmp/, then |
I want to emphasize I really appreciate your work on this PR! This is attempting to address a real-world and important problem. However...the more I think about this, the more I feel (as noted before) that the long term end state should be shipping the EFI bits separately, and have a separate tool (which could be a privileged container image, or a tool on the host that downloads things on its own). This way the layering and ownership of things is very clear - Further, we should define a versioning mechanism for data in And then in an ideal world, we we have a package-system independent (in the same way ostree is) mechanism to update that data. Now, distributions which use rpm may choose to ship e.g. a separate rpmdb for Maybe all of this is to say - we need something like https://github.com/fwupd/fwupd except for bootloaders! (Which would get us into a nice layering of "ostree updates bootupdated, which updates fwupd-efi, which updates your firmware...) Or I guess, we could just expand the scope of fwupd to include bootloaders. That all said...in practice there may be tricky situations where in order to update the bootloader, one needs to update the ostree or vice versa...ideally we can always update the bootloader first and it e.g. compatibly handles older config files though. |
Summoning @hughsie for thoughts on ⬆️ |
Random other side thought: Updating the ESP may not be at all easy to do truly transactionally in the general case, but it'd probably work to just ensure that the system remains bootable, and if we're interrupted halfway through, we just "reconcile" on reboot. We were leaning towards doing something like that in ostree to handle the " |
From a fwupd point of view, we just need to be able to write Also, the ESP is nearly always FAT, for better or worse. |
@cgwalters thanks a lot for your feedback and comments.
Yes, I guess that most users just don't know that the bootloader is never updated since the rpmdb would report a different package version than the one installed in the ESP, but it's confusing that I know this is because the ESP is a fat partition so can't be part of the deployment transaction, but this is not evident at first sight. We should probably document this to raise awareness.
Would this versioning mechanism be for data in
Not sure about expanding fwupd scope since the bootloaders are not really firmware, but I understand your point. And that's why I tried to use a separate command for this. Although it may not be a For now I'll hold this PR until we have decided how the solution should be. I would also like to know @vathpela's opinion on this, and also from @wjt and @carlocaione who also were involved in previous discussions about this. |
I've been also involved in these discussions behind the scenes from the Endless perspective (which I think is why you mentioned @wjt and @carlocaione). From that angle we're additionally interested in updating bootloaders such as legacy grub and u-boot so we're looking for something not limited to ESP. We're also looking for something that would be run automatically, without requiring the user to run an ostree command from the terminal. So to consider this a bit more from the general case: should ostree handle bootloader updates? After a bit of reflection I think the answer of "no, a separate tool should handle it" is actually pretty reasonable based on the fact that ostree did not install the bootloader, so why should it be in charge of updating it? Conceptually, I don't think bootloader installation/updating belongs in ostree. I was wondering if there is a counter-argument around practicality (since EFI bootloaders are so easy to update - just copy files), in that if ostree did at least handle the EFI case it'd solve this gaping hole for many system integrators, but actually considering the challenges around which order to update files and can it be done atomically on VFAT..., maybe its actually not so easy & practical, and the argument to keep it separate holds strong. |
I'm also not opposed to try to bring bootloader updates into the ostree codebase BTW; the logic for "ostree handles ostrees" is obviously circular here because "ostree" is defined to not include
Right, hence the idea to remove the bootloader stuff from the ostree entirely. I imagine some people today are shipping builds in this way, and as mentioned above we are poised to do it for FCOS.
The canonical location for the kernel (and initramfs) is now
OSTree always owns kernel images - the entire codebase is oriented around the concept of a "bootable commit" which is a pair of (kernel+initramfs, userspace) effectively; then a "deployment" is a (bootable commit, kernel arguments, idserial) etc. This property is really important to me; if you type The bootloader has always been outside of this. |
@dsd thanks a lot for your comments.
Yes, I'm also convinced now that bootloader updates don't really belong to ostree and that should be handled by a separate tool. In fact, this tool could be used even in non-ostree based distros since we also have the problem of bootloader update there. For example we never update the bootloader in traditional Fedora for legacy BIOS, only for EFI because copying the binaries in the ESP is handled by the shim and grub rpm packages. |
This is the new default; we end up with the kernel data in only once place. See the treefile docs as well as ostreedev/ostree#1079 and discussion in ostreedev/ostree#1873
This is the new default; we end up with the kernel data in only once place. See the treefile docs as well as ostreedev/ostree#1079 and discussion in ostreedev/ostree#1873
This is the new default; we end up with the kernel data in only once place. See the treefile docs as well as ostreedev/ostree#1079 and discussion in ostreedev/ostree#1873
This pull-request addresses #1649 by adding a new
ostree admin esp-upgrade
subcommand that can be used to upgrade the EFI System Partition (ESP) with files from the/usr/lib/ostree-boot/efi
directory in the current OSTree deployment.The command only works on systems that are booted with an EFI firmware and where the ESP is mounted in
/boot/efi
.