From e21c686939dfe1e960767093ff42b77c1119f987 Mon Sep 17 00:00:00 2001 From: pingqiu Date: Sun, 26 Apr 2026 10:37:20 -0700 Subject: [PATCH] =?UTF-8?q?G5-4=20m01+M02=20bring-up=20=E2=80=94=20sw=20an?= =?UTF-8?q?swer:=20--expected-slots-per-volume=20flag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: cmd/blockmaster/main.go hardcoded ExpectedSlotsPerVolume=3. QA's 2-slot topology silently failed validateVolumeTopology in the controller, so no assignments were minted, no master-log lines, and volumes timed out at durable open. Fix landed in seaweed_block@f5de7c5: --expected-slots-per-volume CLI flag, default 3, set 2 for the 2-node smoke. QA next: rebuild blockmaster, pass --expected-slots-per-volume 2 in §3.4 of the handoff command sequence; rest unchanged. --- .../v3-phase-15-g5-m0102-bringup-answer.md | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 sw-block/design/v3-phase-15-g5-m0102-bringup-answer.md diff --git a/sw-block/design/v3-phase-15-g5-m0102-bringup-answer.md b/sw-block/design/v3-phase-15-g5-m0102-bringup-answer.md new file mode 100644 index 000000000..32e7580e5 --- /dev/null +++ b/sw-block/design/v3-phase-15-g5-m0102-bringup-answer.md @@ -0,0 +1,103 @@ +# G5-4 m01+M02 Bring-Up — sw answer + +**Date**: 2026-04-26 +**From**: sw +**To**: QA +**Refs**: [v3-phase-15-g5-m0102-bringup-handoff.md](v3-phase-15-g5-m0102-bringup-handoff.md) + +--- + +## §1 Root cause + +`cmd/blockmaster/main.go:82` hardcoded `ExpectedSlotsPerVolume: 3`. + +QA's topology has 2 slots (m01-primary + m02-replica). The TopologyController calls `validateVolumeTopology(snap, 3)` on every observed-state snapshot. With 2 slots in the snapshot, validation returns `topology: volume v1 has 2 slots, want 3` and the entire `SubmitObservedState` call returns the error — no assignments minted, no per-volume processing. + +That error propagates back to the caller (observation host) but the controller doesn't log it on the master log channel. **That's why §3.7 master log was silent** — the controller was rejecting every snapshot, but the rejection went to a return value, not a log line. + +Downstream chain (the symptom QA saw): +- master rejects snapshot → publisher never gets a per-volume line → no assignment ever fanned out +- volumes connect to master, subscribe to assignments, wait +- volume's `dp.Open()` calls `waitHealthy()` (10s timeout) → projection never flips Healthy → returns `frontend.ErrNotReady` → `blockvolume: durable open: frontend: volume not ready` +- volume exits before status server stays up + +So none of QA's hypotheses (§4 #1–#4) was the active cause; the gap is one missing CLI flag. + +## §2 Answers to §1 questions + +| # | Question | Answer | +|---|---|---| +| 1 | Missing CLI flag? | **YES — `--expected-slots-per-volume`**. Just added (commit below). Default stays 3 (production RF=3); pass `2` for the 2-node smoke. | +| 2 | Topology YAML needs more fields? | No. The schema you used (volumes/slots/{replica_id, server_id}) is exactly right. | +| 3 | Master needs explicit "mint" trigger? | No. Master mints automatically once heartbeats arrive AND topology validation passes. Your heartbeats arrived; topology validation failed. | +| 4 | Settling period > 4s? | No. Once the slot-count gate passes, mint happens within one heartbeat round-trip (sub-second). Volumes will reach Healthy within ~3s. | +| 5 | Reference test? | `core/authority/convergence_route_test.go` (especially `TestConvergence_Route1_*` around line 200) shows the canonical heartbeat → mint → publish → subscribe chain. All those tests use 3-slot configs because the controller's invariant is "system targets RF=3 in production." | + +## §3 The fix + +Adding `--expected-slots-per-volume` flag to blockmaster (committed in seaweed_block working tree): + +``` +diff --git a/cmd/blockmaster/main.go b/cmd/blockmaster/main.go +@@ flags struct ++ expectedSlotsPerVol int +@@ parseFlags ++ fs.IntVar(&f.expectedSlotsPerVol, "expected-slots-per-volume", 3, ++ "RF/expected slot count per volume; the controller rejects observation ++ snapshots whose slot count differs (default 3, set to 2 for 2-node ++ smoke clusters)") +@@ run +- ControllerConfig: authority.TopologyControllerConfig{ExpectedSlotsPerVolume: 3}, ++ ControllerConfig: authority.TopologyControllerConfig{ExpectedSlotsPerVolume: f.expectedSlotsPerVol}, +``` + +Build + tests pass. Ready to land. + +## §4 Updated bring-up sequence for the 2-node smoke + +Two changes vs §3 of the handoff: + +1. **Rebuild the blockmaster binary** to pick up the new flag +2. **Pass `--expected-slots-per-volume 2`** to blockmaster + +Updated §3.4: + +```bash +ssh -i /c/work/dev_server/testdev_key testdev@192.168.1.181 \ + "nohup /mnt/smb/work/share/g5-binaries/blockmaster \ + --authority-store /tmp/g5sm/master-store \ + --listen 0.0.0.0:9180 \ + --topology /tmp/g5sm/topology.yaml \ + --expected-slots-per-volume 2 \ + --t0-print-ready \ + > /tmp/g5sm/logs/master.log 2>&1