aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/Cargo.toml2
-rw-r--r--src/block/Cargo.toml2
-rw-r--r--src/db/Cargo.toml2
-rw-r--r--src/db/lib.rs8
-rw-r--r--src/db/lmdb_adapter.rs10
-rw-r--r--src/db/sqlite_adapter.rs32
-rw-r--r--src/db/test.rs4
-rw-r--r--src/garage/Cargo.toml2
-rw-r--r--src/garage/cli/layout.rs36
-rw-r--r--src/model/Cargo.toml2
-rw-r--r--src/model/garage.rs2
-rw-r--r--src/net/Cargo.toml2
-rw-r--r--src/rpc/Cargo.toml2
-rw-r--r--src/rpc/layout/mod.rs2
-rw-r--r--src/table/Cargo.toml2
-rw-r--r--src/util/Cargo.toml2
-rw-r--r--src/web/Cargo.toml2
17 files changed, 55 insertions, 59 deletions
diff --git a/src/api/Cargo.toml b/src/api/Cargo.toml
index a5645c26..85b78a5b 100644
--- a/src/api/Cargo.toml
+++ b/src/api/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_api"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/block/Cargo.toml b/src/block/Cargo.toml
index 7eb6bca8..1af4d7f5 100644
--- a/src/block/Cargo.toml
+++ b/src/block/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_block"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/db/Cargo.toml b/src/db/Cargo.toml
index ef5a8659..0a278bc0 100644
--- a/src/db/Cargo.toml
+++ b/src/db/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_db"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/db/lib.rs b/src/db/lib.rs
index d6057505..3485745a 100644
--- a/src/db/lib.rs
+++ b/src/db/lib.rs
@@ -274,12 +274,12 @@ impl<'a> Transaction<'a> {
tree: &Tree,
key: T,
value: U,
- ) -> TxOpResult<Option<Value>> {
+ ) -> TxOpResult<()> {
self.tx.insert(tree.1, key.as_ref(), value.as_ref())
}
/// Returns the old value if there was one
#[inline]
- pub fn remove<T: AsRef<[u8]>>(&mut self, tree: &Tree, key: T) -> TxOpResult<Option<Value>> {
+ pub fn remove<T: AsRef<[u8]>>(&mut self, tree: &Tree, key: T) -> TxOpResult<()> {
self.tx.remove(tree.1, key.as_ref())
}
/// Clears all values in a tree
@@ -362,8 +362,8 @@ pub(crate) trait ITx {
fn get(&self, tree: usize, key: &[u8]) -> TxOpResult<Option<Value>>;
fn len(&self, tree: usize) -> TxOpResult<usize>;
- fn insert(&mut self, tree: usize, key: &[u8], value: &[u8]) -> TxOpResult<Option<Value>>;
- fn remove(&mut self, tree: usize, key: &[u8]) -> TxOpResult<Option<Value>>;
+ fn insert(&mut self, tree: usize, key: &[u8], value: &[u8]) -> TxOpResult<()>;
+ fn remove(&mut self, tree: usize, key: &[u8]) -> TxOpResult<()>;
fn clear(&mut self, tree: usize) -> TxOpResult<()>;
fn iter(&self, tree: usize) -> TxOpResult<TxValueIter<'_>>;
diff --git a/src/db/lmdb_adapter.rs b/src/db/lmdb_adapter.rs
index 436a67fa..de4c3910 100644
--- a/src/db/lmdb_adapter.rs
+++ b/src/db/lmdb_adapter.rs
@@ -252,17 +252,15 @@ impl<'a> ITx for LmdbTx<'a> {
Ok(tree.len(&self.tx)? as usize)
}
- fn insert(&mut self, tree: usize, key: &[u8], value: &[u8]) -> TxOpResult<Option<Value>> {
+ fn insert(&mut self, tree: usize, key: &[u8], value: &[u8]) -> TxOpResult<()> {
let tree = *self.get_tree(tree)?;
- let old_val = tree.get(&self.tx, key)?.map(Vec::from);
tree.put(&mut self.tx, key, value)?;
- Ok(old_val)
+ Ok(())
}
- fn remove(&mut self, tree: usize, key: &[u8]) -> TxOpResult<Option<Value>> {
+ fn remove(&mut self, tree: usize, key: &[u8]) -> TxOpResult<()> {
let tree = *self.get_tree(tree)?;
- let old_val = tree.get(&self.tx, key)?.map(Vec::from);
tree.delete(&mut self.tx, key)?;
- Ok(old_val)
+ Ok(())
}
fn clear(&mut self, tree: usize) -> TxOpResult<()> {
let tree = *self.get_tree(tree)?;
diff --git a/src/db/sqlite_adapter.rs b/src/db/sqlite_adapter.rs
index 5a142117..9c9a668d 100644
--- a/src/db/sqlite_adapter.rs
+++ b/src/db/sqlite_adapter.rs
@@ -192,7 +192,7 @@ impl IDb for SqliteDb {
let db = self.db.get()?;
let lock = self.write_lock.lock();
- let n = db.execute(&format!("DELETE FROM {} WHERE k = ?1", tree), params![key])?;
+ db.execute(&format!("DELETE FROM {} WHERE k = ?1", tree), params![key])?;
drop(lock);
Ok(())
@@ -336,31 +336,17 @@ impl<'a> ITx for SqliteTx<'a> {
}
}
- fn insert(&mut self, tree: usize, key: &[u8], value: &[u8]) -> TxOpResult<Option<Value>> {
+ fn insert(&mut self, tree: usize, key: &[u8], value: &[u8]) -> TxOpResult<()> {
let tree = self.get_tree(tree)?;
- let old_val = self.internal_get(tree, key)?;
-
- let sql = match &old_val {
- Some(_) => format!("UPDATE {} SET v = ?2 WHERE k = ?1", tree),
- None => format!("INSERT INTO {} (k, v) VALUES (?1, ?2)", tree),
- };
- let n = self.tx.execute(&sql, params![key, value])?;
- assert_eq!(n, 1);
-
- Ok(old_val)
+ let sql = format!("INSERT OR REPLACE INTO {} (k, v) VALUES (?1, ?2)", tree);
+ self.tx.execute(&sql, params![key, value])?;
+ Ok(())
}
- fn remove(&mut self, tree: usize, key: &[u8]) -> TxOpResult<Option<Value>> {
+ fn remove(&mut self, tree: usize, key: &[u8]) -> TxOpResult<()> {
let tree = self.get_tree(tree)?;
- let old_val = self.internal_get(tree, key)?;
-
- if old_val.is_some() {
- let n = self
- .tx
- .execute(&format!("DELETE FROM {} WHERE k = ?1", tree), params![key])?;
- assert_eq!(n, 1);
- }
-
- Ok(old_val)
+ self.tx
+ .execute(&format!("DELETE FROM {} WHERE k = ?1", tree), params![key])?;
+ Ok(())
}
fn clear(&mut self, tree: usize) -> TxOpResult<()> {
let tree = self.get_tree(tree)?;
diff --git a/src/db/test.rs b/src/db/test.rs
index e3b7badf..26b816b8 100644
--- a/src/db/test.rs
+++ b/src/db/test.rs
@@ -21,7 +21,7 @@ fn test_suite(db: Db) {
let res = db.transaction::<_, (), _>(|tx| {
assert_eq!(tx.get(&tree, ka).unwrap().unwrap(), va);
- assert_eq!(tx.insert(&tree, ka, vb).unwrap().unwrap(), va);
+ assert_eq!(tx.insert(&tree, ka, vb).unwrap(), ());
assert_eq!(tx.get(&tree, ka).unwrap().unwrap(), vb);
@@ -33,7 +33,7 @@ fn test_suite(db: Db) {
let res = db.transaction::<(), _, _>(|tx| {
assert_eq!(tx.get(&tree, ka).unwrap().unwrap(), vb);
- assert_eq!(tx.insert(&tree, ka, vc).unwrap().unwrap(), vb);
+ assert_eq!(tx.insert(&tree, ka, vc).unwrap(), ());
assert_eq!(tx.get(&tree, ka).unwrap().unwrap(), vc);
diff --git a/src/garage/Cargo.toml b/src/garage/Cargo.toml
index 9cc71abd..483e33c0 100644
--- a/src/garage/Cargo.toml
+++ b/src/garage/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/garage/cli/layout.rs b/src/garage/cli/layout.rs
index f76e33c5..68ace193 100644
--- a/src/garage/cli/layout.rs
+++ b/src/garage/cli/layout.rs
@@ -358,7 +358,7 @@ pub async fn cmd_layout_history(
if layout.versions.len() > 1 {
println!("==== UPDATE TRACKERS ====");
- println!("Several layout versions are currently live in the version, and data is being migrated.");
+ println!("Several layout versions are currently live in the cluster, and data is being migrated.");
println!(
"This is the internal data that Garage stores to know which nodes have what data."
);
@@ -377,15 +377,27 @@ pub async fn cmd_layout_history(
table[1..].sort();
format_table(table);
+ let min_ack = layout
+ .update_trackers
+ .ack_map
+ .min_among(&all_nodes, layout.min_stored());
+
println!();
println!(
"If some nodes are not catching up to the latest layout version in the update trackers,"
);
println!("it might be because they are offline or unable to complete a sync successfully.");
- println!(
- "You may force progress using `garage layout skip-dead-nodes --version {}`",
- layout.current().version
- );
+ if min_ack < layout.current().version {
+ println!(
+ "You may force progress using `garage layout skip-dead-nodes --version {}`",
+ layout.current().version
+ );
+ } else {
+ println!(
+ "You may force progress using `garage layout skip-dead-nodes --version {} --allow-missing-data`.",
+ layout.current().version
+ );
+ }
} else {
println!("Your cluster is currently in a stable state with a single live layout version.");
println!("No metadata migration is in progress. Note that the migration of data blocks is not tracked,");
@@ -426,15 +438,15 @@ pub async fn cmd_layout_skip_dead_nodes(
let all_nodes = layout.get_all_nodes();
let mut did_something = false;
for node in all_nodes.iter() {
- if status.iter().any(|x| x.id == *node && x.is_up) {
- continue;
- }
-
- if layout.update_trackers.ack_map.set_max(*node, opt.version) {
- println!("Increased the ACK tracker for node {:?}", node);
- did_something = true;
+ // Update ACK tracker for dead nodes or for all nodes if --allow-missing-data
+ if opt.allow_missing_data || !status.iter().any(|x| x.id == *node && x.is_up) {
+ if layout.update_trackers.ack_map.set_max(*node, opt.version) {
+ println!("Increased the ACK tracker for node {:?}", node);
+ did_something = true;
+ }
}
+ // If --allow-missing-data, update SYNC tracker for all nodes.
if opt.allow_missing_data {
if layout.update_trackers.sync_map.set_max(*node, opt.version) {
println!("Increased the SYNC tracker for node {:?}", node);
diff --git a/src/model/Cargo.toml b/src/model/Cargo.toml
index 25926080..12931a4c 100644
--- a/src/model/Cargo.toml
+++ b/src/model/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_model"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/model/garage.rs b/src/model/garage.rs
index 363b02dd..29e0bddd 100644
--- a/src/model/garage.rs
+++ b/src/model/garage.rs
@@ -141,7 +141,7 @@ impl Garage {
)?)
.ok()
.and_then(|x| NetworkKey::from_slice(&x))
- .ok_or_message("Invalid RPC secret key: expected 32 bits of entropy, please check the documentation for requirements")?;
+ .ok_or_message("Invalid RPC secret key: expected 32 bytes of random hex, please check the documentation for requirements")?;
let (replication_factor, consistency_mode) = parse_replication_mode(&config)?;
diff --git a/src/net/Cargo.toml b/src/net/Cargo.toml
index c12b39a4..686aaaea 100644
--- a/src/net/Cargo.toml
+++ b/src/net/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_net"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/rpc/Cargo.toml b/src/rpc/Cargo.toml
index 4c8cafd9..acde0911 100644
--- a/src/rpc/Cargo.toml
+++ b/src/rpc/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_rpc"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/rpc/layout/mod.rs b/src/rpc/layout/mod.rs
index 33676c37..aafdea46 100644
--- a/src/rpc/layout/mod.rs
+++ b/src/rpc/layout/mod.rs
@@ -455,7 +455,7 @@ impl UpdateTracker {
}
}
- pub(crate) fn min_among(&self, storage_nodes: &[Uuid], min_version: u64) -> u64 {
+ pub fn min_among(&self, storage_nodes: &[Uuid], min_version: u64) -> u64 {
storage_nodes
.iter()
.map(|x| self.get(x, min_version))
diff --git a/src/table/Cargo.toml b/src/table/Cargo.toml
index 171118ea..e704cd3c 100644
--- a/src/table/Cargo.toml
+++ b/src/table/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_table"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/util/Cargo.toml b/src/util/Cargo.toml
index 883c0aa4..da3e39b8 100644
--- a/src/util/Cargo.toml
+++ b/src/util/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_util"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml
index f097755c..d810d6f9 100644
--- a/src/web/Cargo.toml
+++ b/src/web/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_web"
-version = "1.0.0"
+version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>", "Quentin Dufour <quentin@dufour.io>"]
edition = "2018"
license = "AGPL-3.0"