Skip to content

Commit a2050d1

Browse files
authored
Merge pull request #28 from ThinkParQ/rb/mirror-root-inode
Require all nodes being shut down when mirroring the root inode & various fixes
2 parents 14b6851 + bbf4fae commit a2050d1

File tree

4 files changed

+44
-19
lines changed

4 files changed

+44
-19
lines changed

about.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
accepted = ["MIT", "Apache-2.0", "ISC", "BSD-3-Clause", "Unicode-3.0", "OpenSSL", "Zlib"]
2-
workarounds = ["ring"]
1+
accepted = ["MIT", "Apache-2.0", "ISC", "BSD-3-Clause", "Unicode-3.0", "Zlib"]
32
targets = ["x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl"]
43
private = { ignore = true }

deny.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ feature-depth = 1
7171
# A list of advisory IDs to ignore. Note that ignored advisories will still
7272
# output a note when they are encountered.
7373
ignore = [
74+
{ id = "RUSTSEC-2025-0069", reason = "We use only a small subset of that unmaintained daemonize crate and it's unlikely to change (if it does this needs to be reconsidered)" },
7475
#"RUSTSEC-0000-0000",
7576
#{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" },
7677
#"[email protected]", # you can also ignore yanked crate versions if you wish
@@ -89,7 +90,7 @@ ignore = [
8990
# List of explicitly allowed licenses
9091
# See https://spdx.org/licenses/ for list of possible licenses
9192
# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
92-
allow = ["MIT", "Apache-2.0", "ISC", "BSD-3-Clause", "Unicode-3.0", "OpenSSL", "Zlib"]
93+
allow = ["MIT", "Apache-2.0", "ISC", "BSD-3-Clause", "Unicode-3.0", "Zlib"]
9394

9495
# The confidence threshold for detecting a license from license text.
9596
# The higher the value, the more closely the license text must be to the
@@ -107,20 +108,20 @@ exceptions = [
107108
# Some crates don't have (easily) machine readable licensing information,
108109
# adding a clarification entry for it allows you to manually specify the
109110
# licensing information
110-
[[licenses.clarify]]
111+
# [[licenses.clarify]]
111112
# The package spec the clarification applies to
112-
crate = "ring"
113+
# crate = "ring"
113114
# The SPDX expression for the license requirements of the crate
114-
expression = "MIT AND ISC AND OpenSSL"
115+
# expression = "MIT AND ISC"
115116
# One or more files in the crate's source used as the "source of truth" for
116117
# the license expression. If the contents match, the clarification will be used
117118
# when running the license check, otherwise the clarification will be ignored
118119
# and the crate will be checked normally, which may produce warnings or errors
119120
# depending on the rest of your configuration
120-
license-files = [
121+
# license-files = [
121122
# Each entry is a crate relative path, and the (opaque) hash of its contents
122-
{ path = "LICENSE", hash = 0xbd0eed23 }
123-
]
123+
# { path = "LICENSE", hash = 0xbd0eed23 }
124+
# ]
124125

125126
[licenses.private]
126127
# If true, ignores workspace crates that aren't published, or are only

mgmtd/src/db/import_v7.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,12 @@ pub fn import_v7(tx: &rusqlite::Transaction, base_path: &Path) -> Result<()> {
6565
fn check_format_conf(f: &Path) -> Result<()> {
6666
let s = std::fs::read_to_string(f)?;
6767

68-
// No need for fancy parsing, we only allow upgrading from this exact file
69-
if s != "# This file was auto-generated. Do not modify it!
70-
version=5
71-
nodeStates=1
72-
targetStates=1
73-
"
74-
{
75-
bail!("Unexpected format.conf:\n{s}");
68+
if s.matches("version").count() != 1 {
69+
bail!("Unexpected version in format.conf: version field ambiguous or not found");
70+
}
71+
72+
if !s.contains("\nversion=5\n") {
73+
bail!("Unexpected version in format.conf: Expected \"version=5\"");
7674
}
7775

7876
Ok(())

mgmtd/src/grpc/buddy_group.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,10 @@ pub(crate) async fn mirror_root_inode(
235235
needs_license(&ctx, LicensedFeature::Mirroring)?;
236236
fail_on_pre_shutdown(&ctx)?;
237237

238+
let offline_timeout = ctx.info.user_config.node_offline_timeout.as_secs();
238239
let meta_root = ctx
239240
.db
240-
.read_tx(|tx| {
241+
.read_tx(move |tx| {
241242
let node_uid = match db::misc::get_meta_root(tx)? {
242243
MetaRoot::Normal(_, node_uid) => node_uid,
243244
MetaRoot::Mirrored(_) => bail!("Root inode is already mirrored"),
@@ -267,7 +268,33 @@ pub(crate) async fn mirror_root_inode(
267268
})?;
268269

269270
if clients > 0 {
270-
bail!("This operation requires that all clients are disconnected/unmounted, but still has {clients} clients mounted.");
271+
bail!(
272+
"This operation requires that all clients are disconnected/unmounted. \
273+
{clients} clients are still mounted."
274+
);
275+
}
276+
277+
let mut server_stmt = tx.prepare(sql!(
278+
"SELECT COUNT(*) FROM nodes
279+
WHERE node_type = ?1 AND UNIXEPOCH('now') - UNIXEPOCH(last_contact) < ?2
280+
AND node_uid != ?3"
281+
))?;
282+
283+
let metas = server_stmt.query_row(
284+
params![NodeType::Meta.sql_variant(), offline_timeout, node_uid],
285+
|row| row.get::<_, i64>(0),
286+
)?;
287+
let storages = server_stmt.query_row(
288+
params![NodeType::Storage.sql_variant(), offline_timeout, node_uid],
289+
|row| row.get::<_, i64>(0),
290+
)?;
291+
292+
if metas > 0 || storages > 0 {
293+
bail!(
294+
"This operation requires that all nodes except the root meta node are shut \
295+
down. {metas} meta nodes (excluding the root meta node) and {storages} storage nodes have \
296+
communicated during the last {offline_timeout}s."
297+
);
271298
}
272299

273300
Ok(node_uid)

0 commit comments

Comments
 (0)