Add a real ECStore reopen regression for scanner usage-state reset cleanup boundaries. The fixture seeds each partially completed cleanup state, recreates the store, then verifies the reset resumes without rewriting the bootstrap intent or deleting unrelated metadata.
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
* fix(scanner): require root publication proof before dirty ack
Bind ACK expectations to validated scan candidates and confirm the actual primary-root revision and readback. Retain saved outcomes and dirty responsibility when stronger evidence is unavailable. Isolate CAS attempt confirmation and invalidate proof after scope mutations.
Revalidate observed candidate reuse before issuing a new publication proof, preserve the exact validated authoritative baseline work digest, and settle fixture commit tails before stable maintenance scans. Keep scoped ACK production disabled.
Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
* fix: restore ILM transition and lifecycle validation (#7316)
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
---------
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Treat a negative wall-clock age as zero without bypassing count or byte eviction. Cover canonical and alias queries, terminal outcomes, exact TTL expiry, and capacity limits during rollback.
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
feat(scanner): retain bounded bootstrap admission fairness
Keep a leader-local bounded cohort across scanner retries and preserve
waiting bucket priority during dirty arrivals and capacity overflow.
Order source permits in the dispatcher without changing result identity,
parent budgets, explicit cycle timing, or persistent coverage evidence.
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Retain failed identities in an execution-local count and byte bounded window so healthy later pages can advance. Preserve retry jitter, deadlines, terminal accounting and pressure pacing, with deterministic head-of-line and capacity regressions.
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Run one supervised cleanup attempt for an existing operator reset, with
strict phase and revision checks under the original leader lock. Keep v3
reset authorization and responses unchanged, report deferred status, and
bound probe and shutdown waits without aborting in-flight reset ownership.
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Stop task completion and legacy notices from discharging scanner retry hints. Preserve existing hints and their retry due time across admission observations, bound retry scheduling, and synchronize changed batches once even on cancellation.
Exercise the production MRF consumer, manager, event channel and scanner ledger. Document producer durability gaps without enabling successor activation or garbage collection.
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
* fix(ecstore): retain namespace owners through local physical tails
(cherry picked from commit a2f242463316e87604feadbdac5e4148140e72c0)
* test(ecstore): expose stale fsync group cleanup
* fix(ecstore): capture complete fsync worker guard
(cherry picked from commit 1dc90bb836e20ea9ee45d0a629a9201e20d231c4)
* fix(ecstore): preserve successor fsync group registration
(cherry picked from commit c7dfaad90526052e56c57dafffa4813bdcde46ca)
* test(ecstore): mark physical owner fixtures as inline
* test(ecstore): wait for namespace owner release before asserting
The namespace owner tests decided that ownership had ended when the Weak probe stopped upgrading or when the mutation lease could be reacquired. Both signals fire before the owner guard's Drop decrements the pending counter: Arc releases its strong count before running Drop, and the lease drops its locks before its owner field. The rio-v2 lane hit that window in undo_fresh_version_keeps_physical_namespace_owner_after_timeout.
Extend every drain wait to also require namespace_commits_pending() to be false, so the assertions observe the completed release instead of racing it.
* chore(deps): refresh SDKs and pin clock skew regression coverage
Refresh compatible dependencies for Scanner/Heal V2 batch 1 and verify
the production S3 retry/signing path with a deterministic clock.
Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
* fix(scanner): require complete publication coverage
Refs rustfs/backlog#2261 and rustfs/backlog#2240.
Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
* fix(ci): keep s3s footprint ratchet tight
Route bucket list-through test-only S3 wire types through the app storage facade again so the PR does not add a direct s3s-importing file.
Retighten the s3_error! footprint baseline to the current lower count.
Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
* fix(odm): expose store context after relocation
Expose the ECStore instance context through a narrow accessor so relocated on-demand migration backfill code no longer reaches into private storage fields.
Declare the faster-hex dependency used by the relocated native HTTP source implementation.
Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
* test(scanner): stabilize usage and ODM regressions
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>
Co-authored-by: overtrue <anzhengchao@gmail.com>
* fix(ilm): reject invalid retention counts and validate lifecycle filters
`NewerNoncurrentVersions` had no lower bound at PUT, and evaluation read a
negative count through `usize::try_from(...).unwrap_or(usize::MAX)`. An
HTTP-accepted rule therefore retained (almost) everything and silently
stopped expiring versions — the one outcome a retention rule must never
produce by accident.
Reject a negative count during validation, and stop reading one as
"retain everything" anywhere it can still arrive from older persistence
or an import: evaluation takes no action for such a rule and says so in a
diagnostic, the batch limit path yields no event, and `Evaluator::eval`
reports a typed corruption error to callers that can surface one.
A count-only noncurrent expiration is a MinIO extension, not an AWS form.
It used to be rejected as an actionless rule and was never executed. It
is now accepted and honoured with the semantics MinIO gives it: the
newest N noncurrent versions are kept and every older one is due as soon
as it became noncurrent. Zero keeps the meaning the batch limit path has
always given it — no count constraint — so a zero-count rule with no age
condition still has no action.
`LifecycleRuleFilter` is an all-`Option` DTO, so the schema constraints
were not checked anywhere: validate at most one top-level predicate, an
`And` that combines at least two, no repeated tag key, tag key/value
limits, non-negative sizes, and `ObjectSizeGreaterThan <
ObjectSizeLessThan`. An empty filter stays valid — AWS documents it as
"every object in the bucket".
Schema-shape violations are reported with a distinct `ErrorKind` so the
S3 boundary answers them with `MalformedXML`; rejected values keep the
`InvalidArgument` this path has always returned.
backlog#2201
* fix(ilm): satisfy lifecycle clippy checks
* fix(ilm): fail closed on invalid lifecycle rules
* fix: initialize optional migration source fields
---------
Co-authored-by: cxymds <cxymds@gmail.com>