Read-only probes on demo-felhom: both disks (system SSD /dev/sda, USB /dev/sdb) report PASSED via the exact allowlisted 'smartctl -a -j <dev>'. Card shows Nincs adat because the agent never reads: 'local' is a dir on LVM pve-root (backing='' + smartDeviceFor has no dm/LVM branch), and the USB is surfaced via the non-enriched driveTargets.Known union path. -d sat NOT needed (bridge passes SMART through; sudoers grants only -a -j). Graded fix directions B(low-risk, USB) > A(system SSD, medium) > C(reject). STOP — no fix implemented.
8.8 KiB
SPIKE — why the v0.169.0 disk-health card shows "Nincs adat" on real hardware, 2026-07-25
Question: the new "Lemezek állapota" card (controller v0.169.x) renders Nincs adat for both
physical disks on the live demo host (demo-felhom, a real N100 — NOT virtualized). Is SMART actually
unavailable on this hardware, or does the agent fail to read SMART it could read? If the latter,
where, and what are the fix directions?
Verdict up front: SMART is fully available on both disks via the exact form the sudoers
allowlist already grants (smartctl -a -j <whole-disk>) — the system SSD and the USB HDD both report
PASSED. The card says "Nincs adat" because the agent never asks, for two independent reasons:
local(the system SSD) → UNKNOWN: its storage is adironpve-root, an LVM logical volume onsda3. The agent leavesbacking_deviceempty for it, and even if it didn't,smartDeviceForhas no device-mapper/LVM handling — so the dir → LV → PV → whole-disk (/dev/sda) chain is never resolved andenrichskips the SMART read.- The USB HDD (
/dev/sdb) → ABSENT: it is surfaced only via thedriveTargets.Knownunion path inhandleDisks, which setsbacking_device=/dev/sdbbut never callsenrich(no SMART read at all) → the target'sSmart.Healthstays""→ the controller (correctly) omits it → "Nincs adat".
Neither disk needs smartctl -d sat — the USB-SATA bridge passes SMART through with plain
-a -j. The -d sat candidate is disproven on this hardware, and the sudoers allowlist does not
grant it anyway (recorded below). This is findings-only — no fix implemented; the fix gets its own spec.
Topology (Probe 1 — lsblk -o NAME,TYPE,TRAN,MOUNTPOINT,MODEL)
NAME TYPE TRAN MOUNTPOINT MODEL
sda disk sata AirDisk 512GB SSD
|-sda1 part
|-sda2 part /boot/efi
`-sda3 part (LVM PV)
|-pve-swap lvm [SWAP]
|-pve-root lvm / ← the "local" dir storage
`-pve-data-tpool … lvm ← pve-data thin pool (VM disks 9201)
sdb disk usb /mnt/hdd_1 TOSHIBA MQ04ABF100 ← the USB data drive
The customer's OS and every VM disk live on sda (SATA SSD, via LVM). The data drive is
sdb (USB). Both are real, SMART-capable disks.
The /disks payload (Probe 2 — controller-side curl to the agent localapi)
local-lvm | type=lvmthin | backing='' | mount='' | smart=UNKNOWN
local | type=local | backing='' | mount='' | smart=UNKNOWN
felhom-pbs | type=pbs | backing='' | mount='' | smart=UNKNOWN
47a3361a-… | type=usb | backing='/dev/sdb' | mount='/mnt/hdd_1' | smart=ABSENT
(The controller v0.169.1 already excludes pbs/lvmthin from the card, so only local and the USB
render — both "Nincs adat".)
Backing-path resolution (Probe 3 — readlink -f)
readlink -f /dev/sdb → /dev/sdb (already a clean whole-disk path; NOT a symlink)
readlink -f /dev/sda → /dev/sda
/dev/disk/by-uuid/47a3361a-… → ../../sdb (the durable_id's symlink; the payload already carries the resolved /dev/sdb)
→ The "USB backing is a by-uuid symlink the regex can't match" hypothesis does NOT apply here —
the payload's backing_device is already the resolved /dev/sdb.
SMART actually works on both (Probe 4 — the EXACT allowlisted form)
# smartctl -a -j /dev/sda (system SSD)
model: AirDisk 512GB SSD
smart_status.passed: True
messages: []
# smartctl -a -j /dev/sdb (USB TOSHIBA, behind its USB-SATA bridge)
model: TOSHIBA MQ04ABF100
smart_status.passed: True
messages: ['Warning: This result is based on an Attribute check.']
Both return PASSED with the plain -a -j form — no -d sat needed. (The USB result is
attribute-based, which is normal for a HDD behind a bridge; still a valid PASSED verdict.)
Sudoers / capability-manifest (Part 5.4 recording)
capability/manifest.go:94probes with{"/usr/sbin/smartctl", ["-a","-j","/dev/sda"]}./etc/sudoers.d/felhom-agentgrants only the-a -jform:→/usr/sbin/smartctl -a -j /dev/sd[a-z]*, /usr/sbin/smartctl -a -j /dev/nvme[0-9]*n[0-9]*, /usr/sbin/smartctl -a -j /dev/vd[a-z]*, /usr/sbin/smartctl -a -j /dev/hd[a-z]*,/dev/sdaand/dev/sdbare both permitted (the agent CAN read both today).-d satis NOT granted — a-d satinvocation would be denied by sudoers, so any-d satfix needs a sudoers and manifest widening.
Per-disk table — why the card says what it says
| storage | backing (payload) | whole disk | smartctl -a -j |
agent read path | card | root cause |
|---|---|---|---|---|---|---|
local (dir/pve-root) |
'' |
sda (via /→pve-root→sda3, unresolved) |
PASSED | enrich: catDir but backing_device=='' → SMART skipped |
Nincs adat (UNKNOWN) | dir-on-LVM backing never resolved; smartDeviceFor has no dm/LVM branch |
USB 47a3361a |
/dev/sdb |
sdb |
PASSED | driveTargets.Known union path — enrich never called |
Nincs adat (ABSENT) | union path sets backing but runs no SMART read; smartDeviceFor('/dev/sdb') would resolve it |
felhom-pbs / local-lvm |
'' |
— (logical/network) | n/a | not catDir |
(excluded, v0.169.1) | correct — not physical disks |
smartDeviceFor (source): maps …/nvme0n1pN → …/nvme0n1 and …/sdbN → …/sdb, then
ValidateSMARTDevice. A whole disk /dev/sdb passes through unchanged and validates → it would
resolve fine if enrich were ever called on the union path. There is no branch for /dev/mapper/*
or /dev/dm-*, which is why an LVM-backed dir can never resolve.
Fix directions (graded — DO NOT IMPLEMENT; each needs its own spec)
A — Resolve dm/LVM → whole disk (reaches the SYSTEM SSD local)
Resolve the dir's mount → LV → PV → whole disk (e.g. lsblk -s -no pkname <dev>, or
/sys/block/dm-*/slaves), set backing_device accordingly, and add a dm/LVM branch to
smartDeviceFor.
- Reach: HIGH — the system SSD holds the OS and all VM data; it is the single most important disk to monitor. Also covers any other dir-on-LVM storage.
- Risk: MEDIUM — an LVM VG can span multiple PVs (a dir → N disks, not one); the resolver must handle the multi-slave/RAID case (probe each, report per-disk) rather than assume one. Must not mis-resolve stacked dm (thin pools). Needs a focused test over single-PV and multi-PV shapes.
B — Enrich the driveTargets.Known union path (reaches the USB / felhom data drives)
Run the same SMART read on handleDisks' union branch when backing_device != "".
- Reach: GOOD — the felhom-enrolled data drives (the USB here), which is exactly what a customer cares about most for a health card.
- Risk: LOW — the backing path is already a clean whole disk,
smartDeviceForalready resolves it, and sudoers already grants/dev/sd[a-z]*. Care points: the union path lives inlocalapiwhileenrich/SMARTlives instorage(reuse theo.ops.SMARTseam or a small helper, no duplication), and don't pay smartctl on every/diskscall — the controller's 60s TTL cache already blunts the storm, but consider a short agent-side memo if/disksis hit hard. Cheapest win; do this first.
C — smartctl -d sat retry (+ sudoers/manifest widening) — REJECT for now
- Reach: NONE on this hardware — the USB bridge already returns PASSED with plain
-a -j(disproven above). Would only matter for a future bridge that yields UNKNOWN with-a -j. - Risk: HIGH-relative — requires adding
smartctl -d sat -a -j /dev/sd[a-z]*(+ nvme/vd/hd) to both/etc/sudoers.d/felhom-agentandcapability/manifest.go(widening the root-command allowlist — a privilege-surface change), plus a retry loop. Keep as a documented fallback, gated on an actual UNKNOWN-with--a -jdisk appearing in the field.
D (minor) — EvalSymlinks before the partition regex
Not needed here (backing_device is already /dev/sdb), but cheap insurance for a future payload that
carries a /dev/disk/by-* symlink. Low priority, fold into A/B if convenient.
Recommended order (for the follow-up spec): B (low-risk, covers the data drive) → A (higher value, medium risk, covers the system disk) → skip C until a bridge demands it.
STOP. No agent code, sudoers, or capability-manifest change was made in this spike (read-only probes only). The fix is a separate task.