Skip to content

Fix crutest replace workload to use new regions - #2078

Open
leftwo wants to merge 1 commit into
alan/crutest-fresh-sparefrom
alan/crutest-live-replace-fresh
Open

leftwo wants to merge 1 commit into
alan/crutest-fresh-sparefrom
alan/crutest-live-replace-fresh

Conversation

@leftwo

@leftwo leftwo commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

In the crutest replace workload after each live repair, give the
downstairs that was replaced a new empty region before it is used as
the next replacement. This matches what the control plane does
and avoids re-use of an existing region which comes with been_active
set (which we don't want)

This uses the dsc recreate from #2073 and the crutest recreate_downstairs
from #2074.

The replace workload now requires --dsc, so update the buildomat job
to switch to that instead of providing targets.

If the replace task ends, the IO task now stops instead of running IO
until the count is reached, so a replace failure is reported right away.

@leftwo
leftwo added this pull request to stack #2077 November 6, 2026 21:06
@leftwo
leftwo force-pushed the alan/crutest-live-replace-fresh branch from c4208a9 to 67e9722 Compare November 6, 2026 21:08
@leftwo
leftwo force-pushed the alan/crutest-live-replace-fresh branch from 67e9722 to 918d2d3 Compare November 6, 2026 21:19
@leftwo leftwo changed the title Alan/crutest live replace fresh Fix crutest replace workload to use new regions Nov 6, 2026
@leftwo

leftwo commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

@claude review

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Comment thread crutest/src/main.rs
// The old downstairs is no longer part of the volume. Give it a
// new region, so when it is used as a replacement it is like the
// new region the product would provide.
recreate_downstairs(&dsc_client, old_ds as u32, &log).await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 (optional) An operator running crutest replace can have the wrong region wiped. This happens when --replacement is not dsc client ds_total, or when the targets come from --vcr. The call recreate_downstairs(&dsc_client, old_ds as u32, &log) assumes targets[i] is dsc cid i, and nothing checks that. If the order differs, the call stops and recreates a different downstairs, which may still be live in the volume. Fix: resolve each target to its dsc cid by matching dsc_get_port(cid) against the target port, or check at startup that they match and bail otherwise. This covers the replacement address and VCR-supplied targets.

Why this was flagged

replace_workload treats the targets index as the dsc client id at main.rs:3036. Targets built from dsc (main.rs:830-843) cover cids 0..sv_count*3-1. The replacement is whatever the user passes (main.rs:1326). With --vcr, the targets come from vcr.targets() (main.rs:779) in VCR order. Two inputs break the mapping. One is a dsc with 5 regions and --replacement set to cid 4's port; the old_ds=3 iteration then recreates cid 3 and not the downstairs that was actually swapped out. The other is a VCR whose target order differs from the dsc cids; there recreate_downstairs stops, wipes and restarts a downstairs that is still an active member of the volume (main.rs:2545-2585), so the run fails or loses data. On the base branch, replace_workload never stopped or recreated any region, so these inputs could not wipe a live downstairs. The CI script happens to line up (4 regions, replacement 8840 = cid 3), but nothing validates the mapping.

Verification: Nit. main.rs:3036 calls recreate_downstairs(&dsc_client, old_ds as u32, &log), where old_ds is an index into targets. Nothing checks that targets[old_ds] really is dsc cid old_ds. Unlike ReplaceBeforeActive and ReplaceReconcile, the Replace branch has no region count check. With --vcr order, a live downstairs gets wiped. Every in-repo caller passes the matching cid.

After each live repair in the replace workload, give the downstairs that
was replaced a new, empty region before it is used as the next
replacement.  This makes it look like the new region the control-plane
would provide, instead of reusing a region that was already part of the
volume and would come with been_active status we don't want.

Add a dsc endpoint instead of targets to the replace workload in the live
repair buildomat job..

If the replace task ends, stop the IO task instead of running IO until
the count is reached.
@leftwo
leftwo force-pushed the alan/crutest-live-replace-fresh branch from 918d2d3 to 2afab7e Compare November 10, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant