Commit Graph

218 Commits

Author SHA1 Message Date
Chris An 7728eeab1a feat(heal): advertise MRF lifecycle reader capability (#8916)
* feat(heal): read retained MRF lifecycle v2 checkpoints

* feat(heal): advertise MRF lifecycle reader capability
2026-10-25 21:08:43 +08:00
Chris An 124cbfc00a feat(heal): read retained MRF lifecycle v2 checkpoints (#8913) 2026-10-25 14:34:57 +08:00
Ramakrishna Chilaka 42d376c6b7 perf(ecstore): isolate durable I/O and streamline disk dispatch (#8902)
* perf(ecstore): unify per-disk blocking workers with spin keep-alive and coalesce DELETE hops

Unify per-disk blocking I/O and fsync workers under a 3-lane DiskBlockingQueue
(Foreground, Isolated, Fsync) with MAX_NAMESPACE_WORKERS_PER_DISK = 1 and a
bounded user-space spin/yield keep-alive (WORKER_IDLE_SPIN_ITERS = 256), and
coalesce redundant blocking dispatches along the DELETE hot path:

- Expand DiskBlockingQueue to 3 lanes (Foreground, Isolated, Fsync) with 1
  warm worker per disk/lane and a 256-iteration spin/yield keep-alive before
  exiting spawn_blocking, preventing Tokio BlockingPool shared.idle futex
  wake/wait thrashing between back-to-back stages of PUT and DELETE.
- Route fsync_dir, fsync_dir_with_owner, and namespace file-sync barriers
  through the per-disk Fsync lane on FSYNC_RUNTIME, and replace LocalDisk's
  duplicate MetadataReadQueue with LocalDisk::run_metadata_read backed by
  self.blocking_queue.
- Route write_all_internal(Owned), open_file(O_TRUNC), remove_file_with_owner,
  and remove_dir_with_owner through DiskBlockingQueue with pre-execution
  cancellation checks.
- Coalesce DELETE directory scans in commit_reserved_version_delete and
  finish_version_delete into single blocking passes with periodic cancellation
  polling, batch rollback file writes in write_delete_rollback_files, batch
  rollback unlinks + directory fsync in remove_files_and_fsync_with_owner, and
  coalesce post-rename directory fsyncs in activate_delete_preparation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d85aaf47-2a4b-4c2c-97a3-dbe8c7717e2a

* perf(ecstore): isolate durable work and reduce idle queue locking

Route coalesced writes and delete settlement through the fsync lane while preserving namespace leases, cancellation ownership, and durability ordering. Keep relaxed work on the foreground lane and replace idle mutex polling with an advisory atomic hint; dequeue and worker retirement remain mutex-protected.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): yield disk workers across shared blocking pools

Limit each draining task to 64 completed jobs and reuse the worker guard to reschedule remaining work behind other disks. Preserve per-disk FIFO, worker limits, and per-operation ownership. Add a deterministic two-disk regression with one blocking thread.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): release queued jobs when workers cannot start

Construct the worker guard before submission and track whether execution began. Release pending jobs outside the lane mutex when the last worker is rejected, so waiters, resource units, and self-owning namespace leases cannot remain stranded. Cover closed runtimes and shutdown during batch handoff.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(connect): synchronize restart with observed inventory

Wait for the received POST instead of treating transport backoff as proof of delivery. Inject a pre-HTTP connection drop and use a verified loopback IP fixture without changing timeout or replay assertions.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* refactor(ecstore): unify disk worker lifecycle and drain loop

Represent submitted, running, and retired workers explicitly. Share dequeue, execution, idle recheck, and retirement in one loop while preserving bounded handoff and rejected-task ownership cleanup.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(storage): separate real I/O from paused-clock assertions

Complete durable fixtures before pausing virtual time, drive the immediate scanner tick before freezing time during filesystem waits, and keep checkpoint-backed retry accounting on a real clock. Preserve default fsync isolation, disk deadlines, retry counts, and all outcome assertions.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Hauser <housemecn@gmail.com>
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Copilot-Session: d85aaf47-2a4b-4c2c-97a3-dbe8c7717e2a
2026-10-25 14:22:27 +08:00
Chris An 32c4593587 fix(heal): retain MRF state when bucket identity is unresolved (#8905)
* fix(heal): retain MRF state when bucket identity is unresolved

* test(heal): give real-storage replay fixture a bounded stack
2026-10-25 03:58:46 +08:00
Chris An b23723a51f feat(heal): add live node admission feedback (#8897)
* feat(heal): add live node admission feedback

* test(heal): use storage facade in admission regression

* fix(heal): preserve retryable node admission deferrals
2026-10-25 01:42:02 +09:00
Chris 68a5b2c89c fix(heal): measure admission lock wait and hold separately (#8863)
* fix(heal): measure admission lock wait and hold separately

* fix(heal): exclude force-start cancellation from lock hold

* test(ecstore): drain guarded delete fixture rename tails
2026-10-24 16:17:41 +09:00
Chris 76f4342ae2 feat(scanner): observe canonical heal task terminals (#8851) 2026-10-24 08:50:13 +09:00
Chris 4e88ebcf30 fix(heal): preserve typed replacement readiness deferrals (#8823)
* fix(heal): preserve typed replacement readiness deferrals

* docs(heal): align retry compatibility markers with guards
2026-10-24 00:22:41 +09:00
Chris 2474adc50f feat(heal): inspect blocked checkpoint validation without mutation (#8838) 2026-10-23 23:03:57 +09:00
Chris 1820a4c40b fix(heal): list local blocks and quiet legacy ambiguity logs (#8826)
* fix(heal): list local blocks and quiet legacy ambiguity logs

* test(heal): cover storage and scheduler ambiguity logs
2026-10-23 13:40:00 +08:00
Hauser 90a39a5083 perf(heal): borrow intents during retirement proof checks (#8800)
Share the existing canonical identity resolver with a non-authoritative source eligibility query. Group borrowed intents and create owned anchors only for retired generations, preserving cache and responsibility contracts and moving proof keys.

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-22 17:22:37 +09:00
Hauser 335612f452 perf(heal): skip replay anchor clones for empty repair queues (#8798)
Use a conservative work hint for verified and typed legacy events, retaining the original capacity-maintenance pass and metrics publication. Preserve durable identities, journal retention, retries, and shutdown behavior, with isolated real-runtime and queue lifecycle regressions.

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-22 16:38:06 +09:00
Hauser 66bf2c0a75 perf(heal): aggregate MRF lifecycle metrics in one pass (#8773)
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-22 02:46:26 +08:00
Hauser c1de42af2c fix(heal): type legacy MRF decisions and defer diagnostics (#8778)
* fix(heal): explain unverified legacy heal outcomes

Preserve storage diagnostics in canonical unknown outcomes and explain
legacy payload identity limits through the shared local/peer status path.
Borrow expected receipt identities while preserving all proof checks.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): keep diagnostics from pausing merged MRF repairs

Require the actual MRF executor before publishing legacy pause events.
An ordinary queued owner can retain a merged durable MRF notice without
having performed the specialized deep check. Preserve its diagnostic
without granting it authority to park the repair responsibility.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): type MRF outcomes and defer status diagnostics

Carry storage-owned legacy observations in process and return a typed
terminal result only after the qualified MRF Deep check. Publish pause
events from that result and exact identities instead of source or text.
Keep object names out of retry classification and compute only the
status diagnostic selected by the canonical execution state.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-22 02:45:31 +08:00
Chris 97e600ae69 fix(heal): hold unobserved legacy MRF responsibilities (#8772) 2026-10-22 00:04:16 +09:00
Hauser 102cc18767 test(heal): retain unknown same-key repair across replay (#8759)
Cover actual journal and lifecycle checkpoint replay when an unknown historical source coexists with an exact source-bound repair. Reject a pre-restart lease and retain the complete unresolved record after the new repair is discharged and replayed again.

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-21 15:02:01 +08:00
Chris 6f582b0548 fix(heal): decide object absence from storage evidence, not source (#8697)
* test(heal): add failing regressions for a source-independent absent verdict

Add the regression tests for backlog#2900 that fail on the current code,
where the same object-level not-found is treated as deleted on the plain
heal path but as recreate_failed on the recreate path, and where the
erasure-set healer, the task predicates and the error helpers disagree on
wrapped not-found and transient inputs.

Also add the per-object disposition cache module with its unit tests, the
manager admission tests for it, the compat register entry for the display
boundary, and the admission-invariant notes. The module and the manager
tests are not declared yet, so nothing is wired into the build.

* fix(heal): decide object absence from storage evidence, not request source

Replace the five heal error classifiers (erasure-set healer outcome
mapping, task-level not-found and lock predicates, error.rs recovery
helpers and the storage existence-check matcher) with one typed
classify_heal_error. An object-level not-found from the locked storage
read is Absent for every source and every recreate_missing value; the
recreate path, the usage-observation and scanner object-dir whitelists
are gone, and display-text matching survives only in the marked
classify_error_display boundary.

Add a bounded, expiring per-object disposition memory consulted before
queue admission so a best-effort producer cannot requeue an absent or
terminally failed object on every tick; durable MRF, admin, forced,
high-priority and dry-run requests bypass it. The read-repair producer no
longer forces recreate_missing.

* fix(heal): keep rendered grace windows out of task retries

A grace window rendered into a task message belongs to an attempt that
already finished; its owner schedules the next one. Only typed grace
errors replay the task, as before the classifier merge. Update the
ecstore read-repair black-box test: the producer no longer forces
recreate_missing.

* fix(heal): classify ambiguous legacy delete residue as permanent explicitly

* fix(heal): scope disposition memory and bound absence parsing
2026-10-20 00:11:49 +08:00
Hauser 05b483b31a fix(storage): preserve scanner checkpoints and bound MRF journal I/O (#8692)
* fix(scanner): preserve checkpoints on identity read failures

Distinguish confirmed missing incarnation sidecars from lookup errors before
cache preparation. Preserve durable checkpoint progress when identity reads
are unavailable and report post-scan uncertainty separately from replacement.

Reuse the transaction-fenced reader for optional and required lookups while
retaining existing missing, malformed, system-bucket and lock-loss behavior.
Verify preservation and recovery through a real coordinator with the identity
sidecar write-locked, including unchanged cache revisions and dirty work.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* refactor(ecstore): share required incarnation conversion

Keep the missing-incarnation error contract in one conversion used by both
required lookup entry points. This removes a duplicate formatted error site
and satisfies the existing error-format ratchet without changing its baseline.

Pin the full missing-identity error text in the real SetDisks regression.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): bound cross-disk MRF checkpoint I/O

Run independent journal disks with bounded concurrency while retaining each
replica's payload, companion and manifest ordering and the mirror phases.
Share encoded bodies, deduplicate local roots and collect every result
without changing receipt deadlines or persistence failure semantics.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-19 18:16:49 +08:00
Chris 2b57fa8758 fix(heal): block replacement and root records per entry (#8700)
Count only post-format rebuild failures against the replacement retry
budget; handoffs, format fences, outages, grace waits and conflicts keep
their durable reason without spending an attempt. Retired generations
(committed handoff or approved legacy migration) no longer own their set,
so fresh admission for other slots proceeds, and a committed predecessor
becomes collectible once its successor is verified.

Block discovery conflicts per generation instead of per set, re-evaluate
them on every pass, and expose the blocked entries with reasons. Report
root heal inventory conflicts per record and keep replaying the others.
Revalidate blocked checkpoints hourly with the current reader and clear
markers the reader accepts. Return a dedicated error for ambiguous legacy
delete residue instead of the retryable SlowDown.

Implements rustfs/backlog#2902. Fixes rustfs/rustfs#8664. Addresses
rustfs/rustfs#8366, rustfs/rustfs#8565, rustfs/rustfs#8645 and part of
rustfs/rustfs#8608.

Co-authored-by: Hauser <housemecn@gmail.com>
2026-10-19 18:12:43 +08:00
Chris e0e18908d5 fix(heal): place checkpoint serialization impls before tests (#8663)
* fix(heal): move impls before test module to satisfy clippy items_after_test_module lint

Clippy in Rust 1.99 flags items defined after #[cfg(test)] mod tests.
Move Serialize and Deserialize impls for CheckpointJson before the
test module in crates/heal/src/heal/resume/checkpoint/integrity.rs.

* fix(heal): restore checkpoint integrity file newline

Add the missing final newline so cargo fmt --all --check passes.
The checkpoint serializer implementations and tests remain unchanged.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: Hauser <housemecn@gmail.com>
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-19 07:08:49 +09:00
Hauser e29a76f391 fix(heal): verify checkpoint integrity before applying defaults (#8649)
* fix(heal): verify checkpoint integrity before applying defaults

Validate the persisted JSON shape so intact signed legacy checkpoints can
reach the existing safe schema rewind. Preserve deployed field ordering and
read historical sorted-key digests without changing the checkpoint schema.
Reuse the signing value when saving and retain strict duplicate-field parsing.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): preserve checkpoint writer rollback compatibility

Keep ordered checkpoint parsing local rather than enabling preserve_order
throughout the server. Sort writer keys recursively to retain the production
base reader's digest format while accepting both historical read orders.

Cover real writer canonicalization, nested scalar ordering and depth limits.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-18 04:03:16 +08:00
cxymds 628663f468 fix(heal): recover replacements after pool removal (#8600)
* fix(heal): recover replacements after pool removal

* test(e2e): gate upgrade probes on writable baseline nodes

* test(e2e): register baseline readiness regression in smoke digest
2026-10-16 12:08:29 +08:00
Hauser 8c8c74cbc3 fix(ecstore): unify bounded delete recovery across upgrades (#8594)
* fix(ecstore): complete delete recovery across upgrades and restarts

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(ecstore): expect typed quorum error after delete rollback

Assert the exact InsufficientWriteQuorum bucket and object instead of the removed Io wrapper, retaining the rollback and cleanup ownership checks.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-16 11:09:50 +08:00
Hauser 84f7ab1f5c chore(deps): refresh Rustls and TAR parser test crates (#8547)
* chore(deps): update Rustls patch release

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* chore(deps): update TAR parser test crates

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): avoid collecting requests in test

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Co-authored-by: hector <42570491+majinghe@users.noreply.github.com>
2026-10-14 23:23:57 +08:00
cxymds 388d1f17e6 fix(heal): safely recover missing bucket directories by default (#8517)
* fix(heal): safely recover missing bucket directories by default

* fix(heal): allow bound admin recovery before namespace checks
2026-10-14 03:57:09 -07:00
Hauser 9068d83400 fix(heal): unblock automatic replacement recovery (#8533)
* fix(heal): unblock automatic replacement recovery

Repair bucket publication directories before adopting survivor delete proofs.
Keep explicit empty-volume removal after proof settlement and preserve the
admitted bucket incarnation for administrator replay.

Discover unfinished intents across every local set and resume the durable
owner with its exact target scope before admitting new sibling replacements.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(heal): route scanner fixtures through the storage boundary

Expose the existing disk-layout bootstrap symbols as test-only aliases in
heal::storage_api and use that boundary from scanner recovery regressions.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* refactor(heal): index replacement discovery within each scan

Keep a single endpoint-keyed disk inventory with first-snapshot precedence
and deterministic discovery order. Index local target lookups and move
resume state into generation candidates instead of cloning it.

Retain fresh durable reads and the existing conflict and mutation fences.
Cover duplicate disk handles, endpoint uniqueness and discovery ordering.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(heal): retain committed journals in recovery fixtures

Build one certified survivor delete decision for both replacement and
empty-volume removal tests. Clear target contents without moving its root
inode so Linux disk handles observe the same empty target. Drain PUT tails
and assert the proof remains before the real Heal entry.

Expose the existing recovery state through the ECStore disk API for typed
fixture checks.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(heal): use server stack for replacement regression

The replacement regression polls the composed Heal future on libtest's
smaller calling-thread stack and aborts before reporting an assertion.
Run it on a bounded 8 MiB test thread and Tokio workers, matching the
debug server's stack budget. Keep all storage and object assertions intact.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-14 17:04:36 +08:00
cxymds adf17bbfba fix(heal): reject incomplete administrator bucket discovery (#8512) 2026-10-13 04:12:28 -07:00
Hauser 4166b9503f fix(ecstore): recover interrupted delete transactions (#8468)
* fix(ecstore): recover crash-interrupted delete retries

Retain set-quorum cleanup proof and restore metadata before dropping rollback
markers. Reclaim eligible exact-key residue during explicit delete retries,
with bucket identity, version, retention and namespace fencing guards.

Preserve prefix children and snapshot ownership through batched physical
cleanup, and cover interrupted transactions and failure boundaries.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): route recovery test imports through contracts

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): preserve missing-key deletes at quorum

* feat(ecstore): add certified set-wide delete recovery

Atomically prepare deletion journals and exact targets, publish durable set
receipts, and recover through one fenced disk/RPC core used by startup and
scoped administrator healing. Preserve returning generations, ordinary
missing-key quorum semantics, and legacy rollback wire compatibility.

Retain namespace and volume ownership through late physical operations,
order related transactions causally, and keep proof until full convergence.
Remove the superseded local-only recovery path and add storage, protocol,
RPC, durability and isolated Docker regression coverage.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): reclaim completed multipart delete sidecars

* fix(ecstore): recover multipart sidecars with verified proofs

Recognize native multipart sidecars at the shared recovery boundary and
restore them without treating metadata or proof files as shard payloads.
Validate required proof generations and bind every present live/staged
shard copy to its metadata-bound Merkle proof before restoring metadata.

Cover protected native MPU rollback, split source layouts, missing or
corrupt proofs, and payload corruption with recomputed bitrot checksums.
Add real multipart Docker regressions in both integrity modes.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): settle superseded committed version deletes

Allow a validated committed decision to finish its own data cleanup after
a later decision removes current metadata. Prepared copies need an
inspected same-transaction receipt matching immutable local intent before
promotion, and retain their local journal without importing peer hashes.

Reuse the authority matcher for dry-run and settlement. Cover chained
explicit-version deletions, partial receipt publication, mismatch rejection
and no-resurrection, while retaining the no-decision absence protection.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(ecstore): clarify delete recovery case label

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): restore recovery CI guard coverage

Keep production error sites visible to the ratchet by placing test modules last. Preserve native encoding errors, group preparation identity and ownership, and reduce RPC enum size without changing the wire payload.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(admin): preserve owned OIDC validation errors

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* refactor(ecstore): unify recovery authority and snapshot work

Use one user-bucket legacy settlement boundary and one adoption source predicate for preview and execution. Reuse immutable snapshot digests, consume owned generation metadata, index version membership, and prepare empty witnesses through the canonical journal path.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): preserve delete recovery invariants

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Co-authored-by: overtrue <anzhengchao@gmail.com>
2026-10-12 13:47:37 +08:00
Hauser a464b45367 fix(rustfs): keep recovery handler within S3 gateway (#8429)
* fix(rustfs): route recovery errors through S3 gateway

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): satisfy strict Clippy pagination checks

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): avoid cloning Copy purge identity

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test: restore one-second drive request budgets

* fix(ecstore): resume pending lock bucket creation

Allow retries to reuse an uncommitted Object Lock bucket intent when the same incarnation remains unretired and all physical volumes are absent. Isolate the recovery entrypoint test from the shared production leader lock.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test: provision stack for deep catalog test futures

Apply the existing 4 MiB test-thread stack setup to table-catalog handler/store tests and the relocated-pool GET regression in both local and CI nextest profiles. These cases overflowed libtest's 2 MiB default stack on Linux.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Co-authored-by: overtrue <anzhengchao@gmail.com>
2026-10-09 14:08:12 +08:00
Hauser 8474feaa26 fix: reconcile bucket generations and observe lock failures (#8421)
* fix: reconcile bucket generations and observe lock failures

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix: fence bucket recovery through cancellation and quota reuse

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): route tests through storage API boundary

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(ecstore): use typed lock errors in recovery

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-08 21:26:12 +08:00
cxymds a9670ebb4d fix(ci): preserve heal quorum retries and synchronize background tests (#8422) 2026-10-08 05:03:33 -07:00
Hauser 34917c7947 fix: resume stalled GET bodies and classify transient storage failures (#8414)
* fix: resume stalled GET bodies

Retry a stalled source through the existing identity-fenced resume budget so transient stalls do not truncate committed responses.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix: preserve data usage read quorum errors

Apply the existing system-volume error mapping to snapshot body reads so a metadata-volume outage remains a retryable quorum failure.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix: handle transient heal lock failures

Align erasure-set heal classification with the shared lock taxonomy and avoid duplicate error logging for retried scanner journal writes.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

---------

Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-07 23:11:36 -07:00
cxymds 6b1554003e fix(heal): defer replacement retries until dangling grace expires (#8388) 2026-10-07 07:04:12 -07:00
Chris f7c4ac11b2 fix(heal): retry typed RPC transport failures after peer restart (#8365)
* fix(heal): retry typed RPC transport failures after peer restart

* test(heal): keep original errors in GOAWAY clone coverage
2026-10-06 08:11:19 -07:00
Hauser 003570b61e fix(heal): bound durable MRF rescheduling (#8351)
Reuse stable live-owner proof anchors to avoid duplicate in-flight admission. Pace unverified completions and unavailable attempts with bounded jitter while retaining checkpoints, exact proofs, and generation isolation.

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-04 09:04:11 -07:00
Chris 8452910895 fix: resolve pagination fixtures and heal recovery CI failures (#8316)
* test(e2e): bound delimiter pagination fixture uploads

* fix(heal): classify CAS lock failures before publication

* fix(heal): retry unproven absence within the object budget

* docs(heal): clarify object retry classification

* test(s3): seed the delimiter fixture with bounded concurrent PUTs
2026-10-03 20:40:52 +08:00
Hiroaki KAWAI 94105a1044 fix(heal): skip removed usage observations during read repair (#8135)
* fix(scanner): skip absent usage observations during heal admission

* fix: skip usage observation metadata recreation

* style: apply rustfmt to scanner fix

* Revert "style: apply rustfmt to scanner fix"

This reverts commit c871d03911.

* Revert "fix: skip usage observation metadata recreation"

This reverts commit d500661be6.

* Revert "fix(scanner): skip absent usage observations during heal admission"

This reverts commit c7e03eb926.

* fix: skip read repair for usage observations

* fix(heal): skip removed usage observations during read repair

* fix(connect): return profile capture result directly

* fix(deps): replace yanked yoke-derive release

---------

Co-authored-by: cxymds <cxymds@gmail.com>
2026-10-03 16:49:19 +08:00
Chris 2806a80c91 fix: prevent metadata lock reentry and stabilize CI fixtures (#8257)
* fix(test): establish a writable previous-release upgrade baseline

* fix(ci): reserve capacity for durable admin fixtures

* fix(ci): group durable IAM state fixtures by resource needs

* ci: run E2E doctests with the E2E dependency graph

* fix(ci): separate fixture startup from transport deadlines

* fix(ci): bound pagination after seeding and revisit restored copies

* fix(ci): make filesystem fixture timing deterministic

* fix(ecstore): avoid metadata lock reentry during internal mutations

* test: align recovery fixtures with durable ownership contracts
2026-09-30 20:57:07 +08:00
Chris 88d03d8199 fix(storage): prevent metadata deadlocks and abandoned writes (#8268)
## Related Issues

N/A

## Summary of Changes

Reject system-bucket incarnation lookups before entering the pool metadata owner. Keep each selected scanner backlog publication cohort in one task so waiter cancellation cannot abandon its remaining serialized conditional writes. Bind repair and replay fixtures to persisted bucket incarnations.

## Verification

Head f6d44603fc received an approval from houseme in review 5365588011. This merge does not add a local runtime validation claim. Full main CI remains a separate publication gate.

## Impact

System metadata writes avoid recursive pool locking. Publication retains per-replica conditional writes and stops a cancelled caller from advancing to its next publication phase. Fixture changes supply the identities required by existing repair admission rules.

## Additional Notes

Reverting this change restores the previous behavior.
2026-09-30 19:49:24 +08:00
Chris bb04355a3d fix(heal): retry contended local metadata CAS (#8267) 2026-09-30 15:45:59 +08:00
Hauser d60dfbb826 fix(heal): finalize durable MRF legacy responsibility lifecycle (#8254)
## Related Issues

Resolves the corrected lifecycle fixture findings in PR #8254.

## Summary of Changes

Preserve separate incarnation-bound durable MRF responsibilities and their lifecycle audit records, and align replay fixtures with their checkpoint identities.

## Verification

Two independent source reviews and changed-delta reviews are complete. The final review approved 607a0b9bb0 with no remaining supported findings. Local runtime claims were not independently reproduced for this pull request.

## Impact

Keeps storage generation fences and retained responsibility semantics. Test-capacity reservations preserve existing deadlines and assertions.

## Additional Notes

Squash merge of the currently approved fix under the authorized CI-bypass exception. Main CI and release acceptance remain required.
2026-09-30 14:02:32 +08:00
Chris a88225d208 fix(ci): reduce duplicate work and preserve reliable test failures (#8233)
* fix(ci): reduce duplicate work and preserve reliable test failures

* fix(ci): retain protocol evidence and repair stale test fixtures

* test(connect): honor parent deadline during API fixture readiness

* fix(ci): reserve IO capacity for state writer proofs

* test(connect): align RPC fixtures with service capture contracts

* test(connect): cover pinned service capture failures
2026-09-29 21:06:45 +08:00
Hauser 0a61f4a81e fix(heal): park healthy legacy MRF intents (#8225)
## Related Issues

rustfs/backlog#2682 and rustfs/rustfs#8192.

## Summary of Changes

Reviewed ca970f55ec against d2175d1e1e. No blocking code findings. The hold requires a completed healthy legacy check and an exact incarnation, lease, object, version and scope; it preserves the durable journal and rechecks on restart.

## Verification

Two independent source reviews completed, covering the lenses below. The frozen diff matches Git and passes diff whitespace checks. Reported Cargo and Docker results were not rerun or independently audited in this review.

One factual correction to the PR description: `legacy_sigkill_replay_repairs_without_releasing_unverified_responsibility` uses the default four-member fixture, with three replicas before restoration and four afterward (`mrf_partial_write_test.rs:559,567`). That named regression exercises the production manager path, but is not EC12+4. Other tests in the file use sixteen disks.

## Impact

Correctness: no findings; proofless legacy health never becomes a verified receipt. Security/trust: no findings; exact identity fences remain. Compatibility: no findings; journal encoding remains unchanged. Concurrency/durability: no findings; replay retains one checkpointed owner and replacement generations become retryable. Simplicity: no findings. Coverage: no blocking gap identified, with the test-scope correction above. Performance: no findings; held entries leave the retry index without adding per-admission queue scans.

## Additional Notes

The current main journal failure concerns DecodeFailure, which follows the separate ECDecode task path. This review does not establish that this PR fixes that failure or the scanner-cycle failure, and does not establish a passing main CI or release gate.
2026-09-29 15:28:46 +08:00
Chris 87e9a84a4e fix(ecstore): preserve RPC status when cloning storage errors (#8207)
* fix(ecstore): preserve RPC status when cloning storage errors

* test(heal): retain clone coverage without redundant ownership
2026-09-29 07:15:46 +08:00
Chris 5564932f38 fix(heal): retry cancelled internode RPC operations (#8205) 2026-09-29 01:58:35 +08:00
Chris 5ebc1e480b test: stabilize heal timing and improve heartbeat replay coverage (#8150)
fix: preserve heartbeat replay and stabilize timing tests
2026-09-28 22:07:15 +08:00
Hauser 5cac685e9a feat(ecstore): integrate io_uring backend improvements (#8105) 2026-09-26 17:14:17 +08:00
cxymds 655bb470b8 fix(heal): retry faulty storage disk errors (#8086) 2026-09-23 07:48:39 +00:00
Chris 4047ed6c8d fix(heal): restore bucket metadata before replacement completion (#8042) 2026-09-21 12:18:06 +08:00
Hauser 023adb1696 fix(heal): discharge absent durable partial writes (#8000)
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-09-18 16:07:18 +08:00