Files
mesh-catalog/modules/sensors/cmd/sensors/main.go
T
jochen 66a816c3ac
mesh/merge-gate pass: builds new: modules/sensors, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
sensors: say a stuck drive read, and be the drives' only reader
The second review of #129 found a read stuck in the kernel kept the file fresh and the module healthy,
smartd as a second reader could wake or keep awake the drives the watch spares, and a board chip's
maximum could stop a fan. Read each drive in its own goroutine from a root reader of the module's own,
mark each read in flight, and say a read past its bound or a drive not looked at for twice its cadence;
drop smartd; tell smartctl each drive's kind; take a SAS drive's standby; say a drive asleep since when.
2026-10-08 14:59:10 +02:00

46 lines
1.4 KiB
Go

// The sensors module's Go bundle (novox/hq ADR 0256): the condition of a machine's own hardware —
// temperatures with their own thresholds, fans, each drive's health, the kernel's counts of hardware
// errors — read from /sys and /proc, and changing nothing.
//
// One binary, two ways to run. With no argument it is the bundle the node's tool runner launches and
// speaks MCP to over stdio (ADR 0188, ADR 0193), as the operator account. With `watch` and `drives` it is
// one of the module's two long-running processes, run by the node-engine as root: the fan watch, and the
// drive reader (watch.go).
package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
stdio "git.novox.be/novox/mesh-sdk/go"
)
func main() {
if len(os.Args) > 1 {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, os.Interrupt)
defer stop()
switch os.Args[1] {
case "watch":
w := NewFanWatch(Here())
every(ctx, "watch", w.Look)
case "drives":
r := NewDriveReader(Here())
r.Async = true
every(ctx, "drives", r.Look)
default:
fmt.Fprintf(os.Stderr, "sensors: %q is not a way to run; with no argument it serves its tools, with watch it "+
"watches the fans, with drives it reads the drives\n", os.Args[1])
os.Exit(2)
}
return
}
// An empty name serves as the module the runtime names (MESH_SERVED_MODULE): sensors.
if err := stdio.Serve("", Tools(Here())); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}