parse the config file dynamically to enable quicker tuning

This commit is contained in:
Tim Connors 2025-09-13 04:57:49 +10:00
parent b65d94a112
commit 4c3dd04eaf
3 changed files with 31 additions and 8 deletions

View file

@ -11,10 +11,10 @@ $ipmi_exhaust_sensorname="Exhaust Temp";
$default_exhaust_threshold=50; # the ambient temperature we use above $default_exhaust_threshold=50; # the ambient temperature we use above
# which we fail back to letting the drac # which we fail back to letting the drac
# control the fans # control the fans
$base_temp = 30; # no fans when below this temp $base_temp = 24; # no fans when below this temp
$desired_temp1 = 40; # aim to keep the temperature below this $desired_temp1 = 34; # aim to keep the temperature below this
$desired_temp2 = 45; # really ramp up fans above this $desired_temp2 = 42; # really ramp up fans above this
$desired_temp3 = 55; # really ramp up fans above this $desired_temp3 = 50; # really ramp up fans above this
$demand1 = 5; # prescaled (not taking into effect static_speed_low/high) demand at temp1 $demand1 = 5; # prescaled (not taking into effect static_speed_low/high) demand at temp1
$demand2 = 40; # prescaled (not taking into effect static_speed_low/high) demand at temp2 $demand2 = 40; # prescaled (not taking into effect static_speed_low/high) demand at temp2
$demand3 = 200; # prescaled (not taking into effect static_speed_low/high) demand at temp3 $demand3 = 200; # prescaled (not taking into effect static_speed_low/high) demand at temp3
@ -68,7 +68,6 @@ sub custom_temperature_calculation {
hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:13:0")); # of them, and contribute both to both fan 1 and fan 2) hddtemp("/dev/disk/by-path/pci-0000:02:00.0-scsi-0:0:13:0")); # of them, and contribute both to both fan 1 and fan 2)
if (print_stats_once()) { if (print_stats_once()) {
print "\n";
print "gpu=$gpu, raid_card=$raid_card, cpus=$left_cpu, $right_cpu\n"; print "gpu=$gpu, raid_card=$raid_card, cpus=$left_cpu, $right_cpu\n";
print "drives = $left_outside_drives, $left_middle_drives, $right_middle_drives, $right_outside_drives ; $rear_drives\n"; print "drives = $left_outside_drives, $left_middle_drives, $right_middle_drives, $right_outside_drives ; $rear_drives\n";
} }

View file

@ -81,6 +81,7 @@ sub print_usage {
exit 1; exit 1;
} }
my %included_conf_file;
sub include { sub include {
# http://www.perlmonks.org/?node_id=393426 # http://www.perlmonks.org/?node_id=393426
#package DB; # causes eval to evaluate the string in the caller's #package DB; # causes eval to evaluate the string in the caller's
@ -98,7 +99,12 @@ sub include {
$code = qq[#line 1 "$filename"\n] . $code = qq[#line 1 "$filename"\n] .
$code; $code;
# print "evaling code: $code\n"; # print "evaling code: $code\n";
eval $code; if (!defined $included_conf_file{$filename}
or $included_conf_file{$filename} ne $code) {
print "(re)Parsing file $filename\n";
eval $code;
$included_conf_file{$filename} = $code;
}
if ("$@" ne "") { if ("$@" ne "") {
die "Can't eval $filename: $@"; die "Can't eval $filename: $@";
} }
@ -172,7 +178,9 @@ sub weighted_average {
push @vp, $value; push @vp, $value;
} }
} }
return average(@vp); my $a = average(@vp);
# print "weighted average @v -> @vp -> $a\n";
return $a;
} }
# returns undef if there are no inputs, and ignores inputs that are # returns undef if there are no inputs, and ignores inputs that are
@ -463,7 +471,7 @@ while (@ARGV > 0) {
shift @ARGV; shift @ARGV;
} }
include($conf_file); include $conf_file;
$started=1; $started=1;
$SIG{TERM} = $SIG{HUP} = $SIG{INT} = \&signal_handler; $SIG{TERM} = $SIG{HUP} = $SIG{INT} = \&signal_handler;
@ -499,6 +507,10 @@ my $tempfh;
my $last_print_stats=time; my $last_print_stats=time;
while () { while () {
# Let's parse the file everytime, and detect changes, so we can
# quickly debug new curves without waiting for the restart sequence:
include $conf_file;
my $sensors_json = `timeout -k 1 20 sensors -j 2>/dev/null`; # discard errors, annoyingly, but we do need to suppress things like my $sensors_json = `timeout -k 1 20 sensors -j 2>/dev/null`; # discard errors, annoyingly, but we do need to suppress things like
# "ERROR: Can't get value of subfeature fan1_input: Can't read" # "ERROR: Can't get value of subfeature fan1_input: Can't read"

View file

@ -81,6 +81,18 @@ regexps looking for "Inlet Temp" or "Exhaust Temp" to whatever's your
version of ambient/exhaust air temperature - you might need to anchor version of ambient/exhaust air temperature - you might need to anchor
the text since it's only using grep to filter the results. the text since it's only using grep to filter the results.
The config file as is, looks for specific devices I have plugged into
my R730xd - such as "amdgpu-pci-0400". If it doesn't find them, it
will crash as it tries to dereference json structures that don't
exist. But once you've successfully gotten it to start without
crashing, because you've inspected `sensors -j` yourself and inserted
your relevant hardware into the calculations within
poweredge-fand.conf, then any further tuning can be done by modifying
the config file without having to restart (until you introduce a
syntax error in the conf file that causes the code to bail out with a
syntax error - you'll notice the effects almost immediately as the
fans fallback to their default Dell iDrac behaviour).
You might want to modify setpoints and thresholds. $demand isn't You might want to modify setpoints and thresholds. $demand isn't
actually a percentage. That code is a mess, $static_speed_high is more actually a percentage. That code is a mess, $static_speed_high is more
or less arbitrary - the initial ramps are chosen to sort of scale from or less arbitrary - the initial ramps are chosen to sort of scale from