From 84e24e76731e4e81b8449cd0058fc7d40c218868 Mon Sep 17 00:00:00 2001 From: Hauser Date: Thu, 29 Oct 2026 13:02:21 +0800 Subject: [PATCH] chore(deps): refresh crates and adopt released aws-sigv4 (#9047) * chore(deps): refresh crates and adopt released aws-sigv4 Run two update/upgrade rounds for the main and standalone fuzz workspaces. Replace the temporary SigV4a Git override with aws-sigv4 1.6.4 from the registry and remove its obsolete source permission. Pin OpenID Connect to e20ddbb01ca68356f2979bc125f5613ab45b4e7e. Upgrade async-nats to 0.51.0, hotpath to 0.30.0, libunftp to 0.24.0, and the TOML test dependency to 1.1.8. Retain Arrow/Parquet 59.3.2 for DataFusion 55.2.0 and keep the fuzz PKCS#1 version compatible with pinned RSA rc.18. Co-Authored-By: heihutu Co-Authored-By: zhi22915 * fix(deps): retain safe openidconnect pin against HMAC panic The e20ddbb pin verifies HMAC signatures with mac.verify(signature.into()), which panics in generic-array on malformed length instead of returning InvalidIdentityToken. Retain the previous reviewed pin that uses verify_slice and add a malformed-signature regression covering HS256, HS384, and HS512. * chore(deps): upgrade sysinfo to 0.40.0 Update the main and standalone fuzz lockfiles. Adapt fallible system queries, CPU usage accessors, and OS-native network interface names. Preserve process sampling fallbacks and report unavailable diagnostic sources without panicking. Cover missing host and process collectors. Validation: 167 focused tests passed; production and all five fuzz targets passed cargo check. Formatting, logging guardrails, and the existing dependency policy passed. Linux and Windows runtime checks were not run. Co-Authored-By: heihutu Co-Authored-By: zhi22915 * fix(ci): use the admin error facade for sysinfo failures Keep the sysinfo initialization error behind the existing admin S3 facade. The facade builds the same error code and message without expanding the direct S3 error-macro surface guarded by the migration ratchet. Validation: S3 footprint guard, formatting, whitespace, and production cargo check with sftp, hotpath, and connect_top_net passed. Co-Authored-By: heihutu Co-Authored-By: zhi22915 * chore(deps): refresh hotpath and ctutils (#9055) Run two cargo update/upgrade rounds in both the main and fuzz workspaces on top of PR #9047. Upgrade the hotpath family to 0.30.1 and ctutils to 0.4.7. Retain fuzz pkcs1 0.8.0-rc.4 for the pinned RSA 0.10.0-rc.18; rc.5 fails to compile against that RSA version. Validation: 1096 library tests passed with 19 skipped; upstream ctutils and hotpath-drain property/concurrency suites passed. Production and all five fuzz targets passed cargo check. Formatting, S3 footprint, and the existing dependency policy passed. Co-authored-by: heihutu Co-authored-by: zhi22915 --------- Co-authored-by: heihutu Co-authored-by: zhi22915 --- Cargo.lock | 298 ++++++++---------- Cargo.toml | 43 +-- crates/iam/src/oidc/provider_tests.rs | 63 ++++ crates/io-metrics/src/sampler/process.rs | 29 +- crates/madmin/src/health.rs | 30 +- .../object-data-cache/src/runtime_memory.rs | 4 +- .../src/metrics/collectors/system_process.rs | 14 +- crates/obs/src/metrics/scheduler.rs | 49 ++- crates/obs/src/metrics/stats_collector.rs | 35 +- crates/targets/src/sys/user_agent.rs | 6 +- crates/zstd-compat/Cargo.toml | 4 +- deny.toml | 3 - fuzz/Cargo.lock | 31 +- fuzz/Cargo.toml | 12 - rustfs/src/admin/handlers/diagnostics.rs | 24 +- rustfs/src/admin/handlers/profile_admin.rs | 2 +- rustfs/src/cgroup_resources.rs | 15 +- rustfs/src/config/info.rs | 73 +++-- rustfs/src/connect/diagnostics/top_net.rs | 9 +- rustfs/src/connect/environment.rs | 18 +- rustfs/tests/connect_top_net.rs | 2 +- 21 files changed, 431 insertions(+), 333 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 214140276..574dc3c15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 4 [[package]] name = "addr2line" -version = "0.25.1" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +checksum = "e567177890eb1617b1f774005b66b26b2377afd138a2ca37aae7d8f0c81429d4" dependencies = [ - "gimli 0.32.3", + "gimli 0.34.0", ] [[package]] @@ -286,7 +286,7 @@ dependencies = [ "crc32fast", "digest 0.11.3", "log", - "miniz_oxide 0.9.1", + "miniz_oxide", "num-bigint 0.4.8", "ouroboros", "quad-rand", @@ -721,9 +721,9 @@ dependencies = [ [[package]] name = "async-nats" -version = "0.50.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83a251fa1a4c9d0fe6e816b7acd60549e473e08d14f27a1d992c2675abff05f" +checksum = "a4f92759f418774b78c36ef07885849150ce950c67d9bcdeff8a9c253f57d9a1" dependencies = [ "aws-lc-rs", "base64 0.22.1", @@ -910,9 +910,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.18.2" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faac5829c2b74c28f830747e7818ccfb684261b5f48a1118b1e2a13d36dfab13" +checksum = "048006790404103c488e6c5616b3e7e702a71292aadda08e8f7698a9e0d2eb53" dependencies = [ "aws-lc-sys", "untrusted 0.7.1", @@ -921,9 +921,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.46.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1622d8446a2d4b2ce0c7eefc73dd43a99779028d5ee5c2dd8073a658ba8a2bc" +checksum = "8bfbe32ac36b3c428696ce315464181bc4029d689fd58e3f2a4e58c252242f52" dependencies = [ "cc", "cmake", @@ -960,9 +960,9 @@ dependencies = [ [[package]] name = "aws-sdk-kms" -version = "1.126.0" +version = "1.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c17ea00d100b3a51e9d7b7922baf2912977d66545038f2fa78553461f75a450" +checksum = "ef519fda62fd0fdc066948f5ef33ecb8ae1bf0187bf1a12e8a775c93c4c47e7e" dependencies = [ "arc-swap", "aws-credential-types", @@ -985,9 +985,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.155.0" +version = "1.156.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a542f0e9261b9ce56708d591a62062079fa3c58a362ffbf49a2e48a4f6ced16" +checksum = "1072c9aa20159b9b417115342d38c4c53108fc98e5359fcb86b7d4575747eb59" dependencies = [ "arc-swap", "aws-credential-types", @@ -1021,9 +1021,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.117.0" +version = "1.118.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5316813498fa9c403877007934ae448aa44b18136f58051f8fa3c5b79b44bdc6" +checksum = "b4a89786db8ee6dff2c9302a354ef081354fcb0f527e16ee3cb249a6a5cb6df7" dependencies = [ "arc-swap", "aws-credential-types", @@ -1046,9 +1046,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.119.0" +version = "1.120.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31db35e5662787b786daba15f431e4393c7ea512b70fa112bd048d1f3ecf877a" +checksum = "521c6a11a25f1244efddf947523f277a51a63f0a7ec228f0f62d826e88106366" dependencies = [ "arc-swap", "aws-credential-types", @@ -1071,9 +1071,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.122.0" +version = "1.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a10491638d9e560db90c484dbc77d73b8ad202780cdc9b9e92180603acb07ada" +checksum = "8754d38d29448bd1d4aa4a6312ed010dfa296b3436eb2c551cc6e42fc6a66a38" dependencies = [ "arc-swap", "aws-credential-types", @@ -1098,7 +1098,8 @@ dependencies = [ [[package]] name = "aws-sigv4" version = "1.6.4" -source = "git+https://github.com/smithy-lang/smithy-rs?rev=5c1c4bca2ea7af97496e077c9f1a718eaac64bf8#5c1c4bca2ea7af97496e077c9f1a718eaac64bf8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f385da9b7757ed4c8214797ad663ff534fb622006143530aa80e21f8e06ff85c" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -1166,9 +1167,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.64.2" +version = "0.64.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba8960956e0ee0ca3f3161e62913a61bc65a7ef638ca3ef1d4c7159f8443e398" +checksum = "19af609dd5edf8b056cd0bb001c706c8b3b1458055328b334ec13d7f46f6aaa8" dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", @@ -1187,9 +1188,9 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeca69f65362f7375891008ea525fd440ad6db1836458ac188c87b126804114e" +checksum = "859a81364f8185349c584fb41cd8765a400cf982f447adada590cf008a9f3b85" dependencies = [ "aws-smithy-async", "aws-smithy-protocol-test", @@ -1217,9 +1218,9 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.65.0" +version = "0.65.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6835fb38bc6fc8c91e584b0366eb4ff595e5c485134dbf4f0bdeaa18856666" +checksum = "b45f9fc77ffe92c92c341165a01a565bd30c39ecf5aa8c0719b41719009604f9" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-schema", @@ -1269,9 +1270,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cef0c41e8ca40f74f68ed8ee4d1ddbde12bb847b95ef9b3c025681ddfae58a" +checksum = "4cb80fb19c084da5fca9d797845735e184445e5b958599440d67529bf6ef1b64" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -1292,9 +1293,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.19.1" +version = "1.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06788004dea79018413f381891da6dcca23196acd79c4d51b767fbdacc76eae4" +checksum = "8c4e85cffe9944b10d576b075432bd8f98dbc081e8681cb37d5b2d87dc27bc84" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api-macros", @@ -1309,9 +1310,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api-macros" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221eaa237ddf1ca79b60d1372aad77e47f9c0ea5b3ce5099da8c61d027dc77b3" +checksum = "ce237f890a2283c9b328955c3b0918d2d5bf66a1cb6ceccd36a0047246fbc6e6" dependencies = [ "proc-macro2", "quote", @@ -1331,9 +1332,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55752025c39c0e094962fd73f1c57014b191f678612e517f219468e575af9822" +checksum = "cf183d70774ea2cfcc101ca74a8884e4c76be8b9df65cd303f6a1175c88e8f80" dependencies = [ "base64-simd", "bytes", @@ -1354,9 +1355,9 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.64.0" +version = "0.64.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6581618a2fd006159016d1c36881d94d61b4a017f4a8d631310875e18252413" +checksum = "590fdc1a70546b2f7f2061c42eaf173fb6f26d935330d069edc04dbd8f01d924" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-schema", @@ -1442,15 +1443,15 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +checksum = "42f4220217f3288537b83684130f42fad43320b1c3b805f1910d683d52ded24f" dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide 0.8.9", - "object 0.37.3", + "miniz_oxide", + "object 0.40.0", "rustc-demangle", "windows-link", ] @@ -1609,14 +1610,14 @@ dependencies = [ [[package]] name = "blazesym" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847a0a95b041ad5aae1bdc44f2bd54743f76eb0065c4f86b139f81343c287eaf" +checksum = "3b7b394f5f7049b06702df3207b82932e03e8de884b048670ee2516273a10880" dependencies = [ "cpp_demangle", "crc32fast", "flate2", - "gimli 0.33.0", + "gimli 0.34.0", "libc", "memmap2", "rustc-demangle", @@ -1743,9 +1744,9 @@ dependencies = [ [[package]] name = "brotli" -version = "9.1.0" +version = "9.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6737ce8b81460bf9407909f73ff50bf13f7cb8577e1e76715f57ed0eba58ba44" +checksum = "627b7cfb0578f0eafce087a90fcd40add1231900b69e4d4de2d456260a4f5d81" dependencies = [ "alloc-no-stdlib 3.0.0", "alloc-stdlib 0.3.0", @@ -2236,7 +2237,7 @@ version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cae36683101b2899f48bd31f8db9839437356188e3b1ff23096e73dab09ba8fe" dependencies = [ - "brotli 9.1.0", + "brotli 9.1.1", "bzip2", "compression-core", "flate2", @@ -2657,9 +2658,9 @@ dependencies = [ [[package]] name = "ctutils" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3e9d21d39e6f39ff46e03d5b621424f88ee23d8a1672c6bfc9ccc7f2da4f6a" +checksum = "a2376ffd6f96d8a9db59875b4b6b0237d6900b5baf64279714e05493ce64828a" dependencies = [ "cmov", "subtle", @@ -3797,9 +3798,9 @@ dependencies = [ [[package]] name = "dial9" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634f30ebbf229703503cd7c24c106bb832c26c80e4a4de0dff9d9e81bbd10c70" +checksum = "11185c62245c5ff61c753ec8ec3d56341a13fe4195344ecc100ce94f780533cc" dependencies = [ "bon", "dial9-core", @@ -3814,9 +3815,9 @@ dependencies = [ [[package]] name = "dial9-core" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "944efbaf9995121a93b92a9dacdbb6225332914215af1f08758ce3b9ec3a6693" +checksum = "54f1dcb5d20bdc85b9beb7c2864540526c1394c00783e9f3544feed1cfe529e8" dependencies = [ "ahash", "arc-swap", @@ -3837,9 +3838,9 @@ dependencies = [ [[package]] name = "dial9-macro" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4177b8f8bf95d8e3769c1aad596f5d6fb231953a45c4c3d2a5946fe8e4ec327b" +checksum = "bc225a6797592a51b6d68611927296ea582cf2317f62d6751d697ed2a2783f52" dependencies = [ "proc-macro2", "quote", @@ -3848,9 +3849,9 @@ dependencies = [ [[package]] name = "dial9-metrique" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aefb67b126274a6e0c31a82f624b347be1d531554d35766a2518b5eb04f1f40" +checksum = "56645773b4185f51a9528625a5aedcd4bbc5b5919ba68e7a6108cf076f635efc" dependencies = [ "dial9-core", "dial9-trace-format", @@ -3862,9 +3863,9 @@ dependencies = [ [[package]] name = "dial9-perf-self-profile" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ad6d9ce2232b6ba154d8fa19416594f65ce283233953eb716d0184e0d5eb3e1" +checksum = "00c8c96d18b28ec76adde2107f7d2d5f8bb53b0670fba31bc012841703bc49ca" dependencies = [ "blazesym", "bon", @@ -3881,9 +3882,9 @@ dependencies = [ [[package]] name = "dial9-tokio-telemetry" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e30fba16e95037d93825bad06f087e99f60babce447fd5f344d039540cd39a39" +checksum = "7ccc79f3683219471a8758b8ce459589167c55d72a649d27b89068a1a4cfffe9" dependencies = [ "bon", "bytes", @@ -3906,9 +3907,9 @@ dependencies = [ [[package]] name = "dial9-trace-format" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258116805212db80e607656c81d2bf9830e66d5747e6ed6a29d17eeb2e673ff2" +checksum = "44026339a4c6cbd4914c3eb85e653e741d5739f1e401695a039127ba49c19731" dependencies = [ "ahash", "dial9-trace-format-derive", @@ -3918,9 +3919,9 @@ dependencies = [ [[package]] name = "dial9-trace-format-derive" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b6700840c894de4a66d698850647560a1ae889183d419211877d049a063aad" +checksum = "bbdbf5c76eb6824b0576e6891811caae93fc0bc96c23003556e3f752d069a84d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4420,7 +4421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" dependencies = [ "crc32fast", - "miniz_oxide 0.9.1", + "miniz_oxide", "zlib-rs", ] @@ -4686,20 +4687,23 @@ dependencies = [ "zeroize", ] -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - [[package]] name = "gimli" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1033caf0b349c518623b5396bfb2cf0bddf44f0306d543a250e5743297aafd10" dependencies = [ "fnv", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "indexmap 2.14.2", "stable_deref_trait", ] @@ -5273,9 +5277,9 @@ dependencies = [ [[package]] name = "hotpath" -version = "0.29.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4af2b5ecf2650278fe33b0e49b68c8c484d2306475c127628316dea740cf5c" +checksum = "502dc37a7c218b9b1d3a0ccfb904da81d10d6dda0e899c722c503092d55576ea" dependencies = [ "arc-swap", "async-channel", @@ -5308,15 +5312,15 @@ dependencies = [ [[package]] name = "hotpath-drain" -version = "0.29.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5cceb6c15fbaaeb00b51acc7be7fad533d0b56cb422b1cfc16cf9ca1624d33a" +checksum = "0ea17d04c231b90b1f68a91f6f80fb0762c5dea07c611dce9ae157b56a50ff4c" [[package]] name = "hotpath-macros" -version = "0.29.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c0a42eb299ebb7ec6b9161489e5bf132603a34ca12cecadb8490937aa0492a" +checksum = "a76e0af911930fc97abc766b393b48cdca77fea9f5f6b388cf2123a6d9c30deb" dependencies = [ "proc-macro2", "quote", @@ -6165,9 +6169,9 @@ dependencies = [ [[package]] name = "libunftp" -version = "0.23.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc54288ecbf8beefa5cab3a9921ab03bf1f18a3a0872cbcdb5313fc0baebaeb" +checksum = "7d94587cfb90dd87b7cced3bff07d32cb56ad1192baa5d688dfaa8728f22d48d" dependencies = [ "async-trait", "bitflags 2.13.2", @@ -6179,10 +6183,11 @@ dependencies = [ "getrandom 0.4.3", "lazy_static", "moka", - "nix 0.30.1", + "nix 0.31.3", "prometheus", "proxy-protocol", "rustls", + "rustls-webpki", "slog", "slog-stdlog", "thiserror 2.0.21", @@ -6572,15 +6577,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "miniz_oxide" version = "0.9.1" @@ -6732,7 +6728,7 @@ dependencies = [ "tracing", "twox-hash", "url", - "webpki-roots 1.0.11", + "webpki-roots", ] [[package]] @@ -6830,18 +6826,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags 2.13.2", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "nix" version = "0.31.3" @@ -7124,15 +7108,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - [[package]] name = "object" version = "0.39.1" @@ -7245,9 +7220,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +checksum = "7e036b411754132fd6b74e94b74e9a13c5cf606fa93d1885c35860d3060820b1" [[package]] name = "opentelemetry" @@ -8377,7 +8352,7 @@ dependencies = [ "tracing", "url", "uuid", - "webpki-roots 1.0.11", + "webpki-roots", ] [[package]] @@ -9962,7 +9937,7 @@ dependencies = [ "tracing", "twox-hash", "uuid", - "webpki-roots 1.0.11", + "webpki-roots", ] [[package]] @@ -9985,7 +9960,7 @@ dependencies = [ "tokio-rustls", "tracing", "uuid", - "webpki-roots 1.0.11", + "webpki-roots", ] [[package]] @@ -10884,7 +10859,7 @@ version = "1.0.2" dependencies = [ "base64-simd", "blake2", - "brotli 9.1.0", + "brotli 9.1.1", "bytes", "convert_case 0.12.0", "crc-fast", @@ -10984,9 +10959,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +checksum = "e5e76742e5294153d4dde1207dbec5bdd81eef6fabdc0d2118babadabfd858aa" dependencies = [ "bitflags 2.13.2", "errno", @@ -12239,9 +12214,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.39.6" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2071df9448915b71c4fe6d25deaf1c22f12bd234f01540b77312bb8e41361e6" +checksum = "110e37d98880fd804cd47509b90a8444f7aaaab655ae625e83cd442a8bc2ebf2" dependencies = [ "libc", "memchr", @@ -12660,47 +12635,38 @@ dependencies = [ [[package]] name = "tokio-websockets" -version = "0.10.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f591660438b3038dd04d16c938271c79e7e06260ad2ea2885a4861bfb238605d" +checksum = "d52efb639344a7c6adb8e62c6f3d2c19c001ff1b79a5041ba1c6ed42e19c6aa5" dependencies = [ - "aws-lc-rs", "base64 0.22.1", "bytes", "futures-core", "futures-sink", "http 1.5.0", "httparse", - "rand 0.8.8", + "rand 0.10.3", "rustls-pki-types", + "sha1_smol", + "simdutf8", "tokio", "tokio-rustls", "tokio-util", - "webpki-roots 0.26.11", ] [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" +version = "1.1.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" dependencies = [ "indexmap 2.14.2", "serde_core", "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 0.7.15", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", + "winnow", ] [[package]] @@ -12719,9 +12685,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" dependencies = [ "indexmap 2.14.2", - "toml_datetime 1.1.2+spec-1.1.0", + "toml_datetime", "toml_parser", - "winnow 1.0.4", + "winnow", ] [[package]] @@ -12730,7 +12696,7 @@ version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" dependencies = [ - "winnow 1.0.4", + "winnow", ] [[package]] @@ -12741,9 +12707,9 @@ checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" [[package]] name = "tonic" -version = "0.14.6" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" +checksum = "cd1fa9b1a51188f3266a823208078315811269d06d272c3a61be0b9a194194ff" dependencies = [ "async-trait", "axum", @@ -12765,6 +12731,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-stream", + "tokio-util", "tower", "tower-layer", "tower-service", @@ -12773,9 +12740,9 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.6" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" +checksum = "2c07bd4e9f99e2a3ed8bebad596ae02a94e53745b68acc6900e22c3475c8bc44" dependencies = [ "prettyplease 0.2.37", "proc-macro2", @@ -12785,9 +12752,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.6" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" +checksum = "f63c616ffaa648f7c5dd5657e97d9a285fcb44ff3b70da761d436f5a13ff7be6" dependencies = [ "bytes", "prost 0.14.4", @@ -12796,9 +12763,9 @@ dependencies = [ [[package]] name = "tonic-prost-build" -version = "0.14.6" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27" +checksum = "4a05d8957fac6b3542999796cb4449d45da790751962f974a457e5e00c43d78c" dependencies = [ "prettyplease 0.2.37", "proc-macro2", @@ -13138,9 +13105,9 @@ checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +checksum = "ca718471876992059f251e33aafc334346ada08042b7661dd1fe313a9bced557" [[package]] name = "unicode-xid" @@ -13411,15 +13378,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "webpki-roots" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.11", -] - [[package]] name = "webpki-roots" version = "1.0.11" @@ -13765,12 +13723,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - [[package]] name = "winnow" version = "1.0.4" @@ -13858,9 +13810,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +checksum = "963d6fab92d5504b971dc8bd90ca743c2575e590bc8071ea5bc571598667ae08" dependencies = [ "libc", "rustix", @@ -14037,9 +13989,9 @@ dependencies = [ [[package]] name = "zip" -version = "9.1.2" +version = "9.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e3161de27091f18a831d9494e9c53378a34833af5c1dda35ad85849da18d6" +checksum = "1156b39d142a34b999c2310a50455e0cb3760bf7efad0122f796d813bee26ccb" dependencies = [ "aes 0.9.3", "bzip2", diff --git a/Cargo.toml b/Cargo.toml index 6b860b7d7..4b8a13784 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -149,7 +149,7 @@ async_zip = { default-features = false, version = "0.0.19" } mysql_async = { default-features = false, version = "0.37.1" } async-compression = { version = "0.4.51" } async-trait = "0.1.92" -async-nats = { version = "0.50.0", default-features = false } +async-nats = { version = "0.51.0", default-features = false } axum = "0.8.9" futures = "0.3.34" futures-core = "0.3.34" @@ -175,9 +175,9 @@ tokio-rustls = { default-features = false, version = "0.26.6" } tokio-stream = { version = "0.1.19" } tokio-test = "0.4.6" tokio-util = { version = "0.7.20" } -tonic = { version = "0.14.6" } -tonic-prost = { version = "0.14.6" } -tonic-prost-build = { version = "0.14.6" } +tonic = { version = "0.14.8" } +tonic-prost = { version = "0.14.8" } +tonic-prost-build = { version = "0.14.8" } tower = { version = "0.5.3" } tower-http = { version = "0.7.1" } h3 = "0.0.8" @@ -253,15 +253,15 @@ atoi = "3.1.1" atomic_enum = "0.3.0" aws-config = { version = "1.13.0" } aws-credential-types = { version = "1.3.1" } -aws-sdk-kms = { default-features = false, version = "1.126.0" } -aws-sdk-s3 = { default-features = false, version = "1.155.0" } -aws-sdk-sts = { default-features = false, version = "1.122.0" } +aws-sdk-kms = { default-features = false, version = "1.128.0" } +aws-sdk-s3 = { default-features = false, version = "1.156.0" } +aws-sdk-sts = { default-features = false, version = "1.123.0" } aws-smithy-async = { version = "1.3.1" } -aws-smithy-http-client = { default-features = false, version = "1.5.1" } -aws-smithy-runtime-api = { version = "1.19.1" } -aws-smithy-types = { version = "1.9.0" } +aws-smithy-http-client = { default-features = false, version = "1.5.2" } +aws-smithy-runtime-api = { version = "1.19.2" } +aws-smithy-types = { version = "1.9.1" } base64-simd = "0.8.0" -brotli = "9.1.0" +brotli = "9.1.1" clap = { version = "4.6.7" } const-str = { version = "1.1.0" } convert_case = "0.12.0" @@ -321,7 +321,7 @@ regex = { version = "1.13.1" } rumqttc = { package = "rumqttc-next", version = "0.34.0" } redis = { version = "1.8.0" } rustify = { version = "0.7", default-features = false } -rustix = { version = "1.1.5" } +rustix = { version = "1.1.6" } rust-embed = { version = "8.13.0" } rustc-hash = { version = "2.1.3" } s3s = { git = "https://github.com/s3s-project/s3s", rev = "5761ddfe4c509fcac87e3b99fd5bd9e176b442c0", features = ["minio"] } @@ -334,7 +334,7 @@ compact_str = "0.10.0" snap = "1.1.2" starshard = { version = "2.4.0" } strum = { version = "0.28.0" } -sysinfo = "0.39.6" +sysinfo = "0.40.0" temp-env = "0.3.6" tempfile = "3.27.0" test-case = "3.4.0" @@ -356,13 +356,13 @@ winapi-util = "0.1.11" windows = { version = "0.62.2" } windows-sys = "0.61.2" xxhash-rust = { version = "0.8.19" } -zip = "9.1.2" +zip = "9.1.3" zstd = "0.14.3" # Observability and Metrics metrics = "0.24.6" metrics-util = "0.20" -dial9 = { version = "0.5.5", default-features = false } +dial9 = { version = "0.5.6", default-features = false } opentelemetry = { version = "0.33.1" } opentelemetry-appender-tracing = { version = "0.33.1" } opentelemetry-otlp = { version = "0.33.1" } @@ -373,7 +373,7 @@ opentelemetry-stdout = { version = "0.33.1" } pyroscope = { version = "2.1.5" } # FTP and SFTP -libunftp = { version = "0.23.1" } +libunftp = { version = "0.24.0" } unftp-core = "0.1.0" suppaftp = { version = "12.2.1" } rcgen = { version = "0.14.10", default-features = false, features = ["aws_lc_rs", "crypto", "pem"] } @@ -386,7 +386,7 @@ dav-server = "0.11.0" # Performance Analysis and Memory Profiling rustfs-mimalloc = { version = "0.7.2" } # Preserve Unicode focus filters until rustfs/backlog#2302 is resolved. -hotpath = { version = "0.29.2", default-features = false } +hotpath = { version = "0.30.1", default-features = false } # Snapshot testing for output format regression detection insta = { version = "1.49" } @@ -431,12 +431,3 @@ zstd = { path = "crates/zstd-compat" } # Upstream: openidconnect-rs#244 and oauth2-rs#352. openidconnect = { git = "https://github.com/ramosbugs/openidconnect-rs", rev = "2f77ee73bc4554e1cb6279adb386005429fb4e41" } oauth2 = { git = "https://github.com/ramosbugs/oauth2-rs", rev = "89585f4a280afd7b285eaf1c9be0068874e03d22" } -aws-sigv4 = { git = "https://github.com/smithy-lang/smithy-rs", rev = "5c1c4bca2ea7af97496e077c9f1a718eaac64bf8" } - -# Keep the signer's path dependencies on the SDK's existing registry types. -[patch."https://github.com/smithy-lang/smithy-rs"] -aws-credential-types = { version = "=1.3.1" } -aws-smithy-eventstream = { version = "=0.61.6" } -aws-smithy-http = { version = "=0.64.2" } -aws-smithy-runtime-api = { version = "=1.19.1" } -aws-smithy-types = { version = "=1.9.0" } diff --git a/crates/iam/src/oidc/provider_tests.rs b/crates/iam/src/oidc/provider_tests.rs index 849b0d4d5..8aa240412 100644 --- a/crates/iam/src/oidc/provider_tests.rs +++ b/crates/iam/src/oidc/provider_tests.rs @@ -234,6 +234,69 @@ fn workload_verifier_preserves_algorithm_secret_and_audience_policy() { } } } +#[test] +fn configured_verifier_rejects_malformed_hmac_signature_lengths() { + let secret = "synthetic-oidc-hmac-regression-secret-0123456789-abcdefghijklmnopqrstuvwxyz"; + let mut config = build_mocked_oidc_provider_config("hmac", "https://issuer.example.com"); + config.client_secret = Some(secret.to_owned()); + let now = time::OffsetDateTime::now_utc().unix_timestamp(); + let payload = serde_json::json!({ + "iss": config.config_url, "sub": "synthetic-subject", "aud": config.client_id, + "iat": now, "exp": now + 300, + }); + + for (algorithm, name, signature_length) in [ + (Algorithm::HS256, "HS256", 32), + (Algorithm::HS384, "HS384", 48), + (Algorithm::HS512, "HS512", 64), + ] { + let signed = jsonwebtoken::encode(&Header::new(algorithm), &payload, &EncodingKey::from_secret(secret.as_bytes())) + .expect("sign a valid HMAC control token"); + let valid: CoreIdToken = signed.parse().expect("parse valid HMAC token"); + let (signing_input, signature) = signed.rsplit_once('.').expect("JWT signature segment"); + assert_eq!( + base64_simd::URL_SAFE_NO_PAD + .decode_to_vec(signature) + .expect("decode valid signature") + .len(), + signature_length + ); + + for workload in [false, true] { + let mut document = serde_json::json!({ + "issuer": config.config_url, "jwks_uri": "https://issuer.example.com/jwks", + "response_types_supported": ["id_token"], "subject_types_supported": ["public"], + "id_token_signing_alg_values_supported": [name], + }); + if !workload { + document["authorization_endpoint"] = serde_json::json!("https://issuer.example.com/authorize"); + } + let metadata = DiscoveredProviderMetadata::parse(&serde_json::to_vec(&document).expect("encode metadata"), true) + .expect("parse configured provider metadata"); + let verifier = metadata.verifier(&config); + assert!( + valid.claims(&verifier, |_: Option<&Nonce>| Ok(())).is_ok(), + "valid {name} token must pass for workload={workload}" + ); + + for length in [1, 0, signature_length - 1, signature_length, signature_length + 1, 128] { + let signature = base64_simd::URL_SAFE_NO_PAD.encode_to_string(vec![0_u8; length]); + let malformed: CoreIdToken = format!("{signing_input}.{signature}") + .parse() + .expect("invalid signature length must still reach cryptographic verification"); + assert!( + malformed.claims(&verifier, |_: Option<&Nonce>| Ok(())).is_err(), + "{name} signature length {length} must return an error for workload={workload}" + ); + } + assert!( + valid.claims(&verifier, |_: Option<&Nonce>| Ok(())).is_ok(), + "invalid inputs must not prevent later valid {name} verification" + ); + } + } +} + #[tokio::test] async fn workload_discovery_stops_after_forbidden_jwks() { let requests = Arc::new(std::sync::atomic::AtomicUsize::new(0)); diff --git a/crates/io-metrics/src/sampler/process.rs b/crates/io-metrics/src/sampler/process.rs index 6adff481f..dd8f041cc 100644 --- a/crates/io-metrics/src/sampler/process.rs +++ b/crates/io-metrics/src/sampler/process.rs @@ -25,7 +25,7 @@ fn current_pid() -> Pid { #[derive(Debug)] pub struct ProcessSampler { pid: Pid, - sys: System, + sys: Option, } impl Default for ProcessSampler { @@ -38,8 +38,10 @@ impl ProcessSampler { #[inline] pub fn new() -> Self { let pid = current_pid(); - let mut sys = System::new(); - sys.refresh_processes_specifics(ProcessesToUpdate::Some(&[pid]), true, ProcessRefreshKind::everything()); + let mut sys = System::new().ok(); + if let Some(sys) = sys.as_mut() { + sys.refresh_processes_specifics(ProcessesToUpdate::Some(&[pid]), true, ProcessRefreshKind::everything()); + } Self { pid, sys } } @@ -129,13 +131,14 @@ pub fn snapshot_process_resource_and_system() -> (ProcessResourceSnapshot, Proce pub fn snapshot_process_resource_and_system_with( sampler: &mut ProcessSampler, ) -> (ProcessResourceSnapshot, ProcessSystemSnapshot) { + let Some(sys) = sampler.sys.as_mut() else { + return (ProcessResourceSnapshot::default(), ProcessSystemSnapshot::default()); + }; let platform_stats = crate::snapshot_process_platform_stats(); let lock_snapshot = crate::snapshot_process_lock_counts(); - sampler - .sys - .refresh_processes_specifics(ProcessesToUpdate::Some(&[sampler.pid]), true, ProcessRefreshKind::everything()); + sys.refresh_processes_specifics(ProcessesToUpdate::Some(&[sampler.pid]), true, ProcessRefreshKind::everything()); - if let Some(process) = sampler.sys.process(sampler.pid) { + if let Some(process) = sys.process(sampler.pid) { let disk_usage = process.disk_usage(); let status = ProcessStatusSnapshot::from(process.status()); let uptime_seconds = process.run_time(); @@ -180,6 +183,18 @@ pub fn snapshot_process_resource_and_system_with( mod tests { use super::*; + #[test] + fn unavailable_process_source_returns_empty_snapshots() { + let mut sampler = ProcessSampler { + pid: current_pid(), + sys: None, + }; + assert_eq!( + sampler.snapshot_resource_and_system(), + (ProcessResourceSnapshot::default(), ProcessSystemSnapshot::default()) + ); + } + #[test] fn process_status_snapshot_maps_sysinfo_values() { assert_eq!(ProcessStatusSnapshot::from(ProcessStatus::Run), ProcessStatusSnapshot::Running); diff --git a/crates/madmin/src/health.rs b/crates/madmin/src/health.rs index d7d5b2bff..faad01246 100644 --- a/crates/madmin/src/health.rs +++ b/crates/madmin/src/health.rs @@ -64,7 +64,18 @@ pub struct Cpus { } pub fn get_cpus() -> Cpus { - let mut sys = System::new_all(); + let mut sys = match System::new_all() { + Ok(sys) => sys, + Err(error) => { + return Cpus { + node_common: NodeCommon { + error: Some(error.to_string()), + ..Default::default() + }, + ..Default::default() + }; + } + }; sys.refresh_cpu_all(); let cores = available_parallelism_count(); @@ -254,7 +265,18 @@ pub struct MemInfo { } pub fn get_mem_info(addr: &str) -> MemInfo { - let mut sys = System::new_all(); + let mut sys = match System::new_all() { + Ok(sys) => sys, + Err(error) => { + return MemInfo { + node_common: NodeCommon { + addr: addr.to_string(), + error: Some(error.to_string()), + }, + ..Default::default() + }; + } + }; sys.refresh_memory(); let total = sys.total_memory(); @@ -279,7 +301,9 @@ pub fn get_mem_info(addr: &str) -> MemInfo { } pub fn collect_mem_stats() -> crate::MemStats { - let mut sys = System::new_all(); + let Ok(mut sys) = System::new_all() else { + return crate::MemStats::default(); + }; sys.refresh_memory(); let process_memory = sys diff --git a/crates/object-data-cache/src/runtime_memory.rs b/crates/object-data-cache/src/runtime_memory.rs index 06eec2ea0..14c839258 100644 --- a/crates/object-data-cache/src/runtime_memory.rs +++ b/crates/object-data-cache/src/runtime_memory.rs @@ -76,7 +76,9 @@ pub fn effective_memory_from_system(system: &System) -> EffectiveMemory { /// Resolves the effective memory using a fresh, memory-refreshed system handle. pub fn resolve_effective_memory() -> EffectiveMemory { - let mut system = System::new(); + let Ok(mut system) = System::new() else { + return select_effective_memory(0, 0, None); + }; system.refresh_memory(); effective_memory_from_system(&system) } diff --git a/crates/obs/src/metrics/collectors/system_process.rs b/crates/obs/src/metrics/collectors/system_process.rs index 99dfd83b9..03ef2f73a 100644 --- a/crates/obs/src/metrics/collectors/system_process.rs +++ b/crates/obs/src/metrics/collectors/system_process.rs @@ -64,7 +64,7 @@ impl ProcessAttributes { /// Returns an error if the process does not exist or information /// cannot be retrieved. pub fn from_pid(pid: Pid) -> Result { - let mut system = System::new(); + let mut system = System::new().map_err(|error| ProcessAttributeError::SystemError(std::sync::Arc::new(error)))?; system.refresh_processes(sysinfo::ProcessesToUpdate::Some(&[pid]), true); let process = system @@ -100,6 +100,8 @@ impl ProcessAttributes { pub enum ProcessAttributeError { /// Failed to get current process PID PidError(String), + /// System information is unavailable. + SystemError(std::sync::Arc), /// Process not found ProcessNotFound(u32), } @@ -109,11 +111,19 @@ impl std::fmt::Display for ProcessAttributeError { match self { Self::PidError(e) => write!(f, "Failed to get current PID: {}", e), Self::ProcessNotFound(pid) => write!(f, "Process not found: {}", pid), + Self::SystemError(error) => write!(f, "System information unavailable: {error}"), } } } -impl std::error::Error for ProcessAttributeError {} +impl std::error::Error for ProcessAttributeError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::SystemError(error) => Some(error.as_ref()), + _ => None, + } + } +} /// Process status enumeration. /// diff --git a/crates/obs/src/metrics/scheduler.rs b/crates/obs/src/metrics/scheduler.rs index ba3791fbc..4b0631b40 100644 --- a/crates/obs/src/metrics/scheduler.rs +++ b/crates/obs/src/metrics/scheduler.rs @@ -2169,8 +2169,12 @@ pub fn init_metrics_runtime(token: CancellationToken) { let token_clone = token.clone(); tokio::spawn(async move { let process_attribute_labels = current_process_attribute_labels(); - let mut host_system = System::new_all(); - let mut host_networks = Networks::new(); + let mut host_system = System::new_all().inspect_err(|error| { + warn!(event = EVENT_METRICS_RUNTIME_STATE, component = LOG_COMPONENT_OBS, subsystem = LOG_SUBSYSTEM_METRICS_RUNTIME, result = "system_info_unavailable", collector = "system_monitoring", error = %error, "metrics source unavailable"); + }).ok(); + let mut host_networks = Networks::new().inspect_err(|error| { + warn!(event = EVENT_METRICS_RUNTIME_STATE, component = LOG_COMPONENT_OBS, subsystem = LOG_SUBSYSTEM_METRICS_RUNTIME, result = "network_info_unavailable", collector = "system_monitoring", error = %error, "metrics source unavailable"); + }).ok(); let mut process_sampler = ProcessSampler::new(); let process_interval = config.process_interval; let mut interval = metrics_interval(process_interval, Duration::ZERO); @@ -2178,9 +2182,11 @@ pub fn init_metrics_runtime(token: CancellationToken) { let mut next_resource_run = now; let mut next_system_run = now; - host_system.refresh_cpu_all(); - tokio::time::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL).await; - host_system.refresh_cpu_all(); + if let Some(system) = host_system.as_mut() { + system.refresh_cpu_all(); + tokio::time::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL).await; + system.refresh_cpu_all(); + } #[cfg(feature = "gpu")] let current_pid = match sysinfo::get_current_pid() { @@ -2376,8 +2382,8 @@ fn current_process_metric_labels( fn collect_system_monitoring_metrics( bundle: &ProcessMetricBundle, labels: &[(&'static str, Cow<'static, str>)], - host_system: &mut System, - host_networks: &mut Networks, + host_system: &mut Option, + host_networks: &mut Option, ) -> Vec { let cpu_stats = ProcessCpuStats { usage: bundle.resource.cpu_percent, @@ -2391,17 +2397,20 @@ fn collect_system_monitoring_metrics( read_bytes: bundle.disk_read_bytes, written_bytes: bundle.disk_write_bytes, }; - let network_stats = collect_host_network_stats(host_networks); - let (system_cpu_stats, system_memory_stats) = collect_system_cpu_and_memory_stats_with(host_system); - let mut metrics = Vec::new(); - metrics.extend(collect_cpu_metrics(&system_cpu_stats)); - metrics.extend(collect_memory_metrics(&system_memory_stats)); + if let Some(system) = host_system.as_mut() { + let (system_cpu_stats, system_memory_stats) = collect_system_cpu_and_memory_stats_with(system); + metrics.extend(collect_cpu_metrics(&system_cpu_stats)); + metrics.extend(collect_memory_metrics(&system_memory_stats)); + } metrics.extend(collect_process_cpu_metrics(&cpu_stats, Some(labels))); metrics.extend(collect_process_memory_metrics(&memory_stats, Some(labels))); metrics.extend(collect_process_disk_metrics(&disk_stats, Some(labels))); // Interface counters are host-wide, so keep these metrics free of process labels. - metrics.extend(collect_host_network_metrics(&network_stats, None)); + if let Some(networks) = host_networks.as_mut() { + let network_stats = collect_host_network_stats(networks); + metrics.extend(collect_host_network_metrics(&network_stats, None)); + } metrics } @@ -2413,6 +2422,20 @@ mod tests { use std::time::Duration; use tokio::time::Instant; + #[test] + fn unavailable_host_sources_preserve_process_metrics() { + let bundle = ProcessMetricBundle::default(); + let metrics = collect_system_monitoring_metrics(&bundle, &[], &mut None, &mut None); + let names = metrics.iter().map(|metric| metric.name.as_ref()).collect::>(); + assert!(names.iter().any(|name| name.contains("process_cpu"))); + assert!(names.iter().any(|name| name.contains("process_resident_memory"))); + assert!( + names + .iter() + .all(|name| !name.contains("network_host") && !name.contains("system_cpu")) + ); + } + fn fixed_metrics_runtime_config() -> MetricsRuntimeConfig { MetricsRuntimeConfig { cluster_interval: Duration::from_secs(60), diff --git a/crates/obs/src/metrics/stats_collector.rs b/crates/obs/src/metrics/stats_collector.rs index aab406622..727245279 100644 --- a/crates/obs/src/metrics/stats_collector.rs +++ b/crates/obs/src/metrics/stats_collector.rs @@ -762,7 +762,7 @@ pub async fn collect_disk_stats() -> Vec { fn build_system_cpu_stats(system: &System, server: &str) -> CpuStats { let cpu_usage = system.global_cpu_usage() as f64; let cpu_count = system.cpus().len().max(1) as f64; - let load_avg = System::load_average().one; + let load_avg = System::load_average().map_or(0.0, |load| load.one); CpuStats { server: server.to_string(), @@ -796,7 +796,19 @@ fn build_system_memory_stats(system: &System, server: &str) -> MemoryStats { /// Collect system CPU and memory statistics from a shared sysinfo snapshot. pub fn collect_system_cpu_and_memory_stats() -> (CpuStats, MemoryStats) { - let mut system = System::new_all(); + let Ok(mut system) = System::new_all() else { + let server = current_local_node_identity(); + return ( + CpuStats { + server: server.clone(), + ..Default::default() + }, + MemoryStats { + server, + ..Default::default() + }, + ); + }; collect_system_cpu_and_memory_stats_with(&mut system) } @@ -1040,7 +1052,7 @@ pub fn collect_host_network_stats_with(networks: &Networks) -> HostNetworkStats let transmitted = data.transmitted(); total_received += received; total_transmitted += transmitted; - per_interface.push((interface_name.to_string(), received, transmitted)); + per_interface.push((interface_name.to_string_lossy().into_owned(), received, transmitted)); } HostNetworkStats { @@ -1965,9 +1977,9 @@ mod tests { let previous = rustfs_common::get_global_local_node_name().await; rustfs_common::set_global_local_node_name("node1:9000").await; - let mut system = System::new_all(); + let mut system = System::new_all().expect("initialize system snapshot"); let (cpu, memory) = collect_system_cpu_and_memory_stats_with(&mut system); - let host_network = collect_host_network_stats_with(&Networks::new()); + let host_network = collect_host_network_stats_with(&Networks::new().expect("initialize network snapshot")); let process_bundle = process_metric_bundle_from_snapshots(ProcessResourceSnapshot::default(), ProcessSystemSnapshot::default()); @@ -2472,11 +2484,11 @@ mod tests { #[test] fn host_network_stats_require_a_persistent_networks_snapshot() -> std::io::Result<()> { - if !sysinfo::IS_SUPPORTED_SYSTEM { - return Ok(()); - } - - let mut persistent_networks = Networks::new(); + let mut persistent_networks = match Networks::new() { + Ok(networks) => networks, + Err(sysinfo::Error::Unsupported) => return Ok(()), + Err(error) => return Err(std::io::Error::other(error)), + }; persistent_networks.refresh(true); let initial_stats = collect_host_network_stats_with(&persistent_networks); assert_eq!( @@ -2500,7 +2512,8 @@ mod tests { "a persistent Networks instance should report non-zero loopback deltas after traffic" ); - let recreated_stats = collect_host_network_stats_with(&Networks::new_with_refreshed_list()); + let recreated_stats = + collect_host_network_stats_with(&Networks::new_with_refreshed_list().map_err(std::io::Error::other)?); assert_eq!( recreated_stats.total_received + recreated_stats.total_transmitted, 0, diff --git a/crates/targets/src/sys/user_agent.rs b/crates/targets/src/sys/user_agent.rs index bbe3204a6..b2090ea3d 100644 --- a/crates/targets/src/sys/user_agent.rs +++ b/crates/targets/src/sys/user_agent.rs @@ -90,7 +90,7 @@ impl UserAgent { /// Get Windows platform information #[cfg(windows)] fn get_windows_platform() -> String { - let version = System::os_version().unwrap_or_else(|| "NT Unknown".to_string()); + let version = System::os_version().unwrap_or_else(|_| "NT Unknown".to_string()); if version.starts_with("Windows") { version } else { @@ -106,7 +106,7 @@ impl UserAgent { /// Get macOS platform information #[cfg(target_os = "macos")] fn get_macos_platform() -> String { - let version_str = System::os_version().unwrap_or_else(|| "14.0.0".to_string()); + let version_str = System::os_version().unwrap_or_else(|_| "14.0.0".to_string()); let mut parts = version_str.split('.'); let major = parts.next().unwrap_or("14"); let minor = parts.next().unwrap_or("0"); @@ -125,7 +125,7 @@ impl UserAgent { /// Get Linux platform information #[cfg(target_os = "linux")] fn get_linux_platform() -> String { - let os_name = System::long_os_version().unwrap_or_else(|| "Linux Unknown".to_string()); + let os_name = System::long_os_version().unwrap_or_else(|_| "Linux Unknown".to_string()); format!("X11; {os_name}") } diff --git a/crates/zstd-compat/Cargo.toml b/crates/zstd-compat/Cargo.toml index 0ccf7a8ba..53f711fcb 100644 --- a/crates/zstd-compat/Cargo.toml +++ b/crates/zstd-compat/Cargo.toml @@ -30,8 +30,8 @@ zstdmt = ["zstd_fixed/zstdmt"] [dev-dependencies] zstd-safe = { version = "8.2.0", features = ["seekable"] } -toml = "0.9" -semver = "1.0.27" +toml = "1.1.8" +semver = "1.0.28" apache-avro.workspace = true arrow-array = "59.3.2" arrow-ipc = { version = "59.3.2", features = ["zstd"] } diff --git a/deny.toml b/deny.toml index 433837693..c4afda2f2 100644 --- a/deny.toml +++ b/deny.toml @@ -36,9 +36,6 @@ allow-git = [ # Official s3s repository pinned for Iceberg SigV4 path encoding support. # owner: GatewayJ review: 2026-10 "https://github.com/s3s-project/s3s", - # Official signer pinned to the reviewed SigV4a fix in smithy-rs#4958. - # owner: rustfs-maintainers review: 2026-10 - "https://github.com/smithy-lang/smithy-rs", # Upstream OIDC/OAuth2 crypto migrations, pinned to reviewed PR commits. # owner: rustfs-maintainers review: 2026-10 "https://github.com/ramosbugs/openidconnect-rs", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 43d02ec1c..7af855bc2 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -223,9 +223,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.18.2" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faac5829c2b74c28f830747e7818ccfb684261b5f48a1118b1e2a13d36dfab13" +checksum = "048006790404103c488e6c5616b3e7e702a71292aadda08e8f7698a9e0d2eb53" dependencies = [ "aws-lc-sys", "untrusted 0.7.1", @@ -234,9 +234,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.46.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1622d8446a2d4b2ce0c7eefc73dd43a99779028d5ee5c2dd8073a658ba8a2bc" +checksum = "8bfbe32ac36b3c428696ce315464181bc4029d689fd58e3f2a4e58c252242f52" dependencies = [ "cc", "cmake", @@ -273,9 +273,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.155.0" +version = "1.156.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a542f0e9261b9ce56708d591a62062079fa3c58a362ffbf49a2e48a4f6ced16" +checksum = "1072c9aa20159b9b417115342d38c4c53108fc98e5359fcb86b7d4575747eb59" dependencies = [ "arc-swap", "aws-credential-types", @@ -310,7 +310,8 @@ dependencies = [ [[package]] name = "aws-sigv4" version = "1.6.4" -source = "git+https://github.com/smithy-lang/smithy-rs?rev=5c1c4bca2ea7af97496e077c9f1a718eaac64bf8#5c1c4bca2ea7af97496e077c9f1a718eaac64bf8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f385da9b7757ed4c8214797ad663ff534fb622006143530aa80e21f8e06ff85c" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -1137,9 +1138,9 @@ dependencies = [ [[package]] name = "ctutils" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3e9d21d39e6f39ff46e03d5b621424f88ee23d8a1672c6bfc9ccc7f2da4f6a" +checksum = "a2376ffd6f96d8a9db59875b4b6b0237d6900b5baf64279714e05493ce64828a" dependencies = [ "cmov", "subtle", @@ -1836,18 +1837,18 @@ dependencies = [ [[package]] name = "hotpath" -version = "0.29.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4af2b5ecf2650278fe33b0e49b68c8c484d2306475c127628316dea740cf5c" +checksum = "502dc37a7c218b9b1d3a0ccfb904da81d10d6dda0e899c722c503092d55576ea" dependencies = [ "hotpath-macros", ] [[package]] name = "hotpath-macros" -version = "0.29.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c0a42eb299ebb7ec6b9161489e5bf132603a34ca12cecadb8490937aa0492a" +checksum = "a76e0af911930fc97abc766b393b48cdca77fea9f5f6b388cf2123a6d9c30deb" [[package]] name = "http" @@ -4821,9 +4822,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.39.6" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2071df9448915b71c4fe6d25deaf1c22f12bd234f01540b77312bb8e41361e6" +checksum = "110e37d98880fd804cd47509b90a8444f7aaaab655ae625e83cd442a8bc2ebf2" dependencies = [ "libc", "memchr", diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index ab474b5d7..3fc3004a5 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -19,18 +19,6 @@ rustfs-security-governance = { path = "../crates/security-governance" } rustfs-utils = { path = "../crates/utils", features = ["compress", "path"] } serde_json = "1" -[patch.crates-io] -# Standalone workspaces must repeat the root workspace's fixed SigV4a backend. -aws-sigv4 = { git = "https://github.com/smithy-lang/smithy-rs", rev = "5c1c4bca2ea7af97496e077c9f1a718eaac64bf8" } - -[patch."https://github.com/smithy-lang/smithy-rs"] -# Keep the signer's path dependencies on the SDK's existing registry types. -aws-credential-types = { version = "=1.3.1" } -aws-smithy-eventstream = { version = "=0.61.6" } -aws-smithy-http = { version = "=0.64.3" } -aws-smithy-runtime-api = { version = "=1.19.2" } -aws-smithy-types = { version = "=1.9.1" } - [[bin]] name = "bucket_validation" path = "fuzz_targets/bucket_validation.rs" diff --git a/rustfs/src/admin/handlers/diagnostics.rs b/rustfs/src/admin/handlers/diagnostics.rs index bba323b08..f8ed637f5 100644 --- a/rustfs/src/admin/handlers/diagnostics.rs +++ b/rustfs/src/admin/handlers/diagnostics.rs @@ -26,6 +26,7 @@ use crate::admin::auth::authorize_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::admin::storage_api::access::spawn_traced; +use crate::admin::storage_api::s3::{self, S3ErrorCode}; use crate::admin::utils::json_response; use crate::server::ADMIN_PREFIX; use crate::storage::storage_api::get_global_lock_clients; @@ -587,10 +588,11 @@ struct HealthInfoResponse { unsupported_probes: Vec<&'static str>, } -async fn collect_health_info() -> HealthInfoResponse { +async fn collect_health_info() -> S3Result { use sysinfo::{Pid, System}; - let mut sys = System::new_all(); + let mut sys = System::new_all() + .map_err(|error| s3::error(S3ErrorCode::InternalError, format!("System information unavailable: {error}")))?; sys.refresh_cpu_all(); // A second sample after a short interval yields meaningful CPU usage. tokio::time::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL).await; @@ -603,7 +605,7 @@ async fn collect_health_info() -> HealthInfoResponse { brand: sys.cpus().first().map(|c| c.brand().to_string()).unwrap_or_default(), frequency_mhz: sys.cpus().first().map(|c| c.frequency()).unwrap_or(0), usage_percent: if logical_cores > 0 { - sys.cpus().iter().map(|c| c.cpu_usage() as f64).sum::() / logical_cores as f64 + sys.cpus().iter().map(|c| c.usage() as f64).sum::() / logical_cores as f64 } else { 0.0 }, @@ -619,11 +621,11 @@ async fn collect_health_info() -> HealthInfoResponse { let os = HealthOsInfo { os: std::env::consts::OS.to_string(), - kernel_version: System::kernel_version(), - os_version: System::long_os_version(), - hostname: System::host_name(), + kernel_version: System::kernel_version().ok(), + os_version: System::long_os_version().ok(), + hostname: System::host_name().ok(), arch: std::env::consts::ARCH.to_string(), - uptime_secs: System::uptime(), + uptime_secs: System::uptime().unwrap_or_default(), }; let pid = std::process::id(); @@ -642,7 +644,7 @@ async fn collect_health_info() -> HealthInfoResponse { let drives = collect_drive_info().await; - HealthInfoResponse { + Ok(HealthInfoResponse { version: crate::version::get_version(), deployment_id: crate::admin::runtime_sources::current_deployment_id(), region: crate::admin::runtime_sources::current_region().map(|r| r.as_str().to_string()), @@ -653,7 +655,7 @@ async fn collect_health_info() -> HealthInfoResponse { process, drives, unsupported_probes: vec!["perf-net", "perf-drive-obd", "config-obd", "sys-services"], - } + }) } async fn collect_drive_info() -> Vec { @@ -689,7 +691,7 @@ pub struct HealthInfoHandler {} impl Operation for HealthInfoHandler { async fn call(&self, req: S3Request, _params: Params<'_, '_>) -> S3Result> { authorize(&req, AdminAction::HealthInfoAdminAction).await?; - let response = collect_health_info().await; + let response = collect_health_info().await?; json_response(StatusCode::OK, &response) } } @@ -737,7 +739,7 @@ impl Operation for ConsoleLogHandler { // single capability record, then a keep-alive heartbeat, so `mc admin // logs` connects and stays open without being misled into believing it // received real buffered logs. - let node_name = sysinfo::System::host_name().unwrap_or_else(|| "rustfs".to_string()); + let node_name = sysinfo::System::host_name().unwrap_or_else(|_| "rustfs".to_string()); let (tx, rx) = mpsc::channel::>(8); spawn_traced(async move { diff --git a/rustfs/src/admin/handlers/profile_admin.rs b/rustfs/src/admin/handlers/profile_admin.rs index 097f8766a..b43d921d6 100644 --- a/rustfs/src/admin/handlers/profile_admin.rs +++ b/rustfs/src/admin/handlers/profile_admin.rs @@ -383,7 +383,7 @@ impl Operation for TraceHandler { .map_err(|_| s3_error!(InvalidRequest, "invalid trace parameters"))?; let filter = TraceStreamFilter::from_request(&req.uri, &opts)?; - let node_name = sysinfo::System::host_name().unwrap_or_else(|| "rustfs".to_string()); + let node_name = sysinfo::System::host_name().unwrap_or_else(|_| "rustfs".to_string()); let mut subscription = subscribe_trace_events(); let (tx, rx) = mpsc::channel::>(64); diff --git a/rustfs/src/cgroup_resources.rs b/rustfs/src/cgroup_resources.rs index 501e1318c..2871318c0 100644 --- a/rustfs/src/cgroup_resources.rs +++ b/rustfs/src/cgroup_resources.rs @@ -241,12 +241,15 @@ fn detect_container_resources() -> ContainerResources { let overridden = override_cores.is_some() || override_memory.is_some(); // Get host values from a single sysinfo::System instance (avoids double init) - let (host_cores, host_memory) = { - let mut sys = sysinfo::System::new_with_specifics(sysinfo::RefreshKind::everything().without_processes()); - sys.refresh_cpu_all(); - sys.refresh_memory(); - (sys.cpus().len().max(1), sys.total_memory()) - }; + let (host_cores, host_memory) = + match sysinfo::System::new_with_specifics(sysinfo::RefreshKind::everything().without_processes()) { + Ok(mut sys) => { + sys.refresh_cpu_all(); + sys.refresh_memory(); + (sys.cpus().len().max(1), sys.total_memory()) + } + Err(_) => (std::thread::available_parallelism().map_or(1, |cores| cores.get()), 0), + }; // Determine effective values: override > cgroup > host let cpu_cores = override_cores.or(cgroup_cpus).unwrap_or(host_cores).max(1); diff --git a/rustfs/src/config/info.rs b/rustfs/src/config/info.rs index 6a8a5b27a..85e677600 100644 --- a/rustfs/src/config/info.rs +++ b/rustfs/src/config/info.rs @@ -26,7 +26,7 @@ use serde::Serialize; use std::fmt; /// CPU information -#[derive(Serialize)] +#[derive(Default, Serialize)] struct CpuInfo { /// Number of logical CPU cores core_count: usize, @@ -50,7 +50,7 @@ impl CpuInfo { // Calculate average CPU usage let usage_percent = if core_count > 0 { - sys.cpus().iter().map(|c| c.cpu_usage() as f64).sum::() / core_count as f64 + sys.cpus().iter().map(|c| c.usage() as f64).sum::() / core_count as f64 } else { 0.0 }; @@ -65,7 +65,7 @@ impl CpuInfo { } /// Memory information -#[derive(Serialize)] +#[derive(Default, Serialize)] struct MemoryInfo { /// Total system memory in bytes total_bytes: u64, @@ -148,7 +148,9 @@ struct DiskInfo { impl DiskInfo { fn collect_all() -> Vec { - let disks = sysinfo::Disks::new_with_refreshed_list(); + let Ok(disks) = sysinfo::Disks::new_with_refreshed_list() else { + return Vec::new(); + }; disks .iter() .map(|disk| { @@ -204,7 +206,7 @@ impl ServiceDiskInfo { let volume_path = std::path::Path::new(first_volume); // Find the disk that contains this volume - let disks = sysinfo::Disks::new_with_refreshed_list(); + let disks = sysinfo::Disks::new_with_refreshed_list().ok()?; for disk in disks.iter() { let mount_point = disk.mount_point(); if volume_path.starts_with(mount_point) { @@ -289,18 +291,23 @@ struct SystemInfo { impl SystemInfo { fn collect() -> Self { // Create system info collector - let mut sys = sysinfo::System::new_all(); - sys.refresh_all(); - sys.refresh_cpu_all(); + let mut sys = sysinfo::System::new_all().ok(); + if let Some(sys) = sys.as_mut() { + sys.refresh_all(); + sys.refresh_cpu_all(); + } Self { os_type: sysinfo::System::distribution_id(), - os_version: sysinfo::System::long_os_version().unwrap_or_else(|| "Unknown".to_string()), + os_version: sysinfo::System::long_os_version().unwrap_or_else(|_| "Unknown".to_string()), architecture: std::env::consts::ARCH.to_string(), - hostname: sysinfo::System::host_name().unwrap_or_else(|| "Unknown".to_string()), - kernel_version: sysinfo::System::kernel_long_version(), - cpu: CpuInfo::collect(&sys), - memory: MemoryInfo::collect(&sys), + hostname: sysinfo::System::host_name().unwrap_or_else(|_| "Unknown".to_string()), + kernel_version: sysinfo::System::kernel_long_version().unwrap_or_default(), + cpu: sys.as_ref().map(CpuInfo::collect).unwrap_or_else(|| CpuInfo { + brand: "Unknown".to_owned(), + ..Default::default() + }), + memory: sys.as_ref().map(MemoryInfo::collect).unwrap_or_default(), disks: DiskInfo::collect_all(), } } @@ -383,30 +390,30 @@ struct RuntimeInfo { impl RuntimeInfo { fn collect() -> Self { - let (process_id, memory_usage_mb, cpu_usage_percent) = if let Ok(pid) = sysinfo::get_current_pid() { - let mut sys = sysinfo::System::new(); - sys.refresh_processes_specifics( - sysinfo::ProcessesToUpdate::Some(&[pid]), - true, - sysinfo::ProcessRefreshKind::everything(), - ); + let (process_id, memory_usage_mb, cpu_usage_percent) = + if let (Ok(pid), Ok(mut sys)) = (sysinfo::get_current_pid(), sysinfo::System::new()) { + sys.refresh_processes_specifics( + sysinfo::ProcessesToUpdate::Some(&[pid]), + true, + sysinfo::ProcessRefreshKind::everything(), + ); - let process = sys.process(pid); - let (memory_usage_mb, cpu_usage_percent) = if let Some(p) = process { - let memory = p.memory() as f64 / 1024.0 / 1024.0; // Convert to MB - let cpu = p.cpu_usage() as f64; - (memory, cpu) + let process = sys.process(pid); + let (memory_usage_mb, cpu_usage_percent) = if let Some(p) = process { + let memory = p.memory() as f64 / 1024.0 / 1024.0; // Convert to MB + let cpu = p.cpu_usage() as f64; + (memory, cpu) + } else { + (0.0, 0.0) + }; + + (pid.as_u32(), memory_usage_mb, cpu_usage_percent) } else { - (0.0, 0.0) + // Failed to retrieve current PID; degrade gracefully by + // skipping per-process stats and using sentinel values. + (0, 0.0, 0.0) }; - (pid.as_u32(), memory_usage_mb, cpu_usage_percent) - } else { - // Failed to retrieve current PID; degrade gracefully by - // skipping per-process stats and using sentinel values. - (0, 0.0, 0.0) - }; - // // Get available CPU parallelism (roughly, logical cores available to the process) let cpu_parallelism = std::thread::available_parallelism().map(|p| p.get()).unwrap_or(1); diff --git a/rustfs/src/connect/diagnostics/top_net.rs b/rustfs/src/connect/diagnostics/top_net.rs index ed8474625..6216cd4b0 100644 --- a/rustfs/src/connect/diagnostics/top_net.rs +++ b/rustfs/src/connect/diagnostics/top_net.rs @@ -48,10 +48,11 @@ pub async fn capture_top_net( let Some(_permit) = request.acquire(cancel).await? else { return request.cancelled(TOOL_ID); }; - if !sysinfo::IS_SUPPORTED_SYSTEM { - return request.failed(TOOL_ID, 0, TopReasonCode::SourceUnavailable); - } - let mut networks = Networks::new(); + let mut networks = match Networks::new() { + Ok(networks) => networks, + Err(sysinfo::Error::Unsupported) => return request.failed(TOOL_ID, 0, TopReasonCode::SourceUnavailable), + Err(_) => return request.failed(TOOL_ID, 0, TopReasonCode::CollectionFailed), + }; networks.refresh(true); if networks.is_empty() { return request.failed(TOOL_ID, 0, TopReasonCode::SourceUnavailable); diff --git a/rustfs/src/connect/environment.rs b/rustfs/src/connect/environment.rs index bdde134a4..9f8f75068 100644 --- a/rustfs/src/connect/environment.rs +++ b/rustfs/src/connect/environment.rs @@ -554,7 +554,8 @@ impl HostEnvironment { } // Processes, names, addresses, paths, mount options and device labels are outside this schema. - let system = System::new_with_specifics(RefreshKind::everything().without_processes()); + let system = System::new_with_specifics(RefreshKind::everything().without_processes()) + .map_err(|_| EnvironmentError::SourceUnavailable(EnvironmentSource::Cpu))?; let cores = system.cpus().len(); if cores == 0 { return Err(EnvironmentError::SourceUnavailable(EnvironmentSource::Cpu)); @@ -564,27 +565,32 @@ impl HostEnvironment { return Err(EnvironmentError::SourceUnavailable(EnvironmentSource::Memory)); } let available_memory = system.available_memory(); - let disks = Disks::new_with_refreshed_list(); + let disks = + Disks::new_with_refreshed_list().map_err(|_| EnvironmentError::SourceUnavailable(EnvironmentSource::Filesystem))?; let reported_filesystems = disks .iter() .map(|disk| disk.file_system().to_string_lossy()) .collect::>(); let filesystem_types = filesystem_types(reported_filesystems.iter().map(AsRef::as_ref))?; - let networks = Networks::new_with_refreshed_list(); + let networks = + Networks::new_with_refreshed_list().map_err(|_| EnvironmentError::SourceUnavailable(EnvironmentSource::Network))?; if networks.is_empty() { return Err(EnvironmentError::SourceUnavailable(EnvironmentSource::Network)); } Ok(Self { - os_summary: System::long_os_version().unwrap_or_else(|| "unknown".to_owned()), - kernel_summary: System::kernel_long_version(), + os_summary: System::long_os_version().unwrap_or_else(|_| "unknown".to_owned()), + kernel_summary: System::kernel_long_version().unwrap_or_default(), architecture: std::env::consts::ARCH, cores, total_memory_bytes, under_memory_pressure: available_memory.saturating_mul(10) < total_memory_bytes, filesystem_types, interface_count: networks.len(), - bond_count: networks.keys().filter(|name| name.starts_with("bond")).count(), + bond_count: networks + .keys() + .filter(|name| name.as_encoded_bytes().starts_with(b"bond")) + .count(), }) } } diff --git a/rustfs/tests/connect_top_net.rs b/rustfs/tests/connect_top_net.rs index 0da443a39..0e39aceea 100644 --- a/rustfs/tests/connect_top_net.rs +++ b/rustfs/tests/connect_top_net.rs @@ -119,7 +119,7 @@ fn top_network_uses_exact_counter_deltas_and_fails_closed_on_reset() { #[tokio::test] async fn top_network_capture_observes_real_loopback_traffic() { - if !sysinfo::IS_SUPPORTED_SYSTEM { + if matches!(sysinfo::Networks::new(), Err(sysinfo::Error::Unsupported)) { return; }