Skip to content

Commit 2c63434

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

File tree

7 files changed

+30
-21
lines changed

7 files changed

+30
-21
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: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,6 @@ pub(crate) fn get_sorted_uki_boot_entries<'a>(str: &'a mut String) -> Result<Vec
813813
parse_grub_menuentry_file(str)
814814
}
815815

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

crates/lib/src/install.rs

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

20542054
pub(crate) const COMPOSEFS_TRANSIENT_STATE_DIR: &str = "/run/composefs";
2055-
pub(crate) const COMPOSEFS_STAGED_DEPLOYMENT_PATH: &str = "/run/composefs/staged-deployment";
2055+
/// File created in /run/composefs to record a staged-deployment
2056+
pub(crate) const COMPOSEFS_STAGED_DEPLOYMENT_FNAME: &str = "staged-deployment";
20562057
/// Relative to /sysroot
20572058
pub(crate) const STATE_DIR_RELATIVE: &str = "state/deploy";
20582059

@@ -2094,25 +2095,32 @@ pub(crate) fn write_composefs_state(
20942095
.section(ORIGIN_KEY_BOOT)
20952096
.item(ORIGIN_KEY_BOOT_TYPE, boot_type);
20962097

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

2101-
origin_file
2102-
.write(config.to_string().as_bytes())
2101+
state_dir
2102+
.atomic_write(
2103+
format!("{}.origin", deployment_id.to_hex()),
2104+
config.to_string().as_bytes(),
2105+
)
21032106
.context("Falied to write to .origin file")?;
21042107

21052108
if staged {
21062109
std::fs::create_dir_all(COMPOSEFS_TRANSIENT_STATE_DIR)
21072110
.with_context(|| format!("Creating {COMPOSEFS_TRANSIENT_STATE_DIR}"))?;
21082111

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

2115-
file.write_all(deployment_id.to_hex().as_bytes())?;
2118+
staged_depl_dir
2119+
.atomic_write(
2120+
COMPOSEFS_STAGED_DEPLOYMENT_FNAME,
2121+
deployment_id.to_hex().as_bytes(),
2122+
)
2123+
.with_context(|| format!("Writing to {COMPOSEFS_STAGED_DEPLOYMENT_FNAME}"))?;
21162124
}
21172125

21182126
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)