From d33fb72fcb0e196848ba7f5529dd9b7494107e80 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Thu, 11 Jul 2024 18:55:59 +0800 Subject: [PATCH] filetree: add failpoint when doing exchange Inspired by https://github.com/coreos/bootupd/pull/669#issuecomment-2220760948 --- Cargo.lock | 12 ++++++++++++ Cargo.toml | 1 + src/failpoints.rs | 21 +++++++++++++++++++++ src/filetree.rs | 4 +++- src/main.rs | 1 + tests/e2e-update/e2e-update-in-vm.sh | 5 +++++ 6 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/failpoints.rs diff --git a/Cargo.lock b/Cargo.lock index e802f4a3..237fd3de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,6 +78,7 @@ dependencies = [ "chrono", "clap", "env_logger", + "fail", "fn-error-context", "fs2", "hex", @@ -234,6 +235,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "fail" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5e43d0f78a42ad591453aedb1d7ae631ce7ee445c7643691055a9ed8d3b01c" +dependencies = [ + "log", + "once_cell", + "rand", +] + [[package]] name = "fastrand" version = "2.0.1" diff --git a/Cargo.toml b/Cargo.toml index 1f7c9eac..02059c55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ camino = "1.1.7" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" +fail = { version = "0.5", features = ["failpoints"] } fn-error-context = "0.2.1" fs2 = "0.4.3" hex = "0.4.3" diff --git a/src/failpoints.rs b/src/failpoints.rs new file mode 100644 index 00000000..78dce44f --- /dev/null +++ b/src/failpoints.rs @@ -0,0 +1,21 @@ +//! Wrappers and utilities on top of the `fail` crate. +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/// TODO: Use https://github.com/tikv/fail-rs/pull/68 once it merges +/// copy from https://github.com/coreos/rpm-ostree/commit/aa8d7fb0ceaabfaf10252180e2ddee049d07aae3#diff-adcc419e139605fae34d17b31418dbaf515af2fe9fb766fcbdb2eaad862b3daa +#[macro_export] +macro_rules! try_fail_point { + ($name:expr) => {{ + if let Some(e) = fail::eval($name, |msg| { + let msg = msg.unwrap_or_else(|| "synthetic failpoint".to_string()); + anyhow::Error::msg(msg) + }) { + return Err(From::from(e)); + } + }}; + ($name:expr, $cond:expr) => {{ + if $cond { + $crate::try_fail_point!($name); + } + }}; +} diff --git a/src/filetree.rs b/src/filetree.rs index 047ca384..7985e6dc 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -328,6 +328,7 @@ pub(crate) fn apply_diff( diff: &FileTreeDiff, opts: Option<&ApplyUpdateOptions>, ) -> Result<()> { + println!("{diff:?}"); let default_opts = ApplyUpdateOptions { ..Default::default() }; @@ -382,6 +383,7 @@ pub(crate) fn apply_diff( .with_context(|| format!("copying {:?} to {:?}", path, path_tmp))?; } + println!("{updates:?}"); // do local exchange or rename for (dst, tmp) in updates.iter() { let dst = dst.as_std_path(); @@ -395,6 +397,7 @@ pub(crate) fn apply_diff( .local_rename(tmp, dst) .with_context(|| format!("rename for {} and {:?}", tmp, dst))?; } + crate::try_fail_point!("exchange"); } // Ensure all of the updates & changes are written persistently to disk if !opts.skip_sync { @@ -705,7 +708,6 @@ mod tests { let b_btime_foo_new = fs::metadata(pb.join(foo))?.created()?; assert_eq!(b_btime_foo_new, b_btime_foo); } - Ok(()) } } diff --git a/src/main.rs b/src/main.rs index b075bde0..6691f26f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ mod component; mod coreos; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; +mod failpoints; mod filesystem; mod filetree; #[cfg(any( diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index fd969cad..8b1b3028 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -67,6 +67,11 @@ tmpefimount=$(mount_tmp_efi) assert_not_has_file ${tmpefimount}/EFI/fedora/test-bootupd.efi +if env FAILPOINTS='exchange=return' bootupctl update -vvv 2>err.txt; then + fatal "should have errored" +fi +assert_file_has_content_literal err.txt "error: synthetic failpoint" + bootupctl update | tee out.txt assert_file_has_content out.txt "Previous EFI: .*" assert_file_has_content out.txt "Updated EFI: ${TARGET_GRUB_PKG}.*,test-bootupd-payload-1.0"