diff --git a/internal/sensors/collector.go b/internal/sensors/collector.go index 57391caca7..822c8ad4a4 100644 --- a/internal/sensors/collector.go +++ b/internal/sensors/collector.go @@ -90,6 +90,17 @@ func addMissingSysfsCPU(ctx context.Context, sensorsJSON string) string { return sensorsJSON } for name, value := range fallback { + if _, exists := chips[name]; exists { + // A real lm-sensors chip can have the same name as the synthetic + // fallback. Keep its other readings rather than replacing the chip. + for suffix := 1; ; suffix++ { + alternate := fmt.Sprintf("%s-sysfs-%d", name, suffix) + if _, exists := chips[alternate]; !exists { + name = alternate + break + } + } + } chips[name] = value } merged, err := json.Marshal(chips) diff --git a/internal/sensors/collector_additional_test.go b/internal/sensors/collector_additional_test.go index 4f55322c9e..979fe22769 100644 --- a/internal/sensors/collector_additional_test.go +++ b/internal/sensors/collector_additional_test.go @@ -2,6 +2,7 @@ package sensors import ( "context" + "encoding/json" "os" "path/filepath" "strings" @@ -122,6 +123,34 @@ func TestCollectLocal_CPUChipWithoutTemperatureGainsSysfsCPU(t *testing.T) { } } +func TestCollectLocal_SysfsCPUDoesNotReplaceMatchingSensorChip(t *testing.T) { + dir := t.TempDir() + const original = `{"cpu_thermal-virtual-0":{"temp1":{"temp1_input":"bad"},"fan1":{"fan1_input":1200}}}` + writeScript(t, dir, "sensors", "#!/bin/sh\necho '"+original+"'\n") + t.Setenv("PATH", dir+":"+os.Getenv("PATH")) + thermal, _ := useTestSysfsRoots(t) + writeSysfsSensor(t, thermal, "thermal_zone0", "type", "armada_thermal", "57000") + + out, err := CollectLocal(context.Background()) + if err != nil { + t.Fatal(err) + } + parsed, err := Parse(out) + if err != nil { + t.Fatal(err) + } + if parsed.CPUPackage != 57 || parsed.Fans["cpu_thermal_fan1"] != 1200 { + t.Fatalf("sysfs CPU replaced existing chip readings: %+v", parsed) + } + var chips map[string]json.RawMessage + if err := json.Unmarshal([]byte(out), &chips); err != nil { + t.Fatal(err) + } + if _, ok := chips["cpu_thermal-virtual-0-sysfs-1"]; !ok { + t.Fatalf("expected a distinct sysfs CPU chip, got %s", out) + } +} + func TestCollectLocal_ExistingCPUPrecedesSysfs(t *testing.T) { dir := t.TempDir() const original = `{"coretemp-isa-0000":{"Package id 0":{"temp1_input":42}}}`