mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-26 09:54:47 +00:00
Three production `unsafe` blocks carried no `// SAFETY:` comment at all (`libc::fallocate`, `libc::sysinfo`, `libc::statvfs`), and nothing made that an error: `clippy::undocumented_unsafe_blocks` is a `restriction` lint, allow-by-default, and appeared nowhere in either crate. Turn it on in `seaweed-volume`'s `[lints.clippy]` and in the worker workspace's `[workspace.lints.clippy]`, then document what each block relies on. `memory_status.rs` and `disk_location.rs` get their blocks narrowed to the `zeroed()` and the libc call, so each comment sits next to the operation it justifies and the arithmetic is outside the block. Both turn the success test into an early return on failure; the casts, the multiplication order and the values returned on either path are unchanged. The bigger problem was in `config.rs`'s tests. `with_temp_env_var` and `with_cleared_security_env` called `std::env::set_var`/`remove_var`, claiming soundness because every caller holds `process_state_lock()`. That mutex only serialises the fourteen annotated tests in this module. The same lib test binary runs the `grpc_server.rs` tests, which bind a `TcpListener`, dial loopback and drive a multi-thread tokio runtime, and tonic/hyper/rustls/aws-sdk all read the environment lazily on those threads — which is exactly the race Rust 2024 made these calls unsafe for. `restore_env_var` had no SAFETY comment at all. `#[serial]` would not have helped: it serialises annotated tests, which the mutex already did. So the config layer no longer reads the environment implicitly. An `EnvLookup<'a> = &'a dyn Fn(&str) -> Option<OsString>` is threaded from the public entry points down to every reader — `HOME`, `USERPROFILE`, the twenty-four `WEED_*` keys and `SEAWEED_WRITE_QUEUE`. `parse_cli` and `parse_security_config` keep their signatures and pass `process_env`, a thin wrapper over `std::env::var_os`; `resolve_config` becomes `resolve_config_with_env` (private, one caller). Tests build one with `fake_env` instead, so no test touches the real environment and every `unsafe` in the module is gone. `process_state_lock()` stays, with a smaller job: `set_current_dir` is safe but still process-global, so the tests that move the working directory are still serialised against the ones that read it. Tests naming an explicit config file never reach that search and no longer take the lock. No production behaviour changes: the same keys are read in the same order with the same precedence, and `env_string` reproduces `std::env::var(key).ok()` — absent and non-UTF-8 both read as unset. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
41 lines
1.5 KiB
TOML
41 lines
1.5 KiB
TOML
# Rust plugin workers for SeaweedFS.
|
|
#
|
|
# `core` is the plugin.proto contract and nothing else; a worker crate beside it
|
|
# supplies job handlers and a binary. Adding a worker means adding a member here,
|
|
# not touching the protocol. `sort` is neither: it is the sort specification the
|
|
# sorting jobs share, so that two of them cannot drift on what an order means.
|
|
[workspace]
|
|
resolver = "2"
|
|
members = ["crates/core", "crates/lance", "crates/sort"]
|
|
|
|
[workspace.package]
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
# The edition needs 1.85; the dependency tree needs more. Verified with
|
|
# `cargo +1.94.1 check --all-targets` (1.94.0 fails on the AWS SDK that
|
|
# lance's `aws` feature pulls in).
|
|
rust-version = "1.94.1"
|
|
|
|
[workspace.lints.clippy]
|
|
# Protobuf message literals keep `..Default::default()` on purpose: it is
|
|
# what lets a proto gain a field without touching every constructor.
|
|
needless_update = "allow"
|
|
# Every `unsafe` block states its precondition, right above the block.
|
|
undocumented_unsafe_blocks = "warn"
|
|
|
|
[workspace.dependencies]
|
|
anyhow = "1"
|
|
async-trait = "0.1"
|
|
prost = "0.14"
|
|
prost-types = "0.14"
|
|
tokio = { version = "1", features = ["full"] }
|
|
tokio-stream = "0.1"
|
|
tonic = { version = "0.14", features = ["tls-aws-lc"] }
|
|
tonic-prost = "0.14"
|
|
# Already in the tree via tonic; named here so the metrics server can use them.
|
|
axum = "0.8"
|
|
prometheus = { version = "0.13", default-features = false }
|
|
tonic-prost-build = "0.14"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|