From e6223aab73cac9ead0eefec3927ed5804c3203e7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 20 Dec 2024 08:37:11 -0500 Subject: [PATCH] rhsm: Use atomic_write Just noticed this when reading the code; our cap-std-ext crate has a handy `atomic_write` API which streamlines exactly this use case. This avoids having a corrupted/half-written facts file if our process is interrupted, and also avoids a case where a reading process may temporarily see a half written file. Signed-off-by: Colin Walters --- lib/src/rhsm.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/src/rhsm.rs b/lib/src/rhsm.rs index 2ba477b1..fbb850a8 100644 --- a/lib/src/rhsm.rs +++ b/lib/src/rhsm.rs @@ -1,8 +1,8 @@ //! Integration with Red Hat Subscription Manager -use anyhow::Result; -use cap_std::fs::{Dir, OpenOptions}; -use cap_std_ext::cap_std; +use anyhow::{Context, Result}; +use cap_std::fs::Dir; +use cap_std_ext::{cap_std, dirext::CapStdExtDirExt}; use fn_error_context::context; use serde::Serialize; @@ -96,11 +96,11 @@ pub(crate) async fn publish_facts(root: &Dir) -> Result<()> { let (_deployments, host) = crate::status::get_status(&sysroot, booted_deployment.as_ref())?; let facts = RhsmFacts::from(host.status); - let mut bootc_facts_file = root.open_with( - FACTS_PATH, - OpenOptions::new().write(true).create(true).truncate(true), - )?; - serde_json::to_writer_pretty(&mut bootc_facts_file, &facts)?; + root.atomic_replace_with(FACTS_PATH, |w| { + serde_json::to_writer_pretty(w, &facts)?; + anyhow::Ok(()) + }) + .with_context(|| format!("Writing {FACTS_PATH}"))?; Ok(()) }