Hi, I was trying to get obsdfreqd to work (on 7.2), but it doesn't:
obsdfreqd> doas obsdfreqd -v -T 70 mode;Temperature;maximum_frequency;current_frequency;cpu usage;inertia;new frequency obsdfreqd: sysctl to get temperature: No such file or directory 1; I had apmd running with -L, and obsdfreqd seems to work without temperature limits (though my CPU was getting awfully hot...). I grabbed the source code and checked what it was doing: mib[0] = CTL_HW; mib[1] = HW_SENSORS; mib[2] = 0; mib[3] = SENSOR_TEMP; mib[4] = 0; if (sysctl(mib, 5, &sensor, &len, NULL, 0) == -1) err(1, "sysctl to get temperature"); Bingo, so something's wrong there. I know I can read the temperature with sysctl(1), so what's wrong? According to the man page, mib[2] is the device name/number, but is 0 really the CPU device? I wrote a test program to dump the sensors, and sure enough, on my machine, it is device 3... (test program and output at the end; maybe OpenBSD already had this program, but I invoke the "learning opportunity" card) There might be another issue, though it's hard to check, and I don't know exactly how OpenBSD works on most machines. I have another HP laptop, which, OK, it's running Linux, but it reports no less than 10 different temperature readings, and they are all slightly different (though within a few degrees of each other). I might check how many temperature sensors OpenBSD will actually read on that machine, but I need to find the time. The point is, grabbing the first temperature sensor on the first device that has one might not actually be THE temperature of the CPU whose frequency we're controlling. I'm not sure what the fix here would be; if it were up to me, I'd add a flag like "-S hw.sensors.cpu0.temp0" to tell it exactly which sensor I want, then have the obsdfreqd code: a) get a list of all sensordev devices (3-level mib loop) b) find the one whose xname is 'cpu0' c) parse 'temp0' and extract the '0' d) run sysctl with a 5-level mib { CTL_HW, HW_SENSORS, sensordev.num, SENSOR_TEMP, atoi(tempidx) } I could write that logic if everyone's on board. Actually, the logic to parse those sysctl(1) style strings is already in sysctl's source code, it's more a question of adding a parameter or conf file or something to obsdfreqd to actually tell it what temperature sensor to look at. Test program: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <err.h> #include <sys/time.h> #include <sys/types.h> #include <sys/sensors.h> #include <sys/sysctl.h> #include <assert.h> const char* sensor_type_names[] = { "SENSOR_TEMP", "SENSOR_FANRPM", "SENSOR_VOLTS_DC", "SENSOR_VOLTS_AC", "SENSOR_OHMS", "SENSOR_WATTS", "SENSOR_AMPS", "SENSOR_WATTHOUR", "SENSOR_AMPHOUR", "SENSOR_INDICATOR", "SENSOR_INTEGER", "SENSOR_PERCENT", "SENSOR_LUX", "SENSOR_DRIVE", "SENSOR_TIMEDELTA", "SENSOR_HUMIDITY", "SENSOR_FREQ", "SENSOR_ANGLE", "SENSOR_DISTANCE", "SENSOR_PRESSURE", "SENSOR_ACCEL", "SENSOR_VELOCITY", "SENSOR_ENERGY", }; int main(int argc, char* argv[]) { int mib[5]; size_t len = 0; struct sensordev *sensordevs = NULL; size_t sensorlen = sizeof(struct sensor); memset(mib, 0, sizeof(mib)); mib[0] = CTL_HW; mib[1] = HW_SENSORS; for(int dev = 0; ; ++dev) { mib[2] = dev; if(-1 == sysctl(mib, 3, NULL, &len, NULL, 0)) { warn("Failed to get sensor count for dev %d, end of array, exiting", dev); break; } // sysctl get num sensordevs assert((len % sizeof(struct sensordev)) == 0); size_t nsensordevs = len / sizeof(struct sensordev); printf("Device %d, %zd sensordevs\n", dev, nsensordevs); sensordevs = malloc(len); memset(sensordevs, 0, len); if(-1 == sysctl(mib, 3, sensordevs, &len, NULL, 0)) { warn("Failed to retrieve sensors for device %d", dev); continue; } // sysctl get sensordevs for(int sd = 0; sd < nsensordevs; ++sd) { char xname[17]; memset(xname, 0, sizeof(xname)); strncpy(xname, sensordevs[sd].xname, 16); printf( "num: %d\n" "xname: %s\n" "sensors_count: %d\n", sensordevs[sd].num, xname, sensordevs[sd].sensors_count); for(int st = 0; st < SENSOR_MAX_TYPES; ++st) { if(sensordevs[sd].maxnumt[st] == 0) continue; for(int s = 0; s < sensordevs[sd].maxnumt[st]; ++s) { struct sensor sensor; memset(&sensor, 0, sizeof(struct sensor)); mib[2] = sensordevs[sd].num; mib[3] = st; mib[4] = s; if(-1 == sysctl(mib, 5, &sensor, &sensorlen, NULL, 0)) { warn("Failed to get sensors of type %d for sd %d for dev %d", st, sd, dev); continue; } char desc[33]; memset(desc, 0, sizeof(desc)); strncpy(desc, sensor.desc, 32); printf("\n"); printf( "\tName: %s\n" "\tValue: %llx\n" "\tType: %d (%s)\n" "\tnumt: %d\n", desc, sensor.value, sensor.type, sensor_type_names[sensor.type], sensor.numt); } // for each sensor } // for each sensor type } // for each sensordev free(sensordevs); } // for each dev return 0; } Compile with `cc -o sensors -g -O0 sensors.c` or whatever you usually do. Output on my Toshiba NB250-101 running OpenBSD 7.2: Device 0, 1 sensordevs num: 0 xname: acpiac0 sensors_count: 1 Name: power supply Value: 1 Type: 9 (SENSOR_INDICATOR) numt: 0 Device 1, 1 sensordevs num: 1 xname: acpibat0 sensors_count: 9 Name: voltage Value: a4cb80 Type: 2 (SENSOR_VOLTS_DC) numt: 0 Name: current voltage Value: bf40f0 Type: 2 (SENSOR_VOLTS_DC) numt: 1 Name: rate Value: 3e7fc18 Type: 6 (SENSOR_AMPS) numt: 0 Name: last full capacity Value: 423d08 Type: 8 (SENSOR_AMPHOUR) numt: 0 Name: warning capacity Value: 68fb0 Type: 8 (SENSOR_AMPHOUR) numt: 1 Name: low capacity Value: 1f7e8 Type: 8 (SENSOR_AMPHOUR) numt: 2 Name: remaining capacity Value: 423d08 Type: 8 (SENSOR_AMPHOUR) numt: 3 Name: design capacity Value: 432380 Type: 8 (SENSOR_AMPHOUR) numt: 4 Name: battery full Value: 80 Type: 10 (SENSOR_INTEGER) numt: 0 Device 2, 1 sensordevs num: 2 xname: acpibtn0 sensors_count: 1 Name: lid open Value: 1 Type: 9 (SENSOR_INDICATOR) numt: 0 Device 3, 1 sensordevs num: 3 xname: cpu0 sensors_count: 1 Name: Value: 14093df0 Type: 0 (SENSOR_TEMP) numt: 0 Device 4, 1 sensordevs num: 4 xname: softraid0 sensors_count: 0 Strangely enough, the temperature sensor on this laptop seems to be nameless. Huh. Best regards, Vlad Meşco P.S., I really was not sure what the best way to get in touch with the developer was, so I posted here. I hope it reaches them <3