From a5670bd91d5706f6a819b3896dbcea6c3887bc5d Mon Sep 17 00:00:00 2001 From: saypaul Date: Thu, 8 Aug 2024 17:12:17 +0530 Subject: [PATCH] support for ro /boot Support is added for greenboot to work with read-only /boot. Its uses PrivateMounts=yes to isolate the system and remounts boot as rw followed by setting the grub paremeters as per healthcheck. Following services are affected: * greenboot-grub2-set-success.service * greenboot-grub2-set-counter.service * greenboot-rpm-ostree-check-fallback.service The grub2-editenv command is decoupled from greenboot-grub2-set-success.service and is part of a seperate script. Signed-off-by: saypaul --- greenboot.spec | 1 + .../greenboot-grub2-set-counter.service | 1 + .../greenboot-grub2-set-success.service | 4 +-- ...ot-rpm-ostree-grub2-check-fallback.service | 1 + .../greenboot/greenboot-grub2-set-counter | 28 ++++++++++++++-- .../greenboot/greenboot-grub2-set-success | 33 +++++++++++++++++++ .../greenboot-rpm-ostree-grub2-check-fallback | 20 ++++++++++- 7 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 usr/libexec/greenboot/greenboot-grub2-set-success diff --git a/greenboot.spec b/greenboot.spec index 8a1dab72..1990a72b 100644 --- a/greenboot.spec +++ b/greenboot.spec @@ -154,6 +154,7 @@ install -DpZm 0644 etc/greenboot/greenboot.conf %{buildroot}%{_sysconfdir}/%{nam %{_prefix}/lib/bootupd/grub2-static/configs.d/*.cfg %{_unitdir}/greenboot-status.service %{_libexecdir}/%{name}/greenboot-grub2-set-counter +%{_libexecdir}/%{name}/greenboot-grub2-set-success %{_unitdir}/greenboot-grub2-set-success.service %{_unitdir}/greenboot-grub2-set-counter.service %{_libexecdir}/%{name}/greenboot-rpm-ostree-grub2-check-fallback diff --git a/usr/lib/systemd/system/greenboot-grub2-set-counter.service b/usr/lib/systemd/system/greenboot-grub2-set-counter.service index 72837dc9..a8827daa 100644 --- a/usr/lib/systemd/system/greenboot-grub2-set-counter.service +++ b/usr/lib/systemd/system/greenboot-grub2-set-counter.service @@ -18,6 +18,7 @@ RequiresMountsFor=/boot Type=oneshot RemainAfterExit=yes ExecStart=/usr/libexec/greenboot/greenboot-grub2-set-counter +PrivateMounts=yes [Install] RequiredBy=ostree-finalize-staged.service diff --git a/usr/lib/systemd/system/greenboot-grub2-set-success.service b/usr/lib/systemd/system/greenboot-grub2-set-success.service index f5ef55a1..db10061d 100644 --- a/usr/lib/systemd/system/greenboot-grub2-set-success.service +++ b/usr/lib/systemd/system/greenboot-grub2-set-success.service @@ -15,8 +15,8 @@ After=boot-complete.target [Service] Type=oneshot RemainAfterExit=yes -ExecStart=/usr/bin/grub2-editenv - set boot_success=1 -ExecStart=/usr/bin/grub2-editenv - unset boot_counter +ExecStart=/usr/libexec/greenboot/greenboot-grub2-set-success +PrivateMounts=yes [Install] WantedBy=multi-user.target diff --git a/usr/lib/systemd/system/greenboot-rpm-ostree-grub2-check-fallback.service b/usr/lib/systemd/system/greenboot-rpm-ostree-grub2-check-fallback.service index 30312d36..795eb748 100644 --- a/usr/lib/systemd/system/greenboot-rpm-ostree-grub2-check-fallback.service +++ b/usr/lib/systemd/system/greenboot-rpm-ostree-grub2-check-fallback.service @@ -16,6 +16,7 @@ Before=greenboot-grub2-set-success.service Type=oneshot RemainAfterExit=yes ExecStart=/usr/libexec/greenboot/greenboot-rpm-ostree-grub2-check-fallback +PrivateMounts=yes [Install] RequiredBy=greenboot-healthcheck.service diff --git a/usr/libexec/greenboot/greenboot-grub2-set-counter b/usr/libexec/greenboot/greenboot-grub2-set-counter index 1547a806..0b35ac29 100755 --- a/usr/libexec/greenboot/greenboot-grub2-set-counter +++ b/usr/libexec/greenboot/greenboot-grub2-set-counter @@ -14,7 +14,31 @@ elif [ -n "$GREENBOOT_MAX_BOOT_ATTEMPTS" ]; then else max_boot_attempts=3 # default to 3 attempts fi -grub2-editenv - set boot_counter="$max_boot_attempts" -grub2-editenv - set boot_success=0 + +# Remount /boot as read-only if it was mounted as read-write +if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 +fi + +if ! /usr/bin/grub2-editenv - set boot_counter="$max_boot_attempts"; then + # If the first command fails, remount /boot as read-only and exit with failure + if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 + fi +exit 1 +fi + +if ! /usr/bin/grub2-editenv /boot/grub2/grubenv set boot_success=0; then + # If the first command fails, remount /boot as read-only and exit with failure + if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 + fi + exit 1 +fi + +# Remount /boot as read-only if it was mounted as read-write +if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 +fi echo "<3>GRUB2 environment variables have been set for system upgrade. Max boot attempts is $max_boot_attempts" diff --git a/usr/libexec/greenboot/greenboot-grub2-set-success b/usr/libexec/greenboot/greenboot-grub2-set-success new file mode 100644 index 00000000..be75a7f3 --- /dev/null +++ b/usr/libexec/greenboot/greenboot-grub2-set-success @@ -0,0 +1,33 @@ +#!/bin/bash + +set -eo pipefail + +# Check if /boot is mounted as read-only, and remount as read-write if necessary +if grep -q " /boot .* ro," /proc/mounts; then + mount -o remount,rw /boot || exit 1 +fi + +# Run the grub2-editenv commands +if ! /usr/bin/grub2-editenv /boot/grub2/grubenv set boot_success=1; then + # If the first command fails, remount /boot as read-only and exit with failure + if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 + fi + exit 1 +fi + +if ! /usr/bin/grub2-editenv /boot/grubenv unset boot_counter; then + # If the second command fails, remount /boot as read-only and exit with failure + if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 + fi + exit 1 +fi + +# Remount /boot as read-only if it was mounted as read-write +if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 +fi + +# If everything succeeded, exit with success +exit 0 diff --git a/usr/libexec/greenboot/greenboot-rpm-ostree-grub2-check-fallback b/usr/libexec/greenboot/greenboot-rpm-ostree-grub2-check-fallback index bbe25f66..6193a15a 100755 --- a/usr/libexec/greenboot/greenboot-rpm-ostree-grub2-check-fallback +++ b/usr/libexec/greenboot/greenboot-rpm-ostree-grub2-check-fallback @@ -1,6 +1,11 @@ #!/bin/bash set -euo pipefail +# Check if /boot is mounted as read-only, and remount as read-write if necessary +if grep -q " /boot .* ro," /proc/mounts; then + mount -o remount,rw /boot || exit 1 +fi + # Determine if the current boot is a fallback boot # If booted into fallback deployment, clean up bootloader entries (rollback) if grub2-editenv list | grep -q "^boot_counter=-1$"; then @@ -12,5 +17,18 @@ if grub2-editenv list | grep -q "^boot_counter=-1$"; then echo "<3>Health check logs from previous boot:" echo "<3>$prev_logs" fi - grub2-editenv - unset boot_counter + + if ! /usr/bin/grub2-editenv - unset boot_counter; then + # If the above command fails, remount /boot as read-only and exit with failure + if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 + fi + exit 1 + fi + fi + +# Remount /boot as read-only if it was mounted as read-write +if grep -q " /boot .* rw," /proc/mounts; then + mount -o remount,ro /boot || exit 1 +fi \ No newline at end of file