Repository navigation
Conversation
Member
Author
|
Stateless tests (amd_asan_ubsan, cas s3 storage, parallel, 1/2) and Stateless tests (amd_binary, cas s3 storage, parallel): |
10 of 31 tasks
Two processes of one server_uuid could adopt the same writer epoch: when our counter write timed out and a twin wrote the same next value, the resolve read found identical bytes and reported our write as landed. Each allocation decision now writes a fresh random `allocation_nonce`, so only our own write matches our bytes. The field is a plain key that 26.6.4 readers skip. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every owner write sets `owner_life` to the read value + 1, so no two owner writes carry the same bytes and a delayed If-Match cannot land after a later write; `retirement_verified` records a finished decommission. Both are optional keys that 26.6.4 readers skip. Every claimer re-reads the owner after its mount write and requires its own uuid and life; otherwise it fences its own body and fails, so a successor does not wait the lease out. A remount that finds another life stops for good. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Decommission no longer deletes owner, epoch or mount: the counter keeps epochs from repeating across a member's lives, and the farewell body keeps a paused claimer from minting a lower epoch into an absent slot. Each run tombstones the owner right after its claim, bounded by its lease, confirms the claim, drains on its fenced mount plane, writes its farewell and marks the retirement verified. A lost claim rolls the tombstone back unless an earlier run verified it. After an unresolved tombstone the admin withholds its farewell, so the victim does not run before a late tombstone lands. The result column slot_removed becomes member_retired and namespaces_pending_gc is appended. The admin refuses a member without an epoch counter instead of minting one, and a mount that skips the capability probe now logs it. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mount's startup sweep deleted every staging object under its prefix, including a successor's in-flight uploads when two processes of one member overlapped. Keys are now staging/<srid>/<writer_epoch>/<random>.tmp and the sweep deletes only epochs below the live one; flat keys count as epoch 0 and a nested member's keys are left alone. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A decommission keeps the epoch counter, so allocateWriterEpoch never mints over an absent counter for it and EpochMintPolicy goes. The vanished-slot pacing and the observation prune stay, because a 26.6.4 decommission or a hand delete still removes a mount slot. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MountLeaseRenewer::renewOn sampled the stop flag before the write. A stop that landed after the sample refused the admission with nothing sent, yet the renewal went terminal and finishTeardown skipped the farewell. Read the flag after the refusal instead. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
filimonov
force-pushed
the
fix/antalya-26.6/cas-363-member-lifecycle
branch
from
October 17, 2026 08:34
9fc9db0 to
3a2641d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SYSTEM CAS DROP POOL MEMBERno longer deletes a member'sowner,epochandmountobjects; it deletes only the member's data. Deleting those objects let a restarting victim be issued a writer epoch it already used and let a late tombstone land on a live successor. Keeping them makes epochs strictly increasing perserver_root_idacross lives and removes the tail's race handling.Changes
Writer-epoch counter nonce. Every counter write carries a fresh
allocation_nonce. Two processes with the sameserver_uuidthat race on an ambiguous counter write no longer resolve to the same epoch: their bodies differ, so the byte-equality resolve cannot adopt the other's write.Owner life. The owner object gains
owner_life, a counter every owner write bumps byIf-Match, andretirement_verified. A mount records the life it started under. After every slot claim (start and self-remount) it re-reads the owner and requires its own uuid, that life, and no tombstone; otherwise it fences its own slot body and fails. A self-remount compares the life before it allocates an epoch: an owner at another life ends the remount loop inIdentityLost, and a restart picks up the current life.Decommission run:
Every exit between steps 2 and 5 runs the confirm. When the tombstone's outcome is unknown and the owner does not read back as the tombstone, the run fails without its clean farewell (
Pool::withholdFarewell): the slot keeps the admin's live body, so the victim restarts only after GC fences it (about 1.05 × the lease TTL plus a GC round) instead of reclaiming at once.member_retired = 1only for a verified mark. An owner that moved on to a later unretired life (a rejoin, or another run's rollback) reportsmember_retired = 0with its own warning. A run that cannot tell whether its tombstone or verified mark landed re-reads the owner before advising a rerun.S3 staging keys carry the writer epoch (
staging/<srid>/<epoch>/<random>.tmp), built and parsed inLayout. The startup sweep deletes only earlier epochs, so a paused older process can no longer delete its successor's staging. The epoch and the admission generation come from one capture.Removed: the epoch re-mint policy for decommission (
EpochMintPolicy). A member whose counter is missing (left by an older decommission) is refused, not repaired.A mount that skips the capability probe (
skip_access_check, always the case for decommission) logs it.Lease renewer fix, all CAS mounts. The stop flag was read before the renewal's admission. A stop landing in between made the renewal terminal with nothing sent, so a clean shutdown skipped its farewell and the next start paid the unclean-reclaim wait.
Risks / notes
slot_removedis renamedmember_retiredat the same position, andnamespaces_pending_gcis appended afterwarnings. Rows stillRemovingafter the drain are reported innamespaces_pending_gc; GC deletes them and no rerun is needed.server_root_idrefuses to mount, as before. The refusal names the owner object, its retirement and its life; the troubleshooting table gives the owner rewrite a restart accepts. The alternative is a newserver_root_id. Rejoining a retired id without a hand edit is a separate change.allocation_nonce,owner_lifeandretirement_verifiedare optional plain keys; 26.6.4 readers skip them. An owner withoutowner_lifereads as life 0, and a body without the new fields keeps its exact bytes.member_retired = 0with "the slot does not hold this run's farewell" and asks for a rerun, which waits until GC fences the slot (about one mount lease TTL plus a GC round).test_cas_drop_pool_memberaccepts exactly this outcome;CASDecommission.LongDrainOutlivesOneTtlplaces the stop between two renewals and requires the farewell. Follow-up: shutdown waits for an in-flight renewal.Testing
CASDecommission.UnresolvedTombstoneLeavesNoFarewell: an unresolved tombstone leaves the admin's live body, and the victim reclaims only after a fence.CaEpochAllocCoreround 12 (docs/superpowers/models/CaEpochAllocCore_RESULTS.mdon the CAS design branch): the fenced tombstone keepsNoTombOverLive; without it, and with the wider rollback rule, the sabotages are red.CAS*unit tests: release 2720, ASan 2724, all passed.test_cas_drop_pool_member: 2/2.CAS*.Commits
8c0f14fd7fc4Add an allocation nonce to the CAS writer-epoch counter86b20da89e7fRecord the CAS owner life and recheck the owner after a mount claimd1f194489a2cKeep the CAS control objects on decommission and fence the tombstone133ee5786ae3Put the writer epoch into CAS S3 staging keyse25a8282614eRemove the CAS epoch re-mint policy for decommission93adba90c85dKeep a CAS renewal refused by a mid-renewal stop releasable3a2641dc7032Document the CAS member lifecycle and decommissionChangelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
SYSTEM CAS DROP POOL MEMBERkeeps the member'sowner,epochandmountobjects, tombstones the owner before draining and verifies the retirement. Its result columnslot_removedis renamedmember_retired, andnamespaces_pending_gcis appended. Every CAS mount re-reads its owner after claiming its slot. Writer-epoch allocation is unique between same-uuid processes, and S3 staging keys carry the writer epoch. A clean CAS shutdown no longer skips its farewell when the stop races the start of a lease renewal. A decommission whose tombstone outcome is unknown no longer writes its clean farewell, so the member restarts only after GC fences its slot.Documentation entry for user-facing changes
CI/CD Options
Exclude tests:
Regression jobs to run: