diff --git a/src/backup/chunk_store.rs b/src/backup/chunk_store.rs index 12826216..fc9d3670 100644 --- a/src/backup/chunk_store.rs +++ b/src/backup/chunk_store.rs @@ -1,13 +1,11 @@ use failure::*; + use std::path::{Path, PathBuf}; use std::io::{Read, Write}; -use std::time::Duration; +use std::sync::{Arc, Mutex}; +use std::os::unix::io::AsRawFd; use openssl::sha; -use std::sync::Mutex; - -use std::fs::File; -use std::os::unix::io::AsRawFd; use crate::tools; @@ -35,7 +33,7 @@ pub struct ChunkStore { pub (crate) base: PathBuf, chunk_dir: PathBuf, mutex: Mutex, - _lockfile: File, + locker: Arc>, } // TODO: what about sysctl setting vm.vfs_cache_pressure (0 - 100) ? @@ -131,15 +129,13 @@ impl ChunkStore { let mut lockfile_path = base.clone(); lockfile_path.push(".lock"); - // make sure only one process/thread/task can use it - let lockfile = tools::open_file_locked( - lockfile_path, Duration::from_secs(10))?; + let locker = tools::ProcessLocker::new(&lockfile_path)?; Ok(ChunkStore { name: name.to_owned(), base, chunk_dir, - _lockfile: lockfile, + locker, mutex: Mutex::new(false) }) } @@ -369,6 +365,14 @@ impl ChunkStore { pub fn base_path(&self) -> PathBuf { self.base.clone() } + + pub fn try_shared_lock(&self) -> Result { + tools::ProcessLocker::try_shared_lock(self.locker.clone()) + } + + pub fn try_exclusive_lock(&self) -> Result { + tools::ProcessLocker::try_exclusive_lock(self.locker.clone()) + } } diff --git a/src/backup/datastore.rs b/src/backup/datastore.rs index 3c0222ca..ca078798 100644 --- a/src/backup/datastore.rs +++ b/src/backup/datastore.rs @@ -227,6 +227,8 @@ impl DataStore { if let Ok(ref mut _mutex) = self.gc_mutex.try_lock() { + let _exclusive_lock = self.chunk_store.try_exclusive_lock()?; + let mut gc_status = GarbageCollectionStatus::default(); gc_status.used_bytes = 0; diff --git a/src/backup/dynamic_index.rs b/src/backup/dynamic_index.rs index 195fd0bc..91994aa7 100644 --- a/src/backup/dynamic_index.rs +++ b/src/backup/dynamic_index.rs @@ -340,6 +340,8 @@ impl std::io::Seek for BufferedDynamicReader { pub struct DynamicIndexWriter { store: Arc, + _lock: tools::ProcessLockSharedGuard, + chunker: Chunker, writer: BufWriter, closed: bool, @@ -366,6 +368,8 @@ impl DynamicIndexWriter { pub fn create(store: Arc, path: &Path, chunk_size: usize) -> Result { + let shared_lock = store.try_shared_lock()?; + let full_path = store.relative_path(path); let mut tmp_path = full_path.clone(); tmp_path.set_extension("tmp_didx"); @@ -400,6 +404,7 @@ impl DynamicIndexWriter { Ok(Self { store, + _lock: shared_lock, chunker: Chunker::new(chunk_size), writer: writer, closed: false, diff --git a/src/backup/fixed_index.rs b/src/backup/fixed_index.rs index c8880ab7..869ecbe9 100644 --- a/src/backup/fixed_index.rs +++ b/src/backup/fixed_index.rs @@ -175,6 +175,7 @@ impl IndexFile for FixedIndexReader { pub struct FixedIndexWriter { store: Arc, + _lock: tools::ProcessLockSharedGuard, filename: PathBuf, tmp_filename: PathBuf, chunk_size: usize, @@ -204,6 +205,8 @@ impl FixedIndexWriter { pub fn create(store: Arc, path: &Path, size: usize, chunk_size: usize) -> Result { + let shared_lock = store.try_shared_lock()?; + let full_path = store.relative_path(path); let mut tmp_path = full_path.clone(); tmp_path.set_extension("tmp_fidx"); @@ -250,6 +253,7 @@ impl FixedIndexWriter { Ok(Self { store, + _lock: shared_lock, filename: full_path, tmp_filename: tmp_path, chunk_size,