Skip to content

Commit c17dfe9

Browse files
composefs/state: Use atomic writes for origin and staged deployment files
Signed-off-by: Johan-Liebert1 <[email protected]>
1 parent 0b43a0b commit c17dfe9

File tree

7 files changed

+32
-22
lines changed

7 files changed

+32
-22
lines changed

crates/lib/src/bls_config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use serde::{Deserialize, Deserializer};
1+
use anyhow::Result;
22
use serde::de::Error;
3+
use serde::{Deserialize, Deserializer};
34
use std::collections::HashMap;
4-
use anyhow::Result;
55

66
#[derive(Debug, Deserialize, Eq)]
77
pub(crate) struct BLSConfig {

crates/lib/src/deploy.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,8 @@ pub(crate) fn rollback_composefs_uki() -> Result<()> {
788788
.context("renameat")?;
789789

790790
tracing::debug!("Removing {USER_CFG_ROLLBACK}");
791-
rustix::fs::unlinkat(&entries_dir, USER_CFG_ROLLBACK, AtFlags::REMOVEDIR).context("unlinkat")?;
791+
rustix::fs::unlinkat(&entries_dir, USER_CFG_ROLLBACK, AtFlags::REMOVEDIR)
792+
.context("unlinkat")?;
792793

793794
tracing::debug!("Syncing to disk");
794795
fsync(
@@ -813,7 +814,6 @@ pub(crate) fn get_sorted_uki_boot_entries<'a>(str: &'a mut String) -> Result<Vec
813814
parse_grub_menuentry_file(str)
814815
}
815816

816-
817817
#[context("Getting boot entries")]
818818
pub(crate) fn get_sorted_bls_boot_entries(ascending: bool) -> Result<Vec<BLSConfig>> {
819819
let mut all_configs = vec![];

crates/lib/src/install.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,7 +2049,8 @@ fn setup_composefs_boot(root_setup: &RootSetup, state: &State, image_id: &str) -
20492049
}
20502050

20512051
pub(crate) const COMPOSEFS_TRANSIENT_STATE_DIR: &str = "/run/composefs";
2052-
pub(crate) const COMPOSEFS_STAGED_DEPLOYMENT_PATH: &str = "/run/composefs/staged-deployment";
2052+
/// File created in /run/composefs to record a staged-deployment
2053+
pub(crate) const COMPOSEFS_STAGED_DEPLOYMENT_FNAME: &str = "staged-deployment";
20532054
/// Relative to /sysroot
20542055
pub(crate) const STATE_DIR_RELATIVE: &str = "state/deploy";
20552056

@@ -2091,25 +2092,32 @@ pub(crate) fn write_composefs_state(
20912092
.section(ORIGIN_KEY_BOOT)
20922093
.item(ORIGIN_KEY_BOOT_TYPE, boot_type);
20932094

2094-
let mut origin_file =
2095-
std::fs::File::create(state_path.join(format!("{}.origin", deployment_id.to_hex())))
2096-
.context("Failed to open .origin file")?;
2095+
let state_dir = cap_std::fs::Dir::open_ambient_dir(&state_path, cap_std::ambient_authority())
2096+
.context("Opening state dir")?;
20972097

2098-
origin_file
2099-
.write(config.to_string().as_bytes())
2098+
state_dir
2099+
.atomic_write(
2100+
format!("{}.origin", deployment_id.to_hex()),
2101+
config.to_string().as_bytes(),
2102+
)
21002103
.context("Falied to write to .origin file")?;
21012104

21022105
if staged {
21032106
std::fs::create_dir_all(COMPOSEFS_TRANSIENT_STATE_DIR)
21042107
.with_context(|| format!("Creating {COMPOSEFS_TRANSIENT_STATE_DIR}"))?;
21052108

2106-
let mut file = std::fs::OpenOptions::new()
2107-
.write(true)
2108-
.create(true)
2109-
.open(COMPOSEFS_STAGED_DEPLOYMENT_PATH)
2110-
.context("Opening staged-deployment file")?;
2109+
let staged_depl_dir = cap_std::fs::Dir::open_ambient_dir(
2110+
COMPOSEFS_TRANSIENT_STATE_DIR,
2111+
cap_std::ambient_authority(),
2112+
)
2113+
.with_context(|| format!("Opening {COMPOSEFS_TRANSIENT_STATE_DIR}"))?;
21112114

2112-
file.write_all(deployment_id.to_hex().as_bytes())?;
2115+
staged_depl_dir
2116+
.atomic_write(
2117+
COMPOSEFS_STAGED_DEPLOYMENT_FNAME,
2118+
deployment_id.to_hex().as_bytes(),
2119+
)
2120+
.with_context(|| format!("Writing to {COMPOSEFS_STAGED_DEPLOYMENT_FNAME}"))?;
21132121
}
21142122

21152123
Ok(())

crates/lib/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! to provide a fully "container native" tool for using
55
//! bootable container images.
66
7+
mod bls_config;
78
mod boundimage;
89
pub mod cli;
910
pub(crate) mod deploy;
@@ -18,6 +19,7 @@ pub(crate) mod kargs;
1819
mod lints;
1920
mod lsm;
2021
pub(crate) mod metadata;
22+
pub(crate) mod parsers;
2123
mod podman;
2224
mod progress_jsonl;
2325
mod reboot;
@@ -27,8 +29,6 @@ mod status;
2729
mod store;
2830
mod task;
2931
mod utils;
30-
mod bls_config;
31-
pub(crate) mod parsers;
3232

3333
#[cfg(feature = "docgen")]
3434
mod docgen;

crates/lib/src/spec.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ pub struct BootEntryOstree {
165165
pub deploy_serial: u32,
166166
}
167167

168-
169168
/// A bootable entry
170169
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
171170
#[serde(rename_all = "camelCase")]

crates/lib/src/status.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ use crate::deploy::get_sorted_uki_boot_entries;
2929
use crate::install::BootType;
3030
use crate::install::ORIGIN_KEY_BOOT;
3131
use crate::install::ORIGIN_KEY_BOOT_TYPE;
32-
use crate::install::{COMPOSEFS_STAGED_DEPLOYMENT_PATH, STATE_DIR_RELATIVE};
32+
use crate::install::{
33+
COMPOSEFS_STAGED_DEPLOYMENT_FNAME, COMPOSEFS_TRANSIENT_STATE_DIR, STATE_DIR_RELATIVE,
34+
};
3335
use crate::spec::ImageStatus;
3436
use crate::spec::{BootEntry, BootOrder, Host, HostSpec, HostStatus, HostType};
3537
use crate::spec::{ImageReference, ImageSignature};
@@ -412,7 +414,9 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
412414

413415
let mut host = Host::new(host_spec);
414416

415-
let staged_deployment_id = match std::fs::File::open(COMPOSEFS_STAGED_DEPLOYMENT_PATH) {
417+
let staged_deployment_id = match std::fs::File::open(format!(
418+
"{COMPOSEFS_TRANSIENT_STATE_DIR}/{COMPOSEFS_STAGED_DEPLOYMENT_FNAME}"
419+
)) {
416420
Ok(mut f) => {
417421
let mut s = String::new();
418422
f.read_to_string(&mut s)?;

crates/ostree-ext/src/container_utils.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ pub fn ostree_booted() -> io::Result<bool> {
7777
Path::new(&format!("/{OSTREE_BOOTED}")).try_exists()
7878
}
7979

80-
8180
/// Returns true if the system appears to have been booted with composefs without ostree.
8281
pub fn composefs_booted() -> io::Result<bool> {
8382
let cmdline = std::fs::read_to_string("/proc/cmdline")?;

0 commit comments

Comments
 (0)