Filter out temperature=255 at this stage rather than in clients who use us Allow hddtemp to output a simpler format if --no-device --numeric is requested Ignore idle disks as well in order not to bring them out of idle mode and thus reset timer
93 lines
2.7 KiB
Perl
Executable file
93 lines
2.7 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
# A replacement for the various stock versions of hddtemp that all
|
|
# seem to have big issues with different types of drives, or spin up
|
|
# drives that are in powersaving spun-down mode, etc.
|
|
|
|
# For those disks like some of my SAS drives where `smartctl
|
|
# --nocheck=standby` and `hdparm -C` actually spins up the disk,
|
|
# detect whether a disk is spun down with sdparm commands, and don't
|
|
# invoke smartctl if it is. Otherwise, some of our other disks like
|
|
# our 16TB SATA drives on Dell Perc controllers give unreliable status to `sdparm
|
|
# --command=sense`, but `smartctl --nocheck=standby` does seem to
|
|
# reliably detect their spundown state anyway, so we continue to
|
|
# supply `--nocheck=standby` to cover this case.
|
|
|
|
# Much of this stolen from /etc/munin/plugins/hddtemp_smartctl
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
$ENV{PATH}="$ENV{PATH}:/usr/sbin:/sbin";
|
|
|
|
sub usage {
|
|
print STDERR "@_\n" if @_;
|
|
print STDERR "Usage: hddtemp [-n|--numeric] [--no-device] <devices>\n";
|
|
exit 1;
|
|
}
|
|
|
|
# FIXME: consider using megaclisas-status if it's available, although
|
|
# finding the mapping might be interesting...
|
|
|
|
my $units="°C";
|
|
my $print_device=1;
|
|
while (@ARGV and $ARGV[0] =~ /^-/) {
|
|
if ($ARGV[0] eq "--numeric" or $ARGV[0] eq "-n") {
|
|
shift @ARGV;
|
|
$units="";
|
|
} elsif ($ARGV[0] eq "--no-device") {
|
|
shift @ARGV;
|
|
$print_device=0;
|
|
} else {
|
|
usage;
|
|
}
|
|
}
|
|
|
|
usage "Supply device name(s)" if (!@ARGV);
|
|
|
|
my $last_exit=0;
|
|
foreach my $drive (@ARGV) {
|
|
my $output=`/usr/local/bin/smart-intercept-spindown -A -i $drive`;
|
|
$last_exit = $?>>8;
|
|
if (!($output =~ /(Standby|Idle) condition/)) {
|
|
my $model = "";
|
|
my $temp = "";
|
|
if ($output =~ /(Model Number|Device Model):\s*(.*)/) {
|
|
$model = "$2: ";
|
|
}
|
|
|
|
if ($output =~ /Current Drive Temperature:\s*(\d+)/) {
|
|
$temp = $1;
|
|
} elsif ($output =~ /^(194 Temperature_(Celsius|Internal).*)/m) {
|
|
my @F = split /\s+/, $1;
|
|
$temp = $F[9];
|
|
} elsif ($output =~ /^(231 Temperature_Celsius.*)/m) {
|
|
my @F = split ' ', $1;
|
|
$temp = $F[9];
|
|
} elsif ($output =~ /^(190 (Airflow_Temperature_Cel|Temperature_Case).*)/m) {
|
|
my @F = split ' ', $1;
|
|
$temp = $F[9];
|
|
} elsif ($output =~ /Temperature:\s*(\d+) Celsius/) {
|
|
$temp = $1;
|
|
} else {
|
|
print "$drive: SMART not available\n";
|
|
next;
|
|
}
|
|
|
|
# Some devices permanently return a *temperature* of 255, so
|
|
# ignore them too
|
|
if ($temp == 255) {
|
|
print "$drive: ${model}Temperature not available through SMART\n";
|
|
} else {
|
|
if ($print_device) {
|
|
print "$drive: $model$temp$units\n";
|
|
} else {
|
|
print "$temp$units\n";
|
|
}
|
|
}
|
|
} else {
|
|
print "$drive: Sleeping. Temperature not available\n";
|
|
};
|
|
}
|
|
|
|
exit $last_exit;
|