Skip to content

Commit

Permalink
Merge pull request #497 from amazonlinux/tough-datastore-locking
Browse files Browse the repository at this point in the history
tough: Add locking around datastore write operations
  • Loading branch information
iliana authored Nov 8, 2019
2 parents 0fc51ed + 334a5de commit e1d4edc
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
24 changes: 20 additions & 4 deletions workspaces/updater/tough/src/datastore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,29 @@ use snafu::ResultExt;
use std::fs::{self, File};
use std::io::{ErrorKind, Read};
use std::path::Path;
use std::sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};

#[derive(Debug, Clone)]
pub(crate) struct Datastore<'a>(pub(crate) &'a Path);
pub(crate) struct Datastore<'a>(Arc<RwLock<&'a Path>>);

impl<'a> Datastore<'a> {
pub(crate) fn new(path: &'a Path) -> Self {
Self(Arc::new(RwLock::new(path)))
}

// Because we are not actually changing the underlying data in the lock, we can ignore when a
// lock is poisoned.

fn read(&self) -> RwLockReadGuard<'_, &'a Path> {
self.0.read().unwrap_or_else(PoisonError::into_inner)
}

fn write(&self) -> RwLockWriteGuard<'_, &'a Path> {
self.0.write().unwrap_or_else(PoisonError::into_inner)
}

pub(crate) fn reader(&self, file: &str) -> Result<Option<impl Read>> {
let path = self.0.join(file);
let path = self.read().join(file);
match File::open(&path) {
Ok(file) => Ok(Some(file)),
Err(err) => match err.kind() {
Expand All @@ -21,7 +37,7 @@ impl<'a> Datastore<'a> {
}

pub(crate) fn create<T: Serialize>(&self, file: &str, value: &T) -> Result<()> {
let path = self.0.join(file);
let path = self.write().join(file);
serde_json::to_writer_pretty(
File::create(&path).context(error::DatastoreCreate { path: &path })?,
value,
Expand All @@ -33,7 +49,7 @@ impl<'a> Datastore<'a> {
}

pub(crate) fn remove(&self, file: &str) -> Result<()> {
let path = self.0.join(file);
let path = self.write().join(file);
match fs::remove_file(&path) {
Ok(()) => Ok(()),
Err(err) => match err.kind() {
Expand Down
2 changes: 1 addition & 1 deletion workspaces/updater/tough/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl<'a, T: Transport> Repository<'a, T> {
let metadata_base_url = parse_url(settings.metadata_base_url)?;
let target_base_url = parse_url(settings.target_base_url)?;

let datastore = Datastore(settings.datastore);
let datastore = Datastore::new(settings.datastore);

// 0. Load the trusted root metadata file + 1. Update the root metadata file
let root = load_root(
Expand Down

0 comments on commit e1d4edc

Please sign in to comment.