Skip to content

fix(agent): reclaim volume deletions blocked by an orphaned device hold - #321

Merged
onedr0p merged 3 commits into
mainfrom
fix/teardown-orphan-hold
Jul 21, 2026
Merged

onedr0p merged 3 commits into
mainfrom
fix/teardown-orphan-hold

Conversation

@onedr0p

@onedr0p onedr0p commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Fixes #319.

An orphaned device hold — a leaked filesystem freeze's dead superblock pinning open_cnt on the DRBD device with every mountpoint gone (the #311 aftermath) — makes drbdsetup down fail with (-12) Device is held open by someone forever. Teardown parked on that error indefinitely (648 attempts / 12h in the field report), paging noise for deletion-targeted volumes with zero workload impact.

The issue proposed escalating to an event + terminal condition, and optionally attempting Driver.Restart as recovery. Neither survives contact with the mechanics:

The fix: complete the teardown instead of reporting it better

The only thing an orphaned hold pins is the DRBD minor itself. The backing device, the space, and the CR are all reclaimable — they were only blocked because teardown was serialized behind down succeeding first. When the hold is provably orphaned, teardown now routes around the pinned minor:

  1. drbd.Driver.ForceDetach (new): disconnect peers, then drbdsetup detach <minor> --force. Force-detach is legal on a held-open device — dropping a failing disk under live I/O is its purpose — and it releases the backing. Refuses the wedge signature; no-ops when already Diskless or not in the kernel, so retries converge.
  2. Pools.SweepDelete destroys the freed backing; the finalizer releases through teardown's normal tail. A Normal TeardownReclaimed event names what happened.
  3. The rendered config and minor assignment deliberately stay: the kernel minor is pinned until a reboot, and releasing the number would hand it to a new volume. After the eventual reboot, the existing SweepOrphans startup pass sees an unowned .res with no kernel resource and reaps both — the residue is self-cleaning through machinery that already exists.

The orphan proof (agent.orphanHold)

