forgetest: image.health proves the boot-armed watchdog is active at 60 s

The hardware watchdog is armed by the bootloader and kept fed by the
kernel core; nothing in userspace opens it. Until now nothing in the
catalog read that it is running. image.health reads watchdog0's state,
timeout and bootstatus (CONFIG_WATCHDOG_SYSFS, meta-openglow) and
requires active at 60 s; bootstatus goes into the evidence, so a campaign
that follows a watchdog reset says so.

Bench: on 2026-09-02 the forced hang ended in the factory recovery after
the 60 s timeout; the register read WCR 0x771f. The sysfs view itself
arrives with the next image, so this check is proven there.
Catalog consequence: image.health is always-run.
This commit is contained in:
ScottW514
2026-09-02 18:39:17 -04:00
parent 380f67d666
commit 38cce236a0
+11
View File
@@ -107,6 +107,17 @@ def image_health(ctx):
ev[opt] = val ev[opt] = val
ctx.log("%s=%s", opt, val) ctx.log("%s=%s", opt, val)
ctx.check(val in want, "%s=%s, expected one of %s", opt, val, want) ctx.check(val in want, "%s=%s, expected one of %s", opt, val, want)
# The boot-armed hardware watchdog, as the kernel's core sees it: U-Boot
# arms WDOG1 at 60 s and the core keeps it fed (no userspace opens it).
# The sysfs view needs CONFIG_WATCHDOG_SYSFS; bootstatus carries the
# last reset's cause (32 = the watchdog's timeout).
wd = {k: (_read("/sys/class/watchdog/watchdog0/" + k) or "").strip()
for k in ("identity", "state", "timeout", "bootstatus")}
ev["watchdog"] = wd
ctx.log("watchdog0: %s", wd)
ctx.check(wd["state"] == "active", "watchdog0 is %r, expected active (armed by the bootloader, "
"fed by the kernel core)", wd["state"] or None)
ctx.check(wd["timeout"] == "60", "watchdog0 timeout %r, expected 60 s", wd["timeout"] or None)
rel = _read("/proc/sys/kernel/osrelease", "").strip() rel = _read("/proc/sys/kernel/osrelease", "").strip()
ev["kernel_release"] = rel ev["kernel_release"] = rel
mods = manifest.platform.get("kernel_modules") or [] mods = manifest.platform.get("kernel_modules") or []