Skip to content

Commit

Permalink
app_persistency: allow readonly persistency
Browse files Browse the repository at this point in the history
The permissions of the persistency file are checked for read only.
If the file is read only, write-back to file system will be disabled.
  • Loading branch information
svenrademakers committed Sep 25, 2024
1 parent 50aa48f commit 8164f03
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bmcd"
version = "2.3.2"
version = "2.3.3"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.75.0"
Expand Down
53 changes: 37 additions & 16 deletions src/persistency/app_persistency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use anyhow::Context;
use futures::future::Either;
use tokio::fs::{File, OpenOptions};
use tokio::time::sleep_until;
use tracing::warn;
const BIN_DATA: &str = "/var/lib/bmcd/bmcd.bin";

#[derive(Debug)]
Expand Down Expand Up @@ -73,14 +74,18 @@ impl PersistencyBuilder {

#[derive(Debug)]
struct MonitorContext {
pub file: PathBuf,
pub file: Option<PathBuf>,
pub inner: PersistencyStore,
}

impl MonitorContext {
pub async fn commit_to_file(&self) -> anyhow::Result<MonitorEvent> {
tracing::debug!("commiting persistency to disk");
let mut new = self.file.clone();
let Some(ref file) = self.file else {
return Ok(MonitorEvent::PersistencyWritten);
};

let mut new = file.clone();
new.set_extension("new");

let pending = OpenOptions::new()
Expand All @@ -91,7 +96,7 @@ impl MonitorContext {
.await?;
self.inner.write(pending.into_std().await).await?;

tokio::fs::rename(&new, &self.file).await.with_context(|| {
tokio::fs::rename(&new, &file).await.with_context(|| {
format!(
"error writing persistency binary. backup available at: {}",
new.to_string_lossy()
Expand All @@ -104,9 +109,11 @@ impl MonitorContext {
pub async fn sync_all(&self) -> anyhow::Result<()> {
if self.inner.is_dirty() {
self.commit_to_file().await?;
let file = File::open(&self.file).await?;
file.sync_all().await?;
tracing::info!("persistency synced");
if let Some(f) = &self.file {
let file = File::open(&f).await?;
file.sync_all().await?;
tracing::info!("persistency synced");
}
}
Ok(())
}
Expand Down Expand Up @@ -138,10 +145,14 @@ impl ApplicationPersistency {
tokio::fs::create_dir_all(&parent).await?;
}

let can_write = !std::fs::metadata(&path)
.map(|m| m.permissions().readonly())
.unwrap_or_default();

let empty = Empty::default();
let serialized_file = OpenOptions::new()
.read(true)
.write(true)
.write(can_write)
.create(true)
.truncate(false)
.open(&path)
Expand All @@ -158,17 +169,27 @@ impl ApplicationPersistency {
}
};

let context = Arc::new(MonitorContext { file: path, inner });
let clone = context.clone();
tokio::spawn(async move {
if let Err(e) =
Self::filesystem_writer(write_timeout.unwrap_or(Duration::from_millis(100)), clone)
.await
{
tracing::error!("{:#}", e);
}
let context = Arc::new(MonitorContext {
file: can_write.then_some(path),
inner,
});

if can_write {
let clone = context.clone();
tokio::spawn(async move {
if let Err(e) = Self::filesystem_writer(
write_timeout.unwrap_or(Duration::from_millis(100)),
clone,
)
.await
{
tracing::error!("{:#}", e);
}
});
} else {
warn!("persistency is read only");
};

Ok(Self { context })
}

Expand Down

0 comments on commit 8164f03

Please sign in to comment.