Choose the collector's NVMe acquisition path #16

Closed
opened 2026-08-31 15:16:05 +00:00 by xavierk · 2 comments
Owner

Parent map: Chart Fenris's persistent TUI monitoring redesign

Question

Which acquisition path does the privileged collector pin to for SMART/Health and identity reads: the official libnvme Python bindings (SWIG; attribute getters deliver normalized sysfs values), shelling out to nvme CLI JSON output (untrimmed strings, adds a binary dependency), or staying on smartctl -j plus a sysfs read for subnqn? Decide against dependency weight (ADR 0004's exact lockfile), privilege needs, packaging, and normalization consistency with the identity-key rules in the controller-identity research.

Parent map: [Chart Fenris's persistent TUI monitoring redesign](https://git.bongbetic.com/xavierk/Fenris/issues/1) ## Question Which acquisition path does the privileged collector pin to for SMART/Health and identity reads: the official libnvme Python bindings (SWIG; attribute getters deliver normalized sysfs values), shelling out to `nvme` CLI JSON output (untrimmed strings, adds a binary dependency), or staying on `smartctl -j` plus a sysfs read for `subnqn`? Decide against dependency weight (ADR 0004's exact lockfile), privilege needs, packaging, and normalization consistency with the identity-key rules in the [controller-identity research](https://git.bongbetic.com/xavierk/Fenris/src/branch/research/controller-identity/docs/research/controller-identity.md).
xavierk added this to the Wayfinder: Fenris persistent TUI monitoring redesign milestone 2026-08-31 15:16:05 +00:00
xavierk added the wayfinder:grilling label 2026-08-31 15:16:05 +00:00
xavierk added a new dependency 2026-08-31 15:16:07 +00:00
xavierk removed a dependency 2026-08-31 16:44:30 +00:00
Author
Owner

Slot-fill pointer from Define cross-cutting acceptance criteria: the accepted criteria at docs/spec/acceptance-criteria.md reserve SLOT-B for this decision. Fill the slot in the same commit as your resolution (same practice as ADR amendments).

Slot-fill pointer from [Define cross-cutting acceptance criteria](https://git.bongbetic.com/xavierk/Fenris/issues/13): the accepted criteria at [docs/spec/acceptance-criteria.md](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/spec/acceptance-criteria.md) reserve **SLOT-B** for this decision. Fill the slot in the same commit as your resolution (same practice as ADR amendments).
xavierk self-assigned this 2026-08-31 17:12:10 +00:00
Author
Owner

Resolved in live grilling — all recommendations accepted and confirmed.

Decision — ADR 0006: smartctl counters, sysfs identity.

  1. Pin: counters and thermal evidence solely from smartctl -a -j <device>; controller identity (subnqn, sn, mn, fr, transport) solely from sysfs. No third path anywhere in the codebase.
  2. Hard pin, no fallback: any acquisition failure fails the whole run (ADR 0005 retry/freshness absorbs it); never a partial sample — a transient read failure must not push a healthy drive down the degraded-identity path.
  3. Normalization once, at write time: one function — strip trailing spaces/newlines, no case folding, empty-after-strip → blank; smartctl fields consumed as-is.
  4. vid/ssvid: PCI sysfs node when present, null otherwise; transport from the NVMe class dir. Metadata only, never key components.
  5. Prerequisites: make install verifies smartctl and fails cleanly otherwise; no Python dependency and no OS package beyond smartmontools (ADR 0004 §9 lockfile untouched).

Rejected: libnvme bindings (SWIG module not on PyPI — would couple the exact-lockfile venv to the system Python and distro packaging) and nvme CLI JSON (new OS package, untrimmed strings, subnqn from Identify rather than the kernel — the identity ladder would drop a rung on empty-NQN controllers).

Fills SLOT-B in the accepted criteria as AC-1–AC-5, in the same commit (b2ef130) as ADR 0006, per ticket #13's practice. Environment facts on record: the NVMe class sysfs dir carries model/serial/firmware_rev/subsysnqn/transport; vid/ssvid exist only at the PCI node; the dev host has libnvme's C library but no python3-libnvme.

Resolved in live grilling — all recommendations accepted and confirmed. **Decision — [ADR 0006](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0006-collector-acquisition-path.md): smartctl counters, sysfs identity.** 1. **Pin**: counters and thermal evidence solely from `smartctl -a -j <device>`; controller identity (`subnqn`, `sn`, `mn`, `fr`, `transport`) solely from sysfs. No third path anywhere in the codebase. 2. **Hard pin, no fallback**: any acquisition failure fails the whole run (ADR 0005 retry/freshness absorbs it); never a partial sample — a transient read failure must not push a healthy drive down the degraded-identity path. 3. **Normalization once, at write time**: one function — strip trailing spaces/newlines, no case folding, empty-after-strip → blank; smartctl fields consumed as-is. 4. **vid/ssvid**: PCI sysfs node when present, null otherwise; `transport` from the NVMe class dir. Metadata only, never key components. 5. **Prerequisites**: `make install` verifies `smartctl` and fails cleanly otherwise; no Python dependency and no OS package beyond smartmontools (ADR 0004 §9 lockfile untouched). Rejected: libnvme bindings (SWIG module not on PyPI — would couple the exact-lockfile venv to the system Python and distro packaging) and `nvme` CLI JSON (new OS package, untrimmed strings, `subnqn` from Identify rather than the kernel — the identity ladder would drop a rung on empty-NQN controllers). Fills SLOT-B in [the accepted criteria](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/spec/acceptance-criteria.md) as AC-1–AC-5, in the same commit (b2ef130) as ADR 0006, per ticket #13's practice. Environment facts on record: the NVMe class sysfs dir carries `model`/`serial`/`firmware_rev`/`subsysnqn`/`transport`; `vid`/`ssvid` exist only at the PCI node; the dev host has libnvme's C library but no `python3-libnvme`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: xavierk/Fenris#16