All of, before the reclaim may fire:

  • deletion-targeted volume (a removed replica's volume lives on and keeps the parked retry), known minor;
  • the busy streak already crossed busyFailLimit (~5 min) — an in-flight NodeUnstage never lasts that long;
  • the held-open failure lists openers (the kernel's opener report relayed by drbdsetup) and every opener pid has exited;
  • the device is mounted in no mount namespace on the node. The agent runs hostPID, so the scan walks every process's mountinfo (deduped by ns/mnt) — this is what distinguishes a dead superblock from a force-deleted pod whose container still runs with the volume mounted in its own namespace while the host table is clean (Teardown wedges: drbdsetup down SIGKILLed in a loop, only a reboot clears it (recurring) #195: never destroy a backing under a consumer). Raw-block publishes are matched by the devtmpfs bind root, filesystem mounts by the device's major:minor.

Any doubt — no opener list, an unreadable /proc, a surviving mount, a live pid — reads as "live consumer" and the parked retry stands, exactly as before.

The wedge stays parked, quietly

A kernel-wedged teardown (LINBIT/drbd#137) has no equivalent: DRBD still pins the backing mid-detach, and releasing the finalizer would leak it forever. That path keeps park-and-page, but now latches — reportWedged re-emitted its Warning Event, Error log, and a status write every 5-minute cycle (123 of them in the field report); it now emits once on the transition and stays at V(1) while parked, with the paging gauge still re-raised every cycle. reportBusy's parked-cycle Error log (the 648-line stream) demotes the same way; its Event and status Message were already latched.

Testing

  • Unit: ForceDetach (sequence, wedge refusal, Diskless/absent no-ops), the orphan-proof helpers (opener parsing, cross-namespace mount scan incl. the container-namespace hazard, unreadable-/proc fail-closed), reconciler paths (reclaim after the full escalation, live-opener and mounted-device stay parked, wedge latch).
  • Integration (envtest): green.
  • golangci-lint: 0 issues.
  • E2E (new spec, test/e2e/orphanhold_test.go): reproduces agent: reconcile backoff should not retry unwinnable errors indefinitely (busy openers, kernel wedge) #319 on the real QEMU cluster — freeze the staged filesystem through the staging mountpoint, lazily unmount it out from under the fix(agent): recover volumes wedged by a leaked filesystem freeze #312 thaw-at-unstage guard, delete the pod, verify the kernel still counts an opener with no mounts left (open:yes), then delete the PVC and assert the MiroirVolume completes deletion through the reclaim, the backing LV is destroyed, the zombie minor remains, and the TeardownReclaimed event fired. Runs on the conformance leg (RUN_SPECS=1); the spec timeout accounts for riding the full busy escalation (test.sh go-test timeout raised to 35m).

A leaked filesystem freeze's dead superblock (issue #311) pins the DRBD
device's open_cnt with no mountpoint left to thaw, so drbdsetup down is
refused forever and teardown parked on the error indefinitely.

The only thing such a hold pins is the kernel minor itself, so a
deletion now routes around it once the hold is provably orphaned (past
the busy escalation, every reported opener pid exited, device mounted
in no mount namespace on the node): force-detach frees the backing, the
sweep destroys it, and the finalizer releases. The rendered config and
minor assignment stay so the pinned minor cannot be reassigned; the
startup orphan sweep reaps both after the next reboot.

The kernel-wedge path keeps its parked retry but latches the Warning
Event and Error log on the transition instead of re-emitting them every
cycle, and the parked busy retry demotes its per-cycle Error log the
same way.

A new e2e spec reproduces the leak on the QEMU cluster (freeze, strip
the mountpoints under the thaw-at-unstage guard, delete) and asserts
the deletion completes through the reclaim.

Fixes #319

Signed-off-by: Devin Buhl <devin@buhl.casa>
@greptile-apps

greptile-apps Bot commented Jul 21, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR adds a guarded reclaim path for DRBD volume deletions blocked by orphaned device holds. The main changes are:

  • New orphan-hold checks for DRBD opener PIDs and cross-namespace mount visibility.
  • A ForceDetach path that releases the backing device while keeping the pinned minor reserved until reboot.
  • Reconciler logic that reclaims deletion-targeted volumes only after the busy escalation threshold is crossed.
  • Latched busy and wedged reporting to avoid repeated identical events and status churn.
  • Unit and QEMU e2e coverage for the reclaim path and live-consumer safeguards.

Confidence Score: 5/5

Safe to merge with low risk.

The reclaim path is narrowly gated by deletion state, known minor, busy escalation, opener parsing, PID liveness, and a fail-closed mount scan. The previously reported mountinfo failure and namespace dedupe cases are addressed in the current diff, with focused unit coverage and an e2e reproduction.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

    • Ran DRBD force-detach and wedge tests; the targeted tests passed.
    • Executed unit tests for the orphan-hold agent helper and reconciler reclaim/parking; the tests passed.
    • Built the e2e package with the e2e build tag and verified compilation succeeded.
    • Identified tooling blockers that prevent full end-to-end validation, including missing local tools for QEMU/Kubernetes e2e, envtest, lint, and cluster validation.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
internal/agent/orphanhold.go Adds fail-closed orphaned-hold detection helpers for parsing DRBD opener PIDs and scanning all visible mount namespaces.
internal/agent/reconciler.go Routes deletion teardown around proven orphaned DRBD holds via force detach and quiets repeated busy/wedged escalation reporting.
internal/drbd/drbd.go Refactors peer disconnect logic and adds idempotent ForceDetach with wedge refusal and Diskless/absent no-ops.
test/e2e/orphanhold_test.go Adds an ordered QEMU e2e reproduction that verifies reclaim of a frozen orphaned DRBD hold and expected residue.

Reviews (3): Last reviewed commit: "fix(agent): keep a shared mount namespac..." | Re-trigger Greptile

Comment thread internal/agent/orphanhold.go Resolved
A live process's unreadable mountinfo could hide the one table listing
the device and let the scan report unmounted, authorizing a reclaim
under a consumer. Only a process gone mid-scan is skipped now: reaped
reads ENOENT and a zombie EINVAL (verified empirically), and neither
can hold a mount; every other read error keeps teardown parked.

Signed-off-by: Devin Buhl <devin@buhl.casa>
Comment thread internal/agent/orphanhold.go Resolved
The scan marked a namespace seen at readlink time, before its table was
read. A process exiting between the readlink and the read was skipped
as gone while its surviving siblings were then skipped as duplicates,
so the shared namespace's table - possibly the one listing the device -
was never read and the device could read as orphaned. The namespace is
now marked covered only after a successful read.

Signed-off-by: Devin Buhl <devin@buhl.casa>
@onedr0p
onedr0p merged commit 6e76957 into main Jul 21, 2026
9 of 10 checks passed
@onedr0p
onedr0p deleted the fix/teardown-orphan-hold branch July 21, 2026 15:50
doonga pushed a commit to greyrock-labs/home-ops that referenced this pull request Jul 21, 2026
….11.1 ➔ 0.11.7) (#98)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/home-operations/charts/miroir](https://github.com/home-operations/miroir) | patch | `0.11.1` → `0.11.7` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/11) for more information.

---

### Release Notes

<details>
<summary>home-operations/miroir (ghcr.io/home-operations/charts/miroir)</summary>

### [`v0.11.7`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0117-2026-07-21)

[Compare Source](home-operations/miroir@0.11.6...0.11.7)

##### Bug Fixes

- **agent:** reclaim volume deletions blocked by an orphaned device hold ([#&#8203;321](home-operations/miroir#321)) ([6e76957](home-operations/miroir@6e76957))
- **deps:** update module github.com/go-logr/logr (v1.4.3 → v1.4.4) ([#&#8203;315](home-operations/miroir#315)) ([1d5350e](home-operations/miroir@1d5350e))

##### Miscellaneous Chores

- **mise:** Update tool aqua:astral-sh/uv (0.11.29 → 0.11.30) ([#&#8203;314](home-operations/miroir#314)) ([2110661](home-operations/miroir@2110661))
- **mise:** Update tool talos (1.13.6 → 1.13.7) ([#&#8203;320](home-operations/miroir#320)) ([1e6e587](home-operations/miroir@1e6e587))

### [`v0.11.6`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0116-2026-07-20)

[Compare Source](home-operations/miroir@0.11.5...0.11.6)

##### Features

- **deps:** update module github.com/prometheus/client\_golang (v1.23.2 → v1.24.0) ([#&#8203;310](home-operations/miroir#310)) ([58726c5](home-operations/miroir@58726c5))

##### Bug Fixes

- **agent:** recover volumes wedged by a leaked filesystem freeze ([#&#8203;312](home-operations/miroir#312)) ([de3ed0b](home-operations/miroir@de3ed0b))

##### Documentation

- fix stale and self-contradictory claims from a documentation review ([#&#8203;303](home-operations/miroir#303)) ([639ef79](home-operations/miroir@639ef79))

##### Miscellaneous Chores

- disable Talos dashboard in e2e schematic ([d9005df](home-operations/miroir@d9005df))

### [`v0.11.5`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0115-2026-07-19)

[Compare Source](home-operations/miroir@0.11.4...0.11.5)

##### Bug Fixes

- **agent:** resize a restore clone's backing after DRBD attach ([#&#8203;300](home-operations/miroir#300)) ([8f611e9](home-operations/miroir@8f611e9))

### [`v0.11.4`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0114-2026-07-19)

[Compare Source](home-operations/miroir@0.11.3...0.11.4)

##### Bug Fixes

- **agent:** freeze mounted filesystems before snapshot cuts ([#&#8203;292](home-operations/miroir#292)) ([5dbb657](home-operations/miroir@5dbb657))

##### Documentation

- **quickstart:** note group snapshot CRD conversion requirements ([#&#8203;287](home-operations/miroir#287)) ([fdf393c](home-operations/miroir@fdf393c))

### [`v0.11.3`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0113-2026-07-18)

[Compare Source](home-operations/miroir@0.11.2...0.11.3)

##### Features

- **api:** show a ready/total count in the Replicas printcolumn ([#&#8203;286](home-operations/miroir#286)) ([21a7a14](home-operations/miroir@21a7a14))

##### Bug Fixes

- **agent:** break the fast path when phase contradicts per-node status ([#&#8203;283](home-operations/miroir#283)) ([13f5769](home-operations/miroir@13f5769))
- **backend:** heal missing lvmthin device nodes via vgmknodes ([#&#8203;282](home-operations/miroir#282)) ([78518e8](home-operations/miroir@78518e8))

##### Miscellaneous Chores

- **main:** release 0.11.2 ([#&#8203;278](home-operations/miroir#278)) ([08647c3](home-operations/miroir@08647c3))

### [`v0.11.2`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0112-2026-07-18)

[Compare Source](home-operations/miroir@0.11.1...0.11.2)

##### Features

- **csi:** implement crash-consistent volume group snapshots ([#&#8203;268](home-operations/miroir#268)) ([bef5efc](home-operations/miroir@bef5efc))
- **csi:** support PVC clone via an internal clone-source snapshot ([#&#8203;267](home-operations/miroir#267)) ([569920e](home-operations/miroir@569920e))

##### Bug Fixes

- **agent:** never lift a barrier a sibling round co-holds when closing a round ([#&#8203;275](home-operations/miroir#275)) ([d99c6eb](home-operations/miroir@d99c6eb))
- **backend:** keep thin snapshot LVs inactive and serialize lvm commands ([#&#8203;277](home-operations/miroir#277)) ([022b1da](home-operations/miroir@022b1da))
- **csi:** stop group snapshot deletion from stranding suspend-io barriers ([#&#8203;274](home-operations/miroir#274)) ([8294491](home-operations/miroir@8294491))

##### Miscellaneous Chores

- **mise:** Update tool cosign (3.1.1 → 3.1.2) ([#&#8203;266](home-operations/miroir#266)) ([7b7bd20](home-operations/miroir@7b7bd20))

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNjAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI3Mi4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/98
gabrielcosi pushed a commit to gabrielcosi/home-ops that referenced this pull request Jul 21, 2026
….11.6 ➔ 0.11.7) (#18)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/home-operations/charts/miroir](https://github.com/home-operations/miroir) | patch | `0.11.6` → `0.11.7` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/2) for more information.

---

### Release Notes

<details>
<summary>home-operations/miroir (ghcr.io/home-operations/charts/miroir)</summary>

### [`v0.11.7`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0117-2026-07-21)

[Compare Source](home-operations/miroir@0.11.6...0.11.7)

##### Bug Fixes

- **agent:** reclaim volume deletions blocked by an orphaned device hold ([#&#8203;321](home-operations/miroir#321)) ([6e76957](home-operations/miroir@6e76957))
- **deps:** update module github.com/go-logr/logr (v1.4.3 → v1.4.4) ([#&#8203;315](home-operations/miroir#315)) ([1d5350e](home-operations/miroir@1d5350e))

##### Miscellaneous Chores

- **mise:** Update tool aqua:astral-sh/uv (0.11.29 → 0.11.30) ([#&#8203;314](home-operations/miroir#314)) ([2110661](home-operations/miroir@2110661))
- **mise:** Update tool talos (1.13.6 → 1.13.7) ([#&#8203;320](home-operations/miroir#320)) ([1e6e587](home-operations/miroir@1e6e587))

</details>

---

### Configuration

📅 **Schedule**: (in timezone Europe/Berlin)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNjkuMSIsInVwZGF0ZWRJblZlciI6IjQzLjI2OS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.xcd.dev/gabrielcosi/home-ops/pulls/18
gwzill pushed a commit to gwzill/home-ops that referenced this pull request Jul 28, 2026
…0.10.5 ➔ 0.11.11) (bjw-s-labs#956)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/home-operations/charts/miroir](https://github.com/home-operations/miroir) | minor | `0.10.5` → `0.11.11` |

---

### Release Notes

<details>
<summary>home-operations/miroir (ghcr.io/home-operations/charts/miroir)</summary>

### [`v0.11.11`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01111-2026-07-24)

[Compare Source](home-operations/miroir@0.11.10...0.11.11)

##### Bug Fixes

- **deps:** update module github.com/prometheus/client\_golang (v1.24.0 → v1.24.1) ([#&bjw-s-labs#8203;348](home-operations/miroir#348)) ([20ac78a](home-operations/miroir@20ac78a))
- **helm:** stamp Chart.yaml version on release ([#&bjw-s-labs#8203;352](home-operations/miroir#352)) ([e6e102a](home-operations/miroir@e6e102a))

##### Miscellaneous Chores

- **github-release:** Update release helm-unittest/helm-unittest (v1.1.1 → v1.1.2) ([#&bjw-s-labs#8203;351](home-operations/miroir#351)) ([ff07360](home-operations/miroir@ff07360))

### [`v0.11.10`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01110-2026-07-24)

[Compare Source](home-operations/miroir@0.11.9...0.11.10)

##### Bug Fixes

- **agent:** demote DRBD Primaries before OS teardown + ZFS busy retry + restore fallback ([#&bjw-s-labs#8203;345](home-operations/miroir#345)) ([ab36200](home-operations/miroir@ab36200))

##### Miscellaneous Chores

- **mise:** Update tool aqua:astral-sh/uv (0.11.31 → 0.11.32) ([#&bjw-s-labs#8203;346](home-operations/miroir#346)) ([0ac31d4](home-operations/miroir@0ac31d4))

### [`v0.11.9`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0119-2026-07-23)

[Compare Source](home-operations/miroir@0.11.8...0.11.9)

##### Bug Fixes

- **agent:** fence snapshot barrier writes against stale rounds ([#&bjw-s-labs#8203;342](home-operations/miroir#342)) ([9cf42a8](home-operations/miroir@9cf42a8))
- **container:** update image registry.k8s.io/kubectl (v1.36.2 → v1.36.3) ([#&bjw-s-labs#8203;339](home-operations/miroir#339)) ([37f0f17](home-operations/miroir@37f0f17))
- **deps:** update kubernetes monorepo (v0.36.2 → v0.36.3) ([#&bjw-s-labs#8203;341](home-operations/miroir#341)) ([8384aeb](home-operations/miroir@8384aeb))
- detect stale replica readiness, surface busy-teardown live consumers and unreachable CSI nodes ([#&bjw-s-labs#8203;344](home-operations/miroir#344)) ([4619407](home-operations/miroir@4619407))

##### Miscellaneous Chores

- **mise:** Update tool kubectl (1.36.2 → 1.36.3) ([#&bjw-s-labs#8203;340](home-operations/miroir#340)) ([6794e1c](home-operations/miroir@6794e1c))

### [`v0.11.8`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0118-2026-07-22)

[Compare Source](home-operations/miroir@0.11.7...0.11.8)

##### Features

- **csi:** reshape replica count on restore (grow and shrink) ([#&bjw-s-labs#8203;322](home-operations/miroir#322)) ([bf7f583](home-operations/miroir@bf7f583))

##### Bug Fixes

- **agent:** include connectivity in volume readiness ([#&bjw-s-labs#8203;336](home-operations/miroir#336)) ([16403fc](home-operations/miroir@16403fc))
- conformance stabilization (drbd, csi, stage) ([#&bjw-s-labs#8203;333](home-operations/miroir#333)) ([c333ded](home-operations/miroir@c333ded))
- **csi:** honor topology when shrinking restores ([#&bjw-s-labs#8203;326](home-operations/miroir#326)) ([980c0b3](home-operations/miroir@980c0b3))

##### Miscellaneous Chores

- **mise:** Update tool aqua:astral-sh/uv (0.11.30 → 0.11.31) ([#&bjw-s-labs#8203;330](home-operations/miroir#330)) ([3322d69](home-operations/miroir@3322d69))
- **mise:** Update tool oxfmt (0.59.0 → 0.60.0) ([#&bjw-s-labs#8203;329](home-operations/miroir#329)) ([6657d7a](home-operations/miroir@6657d7a))
- **mise:** Update tool zizmor (1.27.0 → 1.28.0) ([#&bjw-s-labs#8203;324](home-operations/miroir#324)) ([91c09c8](home-operations/miroir@91c09c8))

### [`v0.11.7`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0117-2026-07-21)

[Compare Source](home-operations/miroir@0.11.6...0.11.7)

##### Bug Fixes

- **agent:** reclaim volume deletions blocked by an orphaned device hold ([#&bjw-s-labs#8203;321](home-operations/miroir#321)) ([6e76957](home-operations/miroir@6e76957))
- **deps:** update module github.com/go-logr/logr (v1.4.3 → v1.4.4) ([#&bjw-s-labs#8203;315](home-operations/miroir#315)) ([1d5350e](home-operations/miroir@1d5350e))

##### Miscellaneous Chores

- **mise:** Update tool aqua:astral-sh/uv (0.11.29 → 0.11.30) ([#&bjw-s-labs#8203;314](home-operations/miroir#314)) ([2110661](home-operations/miroir@2110661))
- **mise:** Update tool talos (1.13.6 → 1.13.7) ([#&bjw-s-labs#8203;320](home-operations/miroir#320)) ([1e6e587](home-operations/miroir@1e6e587))

### [`v0.11.6`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0116-2026-07-20)

[Compare Source](home-operations/miroir@0.11.5...0.11.6)

##### Features

- **deps:** update module github.com/prometheus/client\_golang (v1.23.2 → v1.24.0) ([#&bjw-s-labs#8203;310](home-operations/miroir#310)) ([58726c5](home-operations/miroir@58726c5))

##### Bug Fixes

- **agent:** recover volumes wedged by a leaked filesystem freeze ([#&bjw-s-labs#8203;312](home-operations/miroir#312)) ([de3ed0b](home-operations/miroir@de3ed0b))

##### Documentation

- fix stale and self-contradictory claims from a documentation review ([#&bjw-s-labs#8203;303](home-operations/miroir#303)) ([639ef79](home-operations/miroir@639ef79))

##### Miscellaneous Chores

- disable Talos dashboard in e2e schematic ([d9005df](home-operations/miroir@d9005df))

### [`v0.11.5`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0115-2026-07-19)

[Compare Source](home-operations/miroir@0.11.4...0.11.5)

##### Bug Fixes

- **agent:** resize a restore clone's backing after DRBD attach ([#&bjw-s-labs#8203;300](home-operations/miroir#300)) ([8f611e9](home-operations/miroir@8f611e9))

### [`v0.11.4`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0114-2026-07-19)

[Compare Source](home-operations/miroir@0.11.3...0.11.4)

##### Bug Fixes

- **agent:** freeze mounted filesystems before snapshot cuts ([#&bjw-s-labs#8203;292](home-operations/miroir#292)) ([5dbb657](home-operations/miroir@5dbb657))

##### Documentation

- **quickstart:** note group snapshot CRD conversion requirements ([#&bjw-s-labs#8203;287](home-operations/miroir#287)) ([fdf393c](home-operations/miroir@fdf393c))

### [`v0.11.3`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0113-2026-07-18)

[Compare Source](home-operations/miroir@0.11.2...0.11.3)

##### Features

- **api:** show a ready/total count in the Replicas printcolumn ([#&bjw-s-labs#8203;286](home-operations/miroir#286)) ([21a7a14](home-operations/miroir@21a7a14))

##### Bug Fixes

- **agent:** break the fast path when phase contradicts per-node status ([#&bjw-s-labs#8203;283](home-operations/miroir#283)) ([13f5769](home-operations/miroir@13f5769))
- **backend:** heal missing lvmthin device nodes via vgmknodes ([#&bjw-s-labs#8203;282](home-operations/miroir#282)) ([78518e8](home-operations/miroir@78518e8))

##### Miscellaneous Chores

- **main:** release 0.11.2 ([#&bjw-s-labs#8203;278](home-operations/miroir#278)) ([08647c3](home-operations/miroir@08647c3))

### [`v0.11.2`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0112-2026-07-18)

[Compare Source](home-operations/miroir@0.11.1...0.11.2)

##### Features

- **csi:** implement crash-consistent volume group snapshots ([#&bjw-s-labs#8203;268](home-operations/miroir#268)) ([bef5efc](home-operations/miroir@bef5efc))
- **csi:** support PVC clone via an internal clone-source snapshot ([#&bjw-s-labs#8203;267](home-operations/miroir#267)) ([569920e](home-operations/miroir@569920e))

##### Bug Fixes

- **agent:** never lift a barrier a sibling round co-holds when closing a round ([#&bjw-s-labs#8203;275](home-operations/miroir#275)) ([d99c6eb](home-operations/miroir@d99c6eb))
- **backend:** keep thin snapshot LVs inactive and serialize lvm commands ([#&bjw-s-labs#8203;277](home-operations/miroir#277)) ([022b1da](home-operations/miroir@022b1da))
- **csi:** stop group snapshot deletion from stranding suspend-io barriers ([#&bjw-s-labs#8203;274](home-operations/miroir#274)) ([8294491](home-operations/miroir@8294491))

##### Miscellaneous Chores

- **mise:** Update tool cosign (3.1.1 → 3.1.2) ([#&bjw-s-labs#8203;266](home-operations/miroir#266)) ([7b7bd20](home-operations/miroir@7b7bd20))

### [`v0.11.1`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#01111-2026-07-24)

[Compare Source](home-operations/miroir@0.11.0...0.11.1)

##### Bug Fixes

- **deps:** update module github.com/prometheus/client\_golang (v1.24.0 → v1.24.1) ([#&bjw-s-labs#8203;348](home-operations/miroir#348)) ([20ac78a](home-operations/miroir@20ac78a))
- **helm:** stamp Chart.yaml version on release ([#&bjw-s-labs#8203;352](home-operations/miroir#352)) ([e6e102a](home-operations/miroir@e6e102a))

##### Miscellaneous Chores

- **github-release:** Update release helm-unittest/helm-unittest (v1.1.1 → v1.1.2) ([#&bjw-s-labs#8203;351](home-operations/miroir#351)) ([ff07360](home-operations/miroir@ff07360))

### [`v0.11.0`](https://github.com/home-operations/miroir/blob/HEAD/CHANGELOG.md#0110-2026-07-17)

[Compare Source](home-operations/miroir@0.10.5...0.11.0)

##### ⚠ BREAKING CHANGES

- topology UX overhaul — CR-first manifests, node groups, block-implied backend ([#&bjw-s-labs#8203;255](home-operations/miroir#255))
- **api:** drop the deprecated flat MiroirNodeStatus capacity fields ([#&bjw-s-labs#8203;254](home-operations/miroir#254))
- **chart:** render MiroirNode CRs from the chart; watch-driven topology ([#&bjw-s-labs#8203;237](home-operations/miroir#237))

##### Features

- **api:** drop the deprecated flat MiroirNodeStatus capacity fields ([#&bjw-s-labs#8203;254](home-operations/miroir#254)) ([b889c70](home-operations/miroir@b889c70))
- **chart:** render MiroirNode CRs from the chart; watch-driven topology ([#&bjw-s-labs#8203;237](home-operations/miroir#237)) ([efc2180](home-operations/miroir@efc2180))
- **chart:** uninstall data-destruction gate and rook-inspired UX knobs ([#&bjw-s-labs#8203;246](home-operations/miroir#246)) ([af565e0](home-operations/miroir@af565e0))
- topology UX overhaul — CR-first manifests, node groups, block-implied backend ([#&bjw-s-labs#8203;255](home-operations/miroir#255)) ([5de436d](home-operations/miroir@5de436d))

##### Bug Fixes

- **agent:** close two startup edges around a vanished or pool-less MiroirNode ([#&bjw-s-labs#8203;244](home-operations/miroir#244)) ([71e45c5](home-operations/miroir@71e45c5))
- **agent:** gate snapshot rounds on peer disk states and the kernel barrier ([#&bjw-s-labs#8203;248](home-operations/miroir#248)) ([f2af9f5](home-operations/miroir@f2af9f5))
- **backend:** loopfile crash-safety and lvmthin pool activation ([#&bjw-s-labs#8203;250](home-operations/miroir#250)) ([428c15e](home-operations/miroir@428c15e))
- **csi:** expansion guardrails, forced NFS cleanup, and client-leg refusals ([#&bjw-s-labs#8203;251](home-operations/miroir#251)) ([47a08c2](home-operations/miroir@47a08c2))
- **csi:** name the address-conflict exclusion in placement refusals ([#&bjw-s-labs#8203;243](home-operations/miroir#243)) ([7a5ce61](home-operations/miroir@7a5ce61))
- **drbd:** release swept orphans' minors, dedupe status fetches ([#&bjw-s-labs#8203;252](home-operations/miroir#252)) ([9a871c1](home-operations/miroir@9a871c1))
- **image:** reject NBD devices in the lvm global\_filter ([#&bjw-s-labs#8203;257](home-operations/miroir#257)) ([1d72a7f](home-operations/miroir@1d72a7f))
- **membership:** auto-evict liveness gates and tie-breaker client handling ([#&bjw-s-labs#8203;249](home-operations/miroir#249)) ([07fac29](home-operations/miroir@07fac29))

##### Performance Improvements

- **agent:** scope the MiroirNode informer to the node's own object ([#&bjw-s-labs#8203;245](home-operations/miroir#245)) ([eb48b98](home-operations/miroir@eb48b98))
- **controller:** trim redundant topology folds and watch fan-out ([#&bjw-s-labs#8203;247](home-operations/miroir#247)) ([68065d5](home-operations/miroir@68065d5))

##### Documentation

- add an upgrading guide with the 0.9/0.10 migrations ([#&bjw-s-labs#8203;235](home-operations/miroir#235)) ([7afa383](home-operations/miroir@7afa383))
- remove em-dashes, tighten prose, and add admonitions ([#&bjw-s-labs#8203;238](home-operations/miroir#238)) ([e910b73](home-operations/miroir@e910b73))

##### Miscellaneous Chores

- **release:** add the helm chart section to the release-please config ([9f13e52](home-operations/miroir@9f13e52))
- sixth-cycle polish — stale comments, DRY, docs, and named test gaps ([#&bjw-s-labs#8203;253](home-operations/miroir#253)) ([52bbcb2](home-operations/miroir@52bbcb2))

</details>

---

### Configuration

📅 **Schedule**: (in timezone Europe/Amsterdam)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNTIuMSIsInVwZGF0ZWRJblZlciI6IjQzLjI4MS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->

Co-authored-by: Bernd Schorgers <me@bjw-s.dev>
Reviewed-on: https://git.bjw-s.dev/bjw-s/home-ops/pulls/956
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.

agent: reconcile backoff should not retry unwinnable errors indefinitely (busy openers, kernel wedge)

1 participant