From 2247823200547e14082fc643b3b0fbc5bbb04968 Mon Sep 17 00:00:00 2001 From: houseme Date: Tue, 7 Jul 2026 17:47:59 +0800 Subject: [PATCH] fix(runtime): remove tokio io-uring feature and add regression guard (#4364) Drop the [target.'cfg(target_os = "linux")'.dependencies] tokio "io-uring" feature from 6 crates and the rustfs binary. Because .cargo/config.toml enables --cfg tokio_unstable globally, this feature switched every Linux build's file I/O onto tokio's io_uring runtime backend. Restricted Linux environments (Docker default seccomp, gVisor, proot, old kernels) reject io_uring_setup with EACCES/ENOSYS, which tokio surfaced as PermissionDenied and RustFS reported as DiskAccessDenied at startup. Add scripts/check_no_tokio_io_uring.sh so the feature cannot silently return: it fails on any tokio dependency line enabling "io-uring", while still allowing a future application-level io-uring crate dependency. Wire it into make pre-commit/pre-pr/dev-check and CI. Tracking: rustfs/backlog#890 (parent rustfs/backlog#897) Co-authored-by: heihutu --- .config/make/lint-fmt.mak | 5 +++++ .config/make/pre-commit.mak | 6 +++--- .github/workflows/ci.yml | 3 +++ Cargo.lock | 13 ------------- crates/ecstore/Cargo.toml | 4 ---- crates/io-core/Cargo.toml | 7 ------- crates/kms/Cargo.toml | 4 ---- crates/protocols/Cargo.toml | 4 ---- crates/scanner/Cargo.toml | 4 ---- crates/zip/Cargo.toml | 4 ---- rustfs/Cargo.toml | 2 -- scripts/check_no_tokio_io_uring.sh | 29 +++++++++++++++++++++++++++++ 12 files changed, 40 insertions(+), 45 deletions(-) create mode 100755 scripts/check_no_tokio_io_uring.sh diff --git a/.config/make/lint-fmt.mak b/.config/make/lint-fmt.mak index 03337bff9..fe39dcd48 100644 --- a/.config/make/lint-fmt.mak +++ b/.config/make/lint-fmt.mak @@ -45,6 +45,11 @@ logging-guardrails-check: ## Check logging guardrails for redaction and noise re @echo "🪵 Checking logging guardrails..." ./scripts/check_logging_guardrails.sh +.PHONY: tokio-io-uring-check +tokio-io-uring-check: ## Check tokio io-uring runtime feature stays removed + @echo "🚫 Checking tokio io-uring feature guard..." + ./scripts/check_no_tokio_io_uring.sh + .PHONY: compilation-check compilation-check: core-deps ## Run compilation check @echo "🔨 Running compilation check..." diff --git a/.config/make/pre-commit.mak b/.config/make/pre-commit.mak index 4e55e8ec3..416a87287 100644 --- a/.config/make/pre-commit.mak +++ b/.config/make/pre-commit.mak @@ -14,13 +14,13 @@ doc-paths-check: ## Check that instruction/architecture docs reference existing ./scripts/check_doc_paths.sh .PHONY: pre-commit -pre-commit: fmt-check unsafe-code-check architecture-migration-check logging-guardrails-check doc-paths-check quick-check ## Run fast pre-commit checks without clippy/full tests +pre-commit: fmt-check unsafe-code-check architecture-migration-check logging-guardrails-check tokio-io-uring-check doc-paths-check quick-check ## Run fast pre-commit checks without clippy/full tests @echo "✅ All pre-commit checks passed!" .PHONY: pre-pr -pre-pr: fmt-check unsafe-code-check architecture-migration-check logging-guardrails-check doc-paths-check clippy-check test ## Run full pre-PR checks with clippy and tests +pre-pr: fmt-check unsafe-code-check architecture-migration-check logging-guardrails-check tokio-io-uring-check doc-paths-check clippy-check test ## Run full pre-PR checks with clippy and tests @echo "✅ All pre-PR checks passed!" .PHONY: dev-check -dev-check: fmt-check unsafe-code-check architecture-migration-check logging-guardrails-check doc-paths-check quick-check ## Run fast local development checks +dev-check: fmt-check unsafe-code-check architecture-migration-check logging-guardrails-check tokio-io-uring-check doc-paths-check quick-check ## Run fast local development checks @echo "✅ Fast development checks passed!" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b8fd1f3fa..b8b60c770 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -143,6 +143,9 @@ jobs: - name: Check architecture migration rules run: ./scripts/check_architecture_migration_rules.sh + - name: Check tokio io-uring feature guard + run: ./scripts/check_no_tokio_io_uring.sh + test-and-lint: name: Test and Lint needs: skip-check diff --git a/Cargo.lock b/Cargo.lock index 09e2b3f94..7df3d3154 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5243,17 +5243,6 @@ dependencies = [ "rand_core 0.10.1", ] -[[package]] -name = "io-uring" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9080b15e63775b9a2ac7dca720f7050a8b955e092ea0f6020a4a80f69998cdc0" -dependencies = [ - "bitflags 2.13.0", - "cfg-if", - "libc", -] - [[package]] name = "ipconfig" version = "0.3.4" @@ -11467,13 +11456,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", "socket2", "tokio-macros", "windows-sys 0.61.2", diff --git a/crates/ecstore/Cargo.toml b/crates/ecstore/Cargo.toml index f4c5cd35e..df190521f 100644 --- a/crates/ecstore/Cargo.toml +++ b/crates/ecstore/Cargo.toml @@ -171,7 +171,3 @@ harness = false [lib] doctest = false - -# io-uring is Linux-only. Scope the feature to Linux targets. -[target.'cfg(target_os = "linux")'.dependencies] -tokio = { workspace = true, features = ["io-uring"] } diff --git a/crates/io-core/Cargo.toml b/crates/io-core/Cargo.toml index 271010c1d..72c7801ab 100644 --- a/crates/io-core/Cargo.toml +++ b/crates/io-core/Cargo.toml @@ -34,13 +34,6 @@ tokio = { workspace = true, features = ["io-util", "fs", "rt", "sync"] } memmap2 = { workspace = true } rustfs-io-metrics = { workspace = true } -# Enable tokio's io_uring-based runtime backend on Linux. -# Note: this is a tokio runtime feature, not application-level io_uring usage. -# See the Tokio 1.52.0 release notes and tokio-rs/tokio#7907 for the upstream -# runtime feature context. -[target.'cfg(target_os = "linux")'.dependencies] -tokio = { workspace = true, features = ["io-uring"] } - [dev-dependencies] tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } diff --git a/crates/kms/Cargo.toml b/crates/kms/Cargo.toml index 1a8eb8497..73d258b36 100644 --- a/crates/kms/Cargo.toml +++ b/crates/kms/Cargo.toml @@ -70,7 +70,3 @@ temp-env = { workspace = true } [features] default = [] - -# io-uring is Linux-only. Scope the feature to Linux targets. -[target.'cfg(target_os = "linux")'.dependencies] -tokio = { workspace = true, features = ["io-uring"] } diff --git a/crates/protocols/Cargo.toml b/crates/protocols/Cargo.toml index 6b2ab319d..83306c7da 100644 --- a/crates/protocols/Cargo.toml +++ b/crates/protocols/Cargo.toml @@ -136,7 +136,3 @@ tokio = { workspace = true, features = ["test-util", "macros", "rt"] } [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] - -# io-uring is Linux-only. Scope the feature to Linux targets. -[target.'cfg(target_os = "linux")'.dependencies] -tokio = { workspace = true, features = ["io-uring"] } diff --git a/crates/scanner/Cargo.toml b/crates/scanner/Cargo.toml index 95389a997..e7f4ed9ad 100644 --- a/crates/scanner/Cargo.toml +++ b/crates/scanner/Cargo.toml @@ -62,7 +62,3 @@ tokio = { workspace = true, features = ["test-util"] } [lib] doctest = false - -# io-uring is Linux-only. Scope the feature to Linux targets. -[target.'cfg(target_os = "linux")'.dependencies] -tokio = { workspace = true, features = ["io-uring"] } diff --git a/crates/zip/Cargo.toml b/crates/zip/Cargo.toml index 2b18f3696..f819994a6 100644 --- a/crates/zip/Cargo.toml +++ b/crates/zip/Cargo.toml @@ -54,7 +54,3 @@ tempfile = { workspace = true } [lints] workspace = true - -# io-uring is Linux-only. Scope the feature to Linux targets. -[target.'cfg(target_os = "linux")'.dependencies] -tokio = { workspace = true, features = ["io-uring"] } diff --git a/rustfs/Cargo.toml b/rustfs/Cargo.toml index 56b9fc00b..f8fafdd00 100644 --- a/rustfs/Cargo.toml +++ b/rustfs/Cargo.toml @@ -191,8 +191,6 @@ mimalloc = { workspace = true } [target.'cfg(target_os = "linux")'.dependencies] libsystemd.workspace = true -# io-uring is Linux-only. Scope the feature to Linux targets. -tokio = { workspace = true, features = ["io-uring"] } [target.'cfg(not(target_os = "windows"))'.dependencies] libmimalloc-sys = { version = "0.1.49", features = ["extended"] } diff --git a/scripts/check_no_tokio_io_uring.sh b/scripts/check_no_tokio_io_uring.sh new file mode 100755 index 000000000..9e7cd7727 --- /dev/null +++ b/scripts/check_no_tokio_io_uring.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Guard: tokio's io-uring runtime backend must stay disabled. +# +# Restricted Linux environments (Docker default seccomp, gVisor, proot, +# old kernels) reject io_uring_setup with EACCES/ENOSYS. With the global +# `--cfg tokio_unstable` in .cargo/config.toml, a tokio "io-uring" feature +# anywhere in the workspace silently switches every Linux build's file I/O +# onto that backend and turns the rejection into DiskAccessDenied at +# startup (backlog#890). Any future io_uring integration must go through +# an application-level, runtime-probed backend (backlog#894), never the +# tokio runtime feature — so only the tokio dependency line is banned +# here; an explicit `io-uring` crate dependency is allowed. + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="${CHECK_NO_TOKIO_IO_URING_ROOT:-$(cd "${SCRIPT_DIR}/.." && pwd)}" + +cd "$ROOT_DIR" + +status=0 + +while IFS=: read -r file line content; do + printf '%s:%s: tokio must not enable the "io-uring" runtime feature: %s\n' \ + "$file" "$line" "$content" >&2 + status=1 +done < <(rg -n '^[[:space:]]*tokio[[:space:]]*=.*"io-uring"' --glob '**/Cargo.toml' . || true) + +exit "$status"