Skip to content

fix(cephfs): stabilise volume replication disable#746

Open
UtkarshBhatthere wants to merge 1 commit into
mainfrom
worktree-cephfs-replication-disable-flake
Open

fix(cephfs): stabilise volume replication disable#746
UtkarshBhatthere wants to merge 1 commit into
mainfrom
worktree-cephfs-replication-disable-flake

Conversation

@UtkarshBhatthere
Copy link
Copy Markdown
Contributor

Summary

The CephFS volume-level disable (microceph replication disable cephfs --volume X --force) periodically tripped the 120s client deadline in CI (e.g. run 26505076454 job 78056192583):

Error: failed to process disable_replication request for cephfs:
Delete "http://control.socket/1.0/ops/replication/cephfs/vol": context deadline exceeded

Two missing pieces vs. the RBD path:

  • Each per-path ceph fs snapshot mirror remove blocks until the cephfs-mirror daemon ACKs the removal. With four paths and an in-flight sync, the loop can exceed the client deadline.
  • The CephFS disable path had no retries, while the RBD pool disable (microceph/ceph/rbd_mirror.go:213) does.

Changes

  • microceph/ceph/replication_cephfs.go
    • cephFSWaitForMirrorPathsIdle: pre-flight check that polls every peer's per-path status (12 × 5s linear backoff). Returns mirror path not stable: <path> naming the offending path if any path stays non-idle, instead of a generic timeout.
    • disableCephFSVolumeMirror: wraps cephFSSnapshotMirrorRemovePath in retry.Retry (10 × 5s linear), mirroring the RBD pattern.
    • buildPeerStatusFetchers: resolves volumeID + peers + admin socket once in DisableHandler and returns one closure per peer; keeps the pre-wait testable.
  • microceph/cmd/microceph/replication_disable_cephfs.go: prints an early Checking mirror path stability before disabling replication; this may take up to a minute... notice on volume-level force disable so the operator does not perceive the up-to-60s wait as a hang. Gated on --force + no --subvolume + no --dir-path so subvolume/directory disables (which don't pre-wait) stay silent.
  • microceph/ceph/replication_cephfs_test.go: 7 unit tests covering all-idle, never-stabilises, missing-path, late-stabilise, fetcher-error, multi-peer-one-non-idle, and empty-input cases. Test temporarily shrinks the attempt count + backoff so the suite stays fast.
  • .github/workflows/tests.yml: adds an if: failure() log-dump step to the cephfs-replication-test job (snap logs, cephfs-mirror logs, ceph -s, fs snapshot mirror daemon status, replication status, ceph.conf per node) so the next flake leaves the evidence needed to identify which ceph invocation actually hangs.

Test plan

  • go build ./... clean
  • go vet ./ceph/... clean
  • go test ./ceph/... -run TestCephFSWait -v — 7/7 pass
  • go test ./... — all packages pass
  • CI run on this branch with the cephfs-replication-test job passing
  • (If a future flake occurs) verify the new log-dump artifact captures the slow ceph invocation

🤖 Generated with Claude Code

The CephFS volume-level disable (`replication disable cephfs --volume X
--force`) periodically tripped the 120s client deadline in CI because:

- Each path's `ceph fs snapshot mirror remove` blocks until the
  cephfs-mirror daemon acknowledges removal. If a sync is mid-flight,
  a single path can stall long enough that the four-path loop exceeds
  the client budget.
- The disable path had no retries, unlike the RBD pool disable
  (`microceph/ceph/rbd_mirror.go:213`).

Mirror the RBD pattern and add a pre-flight stability check:

- `cephFSWaitForMirrorPathsIdle` polls every peer's per-path status
  (12 × 5s linear backoff) and returns `mirror path not stable: <path>`
  if any path stays non-idle, so the operator sees the offending path
  instead of a generic deadline error.
- `disableCephFSVolumeMirror` now wraps `cephFSSnapshotMirrorRemovePath`
  in `retry.Retry` (10 × 5s linear), absorbing transient daemon errors.
- CLI prints an early notice on volume-level force disable so the
  operator does not perceive the up-to-60s wait as a hang.
- `cephfs-replication-test` workflow job gains an `if: failure()`
  log-dump step (snap logs, mirror daemon status, replication status,
  ceph.conf per node) so the next flake leaves enough evidence behind
  to identify the slow ceph CLI invocation.

Unit tests cover idle / never-stable / missing-path / late-stabilise /
fetcher-error / multi-peer-one-non-idle / empty-input cases.

Assisted-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Utkarsh Bhatt <utkarsh_bhatt@outlook.com>
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