From 8d8f9b69ee9a9a56fd03955a95f7a11a5214c3ba Mon Sep 17 00:00:00 2001 From: Bruce Leidl Date: Mon, 4 Oct 2021 06:09:26 -0400 Subject: [PATCH] Add citadel.revert-rootfs boot option Forces booting from the older rootfs partition in case the newer partition is broken or unbootable. --- citadel-tool/src/boot/rootfs.rs | 28 ++++++++++++++++++++++++++-- libcitadel/src/cmdline.rs | 2 ++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/citadel-tool/src/boot/rootfs.rs b/citadel-tool/src/boot/rootfs.rs index 0c2f5e7..55b853c 100644 --- a/citadel-tool/src/boot/rootfs.rs +++ b/citadel-tool/src/boot/rootfs.rs @@ -5,7 +5,7 @@ use libcitadel::{BlockDev, ResourceImage, CommandLine, ImageHeader, Partition, R use libcitadel::verity::Verity; pub fn setup_rootfs() -> Result<()> { - let mut p = choose_boot_partiton(true)?; + let mut p = choose_boot_partiton(true, CommandLine::revert_rootfs())?; if CommandLine::noverity() { setup_partition_unverified(&p) } else { @@ -75,7 +75,26 @@ fn setup_linear_mapping(blockdev: &Path) -> Result<()> { Ok(()) } -fn choose_boot_partiton(scan: bool) -> Result { +fn is_revertible_partition(best: &Option, partition: &Partition) -> bool { + if !is_bootable(partition) { + return false; + } + match best { + Some(p) => p.path() != partition.path(), + None => true, + } +} + +fn choose_revert_partition(best: Option) -> Option { + for p in Partition::rootfs_partitions().unwrap_or(Vec::new()) { + if is_revertible_partition(&best, &p) { + return Some(p); + } + } + best +} + +fn choose_boot_partiton(scan: bool, revert_rootfs: bool) -> Result { let mut partitions = Partition::rootfs_partitions()?; if scan { @@ -88,6 +107,11 @@ fn choose_boot_partiton(scan: bool) -> Result { for p in partitions { best = compare_boot_partitions(best, p); } + + if revert_rootfs { + best = choose_revert_partition(best); + } + best.ok_or_else(|| format_err!("No partition found to boot from").into()) } diff --git a/libcitadel/src/cmdline.rs b/libcitadel/src/cmdline.rs index b0f7070..6f56c2d 100644 --- a/libcitadel/src/cmdline.rs +++ b/libcitadel/src/cmdline.rs @@ -61,6 +61,8 @@ impl CommandLine { pub fn overlay() -> bool { Self::var_exists("citadel.overlay") } + pub fn revert_rootfs() -> bool { Self::var_exists("citadel.revert-rootfs") } + /// Return `true` if sealed realmfs images are enabled on kernel command line pub fn sealed() -> bool { Self::var_exists("citadel.sealed") }