From d0a0d1028c9940d78e0e86f49e28dbe685cca75c Mon Sep 17 00:00:00 2001 From: Karl Engelhardt Date: Mon, 28 Sep 2020 17:32:21 +0200 Subject: [PATCH 1/3] Set quota in logfile instead of removing it from map If we remove it from the map, all existing data is overwritten on the next insert operation. --- src/lib.rs | 2 +- src/logfile.rs | 15 +++++++++++++++ src/logfile_map.rs | 14 +++++++++----- src/quota.rs | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ca523d9..caf5af9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -116,7 +116,7 @@ impl Sensorlog { Ok(measurements) } - pub fn set_storage_quota_for(&mut self, sensor_id: &str, quota: ::quota::StorageQuota) { + pub fn set_storage_quota_for(&mut self, sensor_id: &str, quota: ::quota::StorageQuota) -> Result<(), Error> { let logfile_id = LogfileID::from_string(sensor_id.to_string()); self.logfile_map.set_storage_quota_for(&logfile_id, quota) } diff --git a/src/logfile.rs b/src/logfile.rs index 4a05a9d..6543bf5 100644 --- a/src/logfile.rs +++ b/src/logfile.rs @@ -173,6 +173,21 @@ impl Logfile { let reader = LogfileReader::new(&storage_locked.partitions); reader.fetch_measurements(time_start, time_limit, limit) } + + pub fn set_storage_quota(&self, quota: StorageQuota) -> Result<(), ::Error> { + if quota.is_zero() { + return Err(err_quota!("insufficient quota")); + } + + // lock the storage + let mut storage_locked = match self.storage.write() { + Ok(l) => l, + Err(_) => fatal!("lock is poisoned"), + }; + storage_locked.storage_quota = quota; + + Ok(()) + } } impl LogfileStorage { diff --git a/src/logfile_map.rs b/src/logfile_map.rs index 41c529a..25ef0ce 100644 --- a/src/logfile_map.rs +++ b/src/logfile_map.rs @@ -86,13 +86,17 @@ impl LogfileMap { Ok(logfile) } - pub fn set_storage_quota_for(&mut self, logfile_id: &LogfileID, quota: ::quota::StorageQuota) { - self.config.set_storage_quota_for(&logfile_id, quota); - // grab write lock - let mut logfiles_locked = match self.logfiles.write() { + pub fn set_storage_quota_for(&mut self, logfile_id: &LogfileID, quota: ::quota::StorageQuota) -> Result<(), ::Error> { + self.config.set_storage_quota_for(&logfile_id, quota.clone()); + + let logfiles_locked = match self.logfiles.read() { Ok(l) => l, Err(_) => fatal!("lock is poisoned"), }; - logfiles_locked.remove(&logfile_id.get_string()); + if let Some(logfile) = logfiles_locked.get(&logfile_id.get_string()) { + logfile.set_storage_quota(quota)?; + } + + Ok(()) } } diff --git a/src/quota.rs b/src/quota.rs index 446d9c2..051330d 100644 --- a/src/quota.rs +++ b/src/quota.rs @@ -19,7 +19,7 @@ * of said person’s immediate fault when using the work as intended. */ -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum StorageQuota { Unlimited, Limited { limit_bytes: u64 }, From 611d264e722daa7b017c2022b14e0d7361c2873a Mon Sep 17 00:00:00 2001 From: Karl Engelhardt Date: Mon, 28 Sep 2020 17:35:15 +0200 Subject: [PATCH 2/3] Bugfix: Make sure currently used partition is not delted This bug was triggered, when a storage quota < partition_size_bytes_default was set. The garbage collection marked the '0' partition to be deleted. After that the file was written, and then the marked partitions deleted, removing the just written data and leading to a corrupt storage. --- src/logfile.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/logfile.rs b/src/logfile.rs index 6543bf5..253af27 100644 --- a/src/logfile.rs +++ b/src/logfile.rs @@ -150,8 +150,13 @@ impl Logfile { storage_locked.allocate(measurement_size)?; // insert the new measurement into the head partition - match storage_locked.partitions.last_mut() { - Some(p) => p.append_measurement(measurement)?, + match &mut storage_locked.partitions.last_mut() { + Some(p) => { + p.append_measurement(measurement)?; + let part_name = p.get_file_name(); + // Make sure that the currently used partition is not in self.deleted_partition + storage_locked.partitions_deleted.retain(|x| x.get_file_name() != part_name); + }, None => return Err(err_server!("corrupt partition map")), }; From 150db6f5c53f48b4d26315936016555e17c2ebe7 Mon Sep 17 00:00:00 2001 From: Karl Engelhardt Date: Mon, 28 Sep 2020 18:04:31 +0200 Subject: [PATCH 3/3] Bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d904dc..1be4c3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -418,7 +418,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "sensorlog" -version = "1.0.0" +version = "1.1.0" dependencies = [ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 5419837..b3a78df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "sensorlog" description = "A lightweight data logging service" repository = "https://github.com/nyantec.sensorlog" -version = "1.0.0" +version = "1.1.0" authors = ["The sensorlog Authors "] license = "MirOS"