fan2go icon indicating copy to clipboard operation
fan2go copied to clipboard

drivetemp ids aren't stable

Open Maxr1998 opened this issue 1 month ago • 4 comments

Describe the bug I recently added an HBA to my system (namely the LSI 9500-8i) and set up drivetemp to make my fans react to HDD temps. Unfortunately, on nearly each reboot, the ids for controllers change.

E.g. at one boot it's drivetemp-0-* for the HBA and drivetemp-13-* for the onboard SATA, at another it is drivetemp-13-* for the HBA and drivetemp-0-* for the onboard SATA, or even drivetemp-13-* for the HBA and drivetemp-12-* for the onboard SATA.

To Reproduce

  • Set up fan2go with sensors for HDDs using the drivetemp platform
  • Reboot
  • fan2go fails to start because it cannot find the drivetemp identifiers from the configuration

Expected behavior There should be a way to set up stable drivetemp ids somehow, or an alternative way to get HDD temperatures (by disk id or similar).

Server info

  • Distro: Ubuntu Server 24.04 LTS
  • uname -a: Linux iridium 6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
  • sensors -v: sensors version 3.6.0 with libsensors version 3.6.0
  • fan2go version: 0.11.1

Additional context

  • drivetemp is set up in /etc/modules to be loaded at boot.

Maxr1998 avatar Nov 30 '25 17:11 Maxr1998

Hi @Maxr1998,

that's unfortunate. Is there another property exposed by sensors (or on the file system) for these disks that would be viable as a stable identifier?

markusressel avatar Dec 01 '25 23:12 markusressel

Hi, thanks for the reply. Unfortunately, I haven't found anything in the sensors output or drivetemp hwmon sysfs folders that would be unique. So this might need "fixes" from upstream, provided it considers this an issue.

Maybe an alternative implementation that queries drive temperatures from smart data with each drive identified by a /dev/disk/by-id/ path would work?

Maxr1998 avatar Dec 02 '25 16:12 Maxr1998

That could certainly work. Maybe you can try to come up with a proof of concept using the command sensor? If that works it might either be already good enough, or justify writing a completely new sensor source implementation (which is quite a bit of work).

markusressel avatar Dec 02 '25 18:12 markusressel

That's fair. I think there are multiple options of ascending complexity. A simple solution might be using smartctl's JSON response format + jq to get a raw temperature reading:

sudo smartctl -a --json=c /dev/disk/by-id/scsi-… | jq '.temperature.current * 1000'

A more directed approach would be using a library and only printing the temperature in the first place, I wrote a simple proof of concept for a CLI tool based on libatasmart:

Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <atasmart.h>

int main(int argc, char *argv[]) {
    SkDisk* d;
    uint64_t temperature;
    int ret;
    SkBool smart_available;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <device_path>\n", argv[0]);
        fprintf(stderr, "Example: %s /dev/sda\n", argv[0]);
        return 1;
    }

    const char* device_path = argv[1];

    if (sk_disk_open(device_path, &d) < 0) {
        fprintf(stderr, "Failed to open disk %s: %s\n", device_path, strerror(errno));
        return 1;
    }

    if (sk_disk_smart_is_available(d, &smart_available) < 0) {
        fprintf(stderr, "Failed to check if SMART is available: %s\n", strerror(errno));
        sk_disk_free(d);
        return 1;
    }

    if (!smart_available) {
        fprintf(stderr, "SMART not available.\n");
        sk_disk_free(d);
        return 0;
    }

    if (sk_disk_smart_read_data(d) < 0) {
        fprintf(stderr, "Failed to read SMART data: %s\n", strerror(errno));
        sk_disk_free(d);
        return 1;
    }

    ret = sk_disk_smart_get_temperature(d, &temperature);
    if (ret == 0) {
        printf("%llu", (unsigned long long) (temperature - 273150));
    } else {
        fprintf(stderr, "Failed to get temperature: %s\n", strerror(-ret));
    }

    sk_disk_free(d);

    return 0;
}

I'm not sure if you can import C libraries into Go so easily, but there's also smart.go, that's quite a bit newer though and maybe not as robust yet.

Maxr1998 avatar Dec 02 '25 22:12 Maxr1998