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 readonly /boot mount #136

Closed
cgwalters opened this issue Mar 20, 2024 · 7 comments · Fixed by #146
Closed

Support readonly /boot mount #136

cgwalters opened this issue Mar 20, 2024 · 7 comments · Fixed by #146
Labels
jira flow issues to jira

Comments

@cgwalters
Copy link
Contributor

In some image based systems (e.g. ostree/bootc) like (e.g. Fedora CoreOS) we mount /boot as read-only by default. The rationale for this is few things should be touching /boot. Those that do (like ostree) do:

  • Create private mount namespace
  • Remount readonly

This is easy to do with systemd, just add PrivateMounts=true to the units for the first part, then in the code check if /boot is readonly, and if so mount -o remount,rw /boot.

@say-paul say-paul added the jira flow issues to jira label Mar 20, 2024
@say-paul
Copy link
Member

With composefs enabled, the entire file-system will be readonly, so we need to ensure the transient rootfs in enabled too.
thoughts? @cgwalters @jmarrero

@cgwalters
Copy link
Contributor Author

cgwalters commented Mar 27, 2024 via email

@say-paul
Copy link
Member

say-paul commented Aug 7, 2024

@cgwalters I tried the following approach as suggested but seems even if /boot is mounted as rw,
grubedit-env fails to edit /boot/grub2/grubenv.

[core@localhost ~]$ sudo systemctl status greenboot-grub2-set-success.service
× greenboot-grub2-set-success.service - Mark boot as successful in grubenv
     Loaded: loaded (/usr/lib/systemd/system/greenboot-grub2-set-success.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Wed 2024-08-07 13:38:59 UTC; 6min ago
    Process: 945 ExecStartPre=/bin/sh -c if grep -q " /boot .* ro," /proc/mounts; then mount -o remount,rw /boot || exit 1; fi (code=exited, status=0/SUCCESS)
    Process: 959 ExecStart=/usr/bin/grub2-editenv /boot/grub2/grubenv set boot_success=1 (code=exited, status=1/FAILURE)
    Process: 961 ExecStopPost=/bin/sh -c if grep -q " /boot .* rw," /proc/mounts; then mount -o remount,ro /boot || exit 1; fi (code=exited, status=0/SUCCESS)
   Main PID: 959 (code=exited, status=1/FAILURE)
        CPU: 2.010s

Aug 07 13:38:57 localhost.localdomain systemd[1]: Starting Mark boot as successful in grubenv...
Aug 07 13:38:59 localhost.localdomain grub2-editenv[959]: /usr/bin/grub2-editenv: error: cannot open `/boot/grub2/grubenv': Read-only file system.
Aug 07 13:38:59 localhost.localdomain systemd[1]: greenboot-grub2-set-success.service: Main process exited, code=exited, status=1/FAILURE
Aug 07 13:38:59 localhost.localdomain systemd[1]: greenboot-grub2-set-success.service: Failed with result 'exit-code'.
Aug 07 13:38:59 localhost.localdomain systemd[1]: Failed to start Mark boot as successful in grubenv.
Aug 07 13:38:59 localhost.localdomain systemd[1]: greenboot-grub2-set-success.service: Consumed 2.010s CPU time.
[core@localhost ~]$ sudo systemctl cat greenboot-grub2-set-success.service

[Unit]
Description=Mark boot as successful in grubenv
Requires=boot-complete.target
After=boot-complete.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/bin/sh -c 'if grep -q " /boot .* ro," /proc/mounts; then mount -o remount,rw /boot || exit 1; fi'
ExecStart=/usr/bin/grub2-editenv /boot/grub2/grubenv set boot_success=1
ExecStart=/usr/bin/grub2-editenv /boot/grub2/grubenv unset boot_counter
ExecStopPost=/bin/sh -c 'if grep -q " /boot .* rw," /proc/mounts; then mount -o remount,ro /boot || exit 1; fi'
PrivateMounts=true

[Install]
WantedBy=multi-user.target
[core@localhost ~]$

@cgwalters
Copy link
Contributor Author

if grep -q " /boot .* ro," /proc/mounts;

It's simpler and less "ad hoc string parsing" to use test -w /boot

I tried the following approach as suggested but seems even if /boot is mounted as rw,
grubedit-env fails to edit /boot/grub2/grubenv.

At a quick look at the docs for PrivateMounts= in man systemd.exec, it looks like a separate namespace is set up for each Exec* invocation, so you'll need to do it like this:

PrivateMounts=true
ExecStart=/bin/sh -c 'test -w /boot || mount -o remount,rw /boot && /usr/bin/grub2-editenv /boot/grub2/grubenv set boot_success=1 && /usr/bin/grub2-editenv /boot/grub2/grubenv unset boot_counter

or so

@cgwalters
Copy link
Contributor Author

(Or probably cleaner, split that out to its own file instead of inline script, or even better make it not shell script)

@say-paul
Copy link
Member

yes, figured that out later, applied the similar approach here PR: #146

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

Successfully merging a pull request may close this issue.

2 participants