drivetemp ids aren't stable
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
drivetempplatform - 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/Linuxsensors -v: sensors version 3.6.0 with libsensors version 3.6.0fan2go version: 0.11.1
Additional context
drivetempis set up in/etc/modulesto be loaded at boot.
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?
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?
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).
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.