Skip to content
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

Support for the Raspberry Pi bootloader #1801

Open
fkrull opened this issue Jan 11, 2019 · 12 comments
Open

Support for the Raspberry Pi bootloader #1801

fkrull opened this issue Jan 11, 2019 · 12 comments

Comments

@fkrull
Copy link
Contributor

fkrull commented Jan 11, 2019

I'd like OSTree (i.e. ostree admin deploy) to integrate with the Raspberry Pi bootloader like it does with e.g. GRUB. My general idea is that after deploying, ostree would set the kernel and initramfs path as well as kernel options in /boot/config.txt. I haven't actually tried any of this since I don't have a bootable image yet, but I feel it should work.


The reason I'm opening this issue without actually having figured out if my idea works is because I think it might be better to implement some sort of extension point for bootloader integrations instead. That way, libostree wouldn't need to include support for marginal bootloaders and I wouldn't have to write the config file mangling in C ;)

Some ideas:

  • Every binary in a certain directory, let's say /usr/lib/ostree/bootloaders participates in the selection process in _ostree_sysroot_query_bootloader, by mapping the OstreeBootloaderInterface functions to certain command-line arguments (e.g. <binary> query is expected to return a zero exit code if that bootloader is active).
  • The path to a bootloader helper is configured in some file, e.g. the repo config as suggested at systemd-boot support #1719 (comment). This setting could either override the normal bootloader selection or just add to it.
  • Like above, but it's just a fixed path rather than a setting, e.g. if /usr/lib/ostree/bootloader-helper exists and is executable. This just seems like a strictly more confusing variant of the previous one though.

So yeah. I wanted to at least explain my usecase, but I feel a "plugin" approach would be quite useful here, not least because it saves me from having to work out my details in the context of libostree. Thoughts?

@AdrianVovk
Copy link

Maybe a hybrid approach could work? There would be many different forks coming from the bootloader helpers. They would need to be queried, paths need to be figured out, etc, and all of that requires forks to the process. What about the bootloaders are defined in C (at least the common ones like GRUB, systemd-boot, uboot, etc) and then the sysadmin or distro packager can add extra bootloader config scripts in /{etc,usr/lib}/ostree/bootloaders/foo. There would be a special stub bootloader implmented in C that execs /{etc,usr/lib}/ostree/bootloaders/default which is a symlink to the correct bootloader.

That way, the most common configurations will remain quick, but the custom stuff will remain extensible

@refi64
Copy link

refi64 commented Jan 12, 2019

I mean, OSTree already uses GLib, which has a dynamic module API.

@AdrianVovk
Copy link

@kirbyfan64 the point is to not have to write C code. I presume OP wants to write a python script or so

@refi64
Copy link

refi64 commented Jan 12, 2019

I mean, there's always also libpeas, which supports other languages, but that'd also maybe be a big dependency.

One thing worth thinking about: how much overhead do the forks really cost? If the normal bootloaders are still written in C, the overhead of running two or three programs on deploys wouldn't really be much. grub2-mkconfig is already a shell script anyway.

@AdrianVovk
Copy link

@kirbyfan64 That's what I'm saying. If the common bootloaders are in C and we have a "stub" bootloader that calls a shell script or whatever, that would be a good compromise

@fkrull
Copy link
Contributor Author

fkrull commented Jan 12, 2019

I wasn't even thinking of changing the built-in bootloaders. That's ultimately an implementation detail anyway.

the point is to not have to write C code. I presume OP wants to write a python script or so

Well, if you put it like that. ;) My reasoning for an executable interface over a shared object one:

  • The ostree <-> bootloader interface, as it exists now, seems simple enough to map to just command-line arguments and exit codes.
  • As far as I'm aware, processes on Linux are quite cheap.
  • It's so much simpler to work with. For a shared object plugin, you need to use a language that can create shared libraries with the correct ABI, you need various headers, you need to compile and link it correctly etc. For a helper-executable-type interface, you can go as simple as a shell script if that suits your needs.
  • And, yes, I wouldn't have to write C. (Or if I end up implementing this feature, at least less C.)

@AdrianVovk
Copy link

I guess forking two or three times per deploy is fine. Having all of the bootloaders in one place and implemented in the same way would be good

Implementation-wise: OSTree can read the repo config for a bootloader name, and then will look in /etc/ostree/bootloaders/LOADER. If that file isn't there or isn't executable, it will look in /usr/lib/ostree/bootloaders/LOADER. This way, the admin can add their own bootloaders or even override the built in ones

If we want to minimize forks, we can fork off the process once which will go into a loop. Then it would read commands off of stdin, and then finally OSTree would send SIGTERM when it's done

@cgwalters
Copy link
Member

In #1719 we discussed making the bootloader configurable. I think an implementation where we have e.g. /usr/lib/ostree/bootloaders/rpi which is an executable program, and

[sysroot]
bootloader=rpi

would be quite straightforward.

@cgwalters
Copy link
Member

One thing related to this is coreos/fedora-coreos-tracker#47

If the bootloader backend is just "fork off a subprocess" then we don't have any way to communicate extended information back to ostree. The primary thing I care about is having ostree admin status be a source of truth (or at least useful information).

Today one can rely on the top of the list being the actual next thing to boot.

Maybe we need some sort of JSON or something passed back from the bootloader backend that has e.g. extended information about whether the entry is the next one to boot.

@wmanley
Copy link
Member

wmanley commented Oct 26, 2020

FWIW I think it would be better just to build RPi bootloader support into ostree. It's not very hard to add an additional bootloader, see #1937 for example. It's true that the string mangling in C is a little inconvenient, but there shouldn't be a lot of this. The config.txt is a very simple format. You'd need to read line-by-line match for lines beginning with cmdline= and kernel=, replacing or inserting them as needed.

Adding a plugin system makes deployment and future development more complicated. Who "owns" the bootloaders? How are they distributed? What if you want to use existing helper code from ostree?, etc.

I'd be happy to help if there was someone interested in implementing this.

@wmanley
Copy link
Member

wmanley commented Oct 26, 2020

You'd need to read line-by-line match for lines beginning with cmdline= and kernel=, replacing or inserting them as needed.

In fact, the only key that would need to be set is os_prefix.

@goldyfruit
Copy link

I would love to see the plugin idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants