diff --git a/plugins/other/hddtemp_smartctl b/plugins/other/hddtemp_smartctl new file mode 100755 index 00000000..55994ff7 --- /dev/null +++ b/plugins/other/hddtemp_smartctl @@ -0,0 +1,164 @@ +#!/usr/bin/perl -w +# +# Plugin to monitor harddrive temperatures through SMART. +# +# client-conf.d/-options: +# +# smartctl -- path to smartctl executable +# drives -- List drives to monitor. E.g. "env.drives hda hdc". +# type_$dev -- device type for one drive, e.g. "env.type_sda 3ware,0" +# args_$dev -- additional arguments to smartctl for one drive, +# e.g. "env.args_hda -v 194,10xCelsius" +# Use this to make the plugin use the --all or -a option +# if your disk will not return it's temperature when +# only the -A option is used. +# +# Note for users of RAID controllers (smartmontools currently only +# supports 3ware): you can specify the drives attached to your RAID +# controller(s) as raiddev_num (e.g. sda_0). Then you must specify the +# type like this: type_sda_0 3ware,0. +# +# $Log$ +# Revision 1.1.2.5 2005/03/03 10:22:25 lupe +# Add feature to specify additional arguments to smartctl +# +# Revision 1.1.2.4 2005/02/17 10:59:33 lupe +# Support more than one drive on RAID controllers. Explain how to configure +# them. +# +# Revision 1.1.2.3 2005/01/29 22:14:36 jimmyo +# Make the plugin check all rdsks. +# +# Revision 1.1.2.2 2005/01/26 09:34:37 jimmyo +# Added license note. +# +# Revision 1.1.2.1 2005/01/25 21:00:05 jimmyo +# Added plugin generic/hddtemp_smartctl, made by Lupe Christoph. Made it the default hddtemp plugin. +# +# Revision 1.1 2004/11/10 16:11:27 jimmyo +# Added new plugin linux/hddtemp_smartctl, made by Peter Gervai (SF#1032727). +# +# Revision 1.0 2004/09/22 +# New plugin: Peter Gervai +# +# +#%# family=auto +#%# capabilities=autoconf +# +# Copyright (c) 2005, Lutz Peter Christoph +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * The name and aliases of Lutz Peter Christoph ("Lupe Christoph", +# "Lutz Christoph") may not be used to endorse or promote products +# derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +use strict; + +my $smartctl = exists $ENV{smartctl} ? $ENV{smartctl} : undef; + +# If the envvar is not set, look for smartctl +# first, try $PATH +$smartctl = `which smartctl` unless $smartctl; +chomp $smartctl; +$smartctl = undef unless -x $smartctl; + +# Still not found? Check obvious places +my @dirs = qw(/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin); +until ($smartctl or @dirs == 0) { + my $dir = shift @dirs; + my $path = $dir.'/smartctl'; + $smartctl = $path if -x $path; +} + +$ENV{LANG} = 'C'; +$ENV{LC_ALL} = 'C'; +my @drives; + +# Try to get a default set of drives +if ($^O eq 'linux') { + # On Linux, we know how to enumerate ide drives. + # SCSI is not as easy + if (-d '/dev') { + opendir(IDE, '/dev'); + @drives = grep /sd[a-z]$/, readdir IDE; + closedir(IDE); + } +} elsif ($^O eq 'solaris') { + @drives = map { s@.*/@@ ; $_ } glob '/dev/rdsk/c*t*d*s2'; +} + +@drives = split ' ', $ENV{drives} if exists $ENV{drives}; + +# Sort list of drives +@drives = sort @drives; + +if (defined $ARGV[0]) { + if ($ARGV[0] eq 'autoconf') { + if ($smartctl and -x $smartctl) { + if (@drives) { + print "yes\n"; + exit 0; + } else { + print "no (no drives known)\n"; + exit 1; + } + } else { + print "no (smartctl not found)\n"; + exit 1; + } + } elsif ($ARGV[0] eq 'config') { + print "graph_title HDD temperature\n"; + print "graph_args --base 1000 -l 0\n"; + print "graph_vlabel temp in �C\n"; + print "graph_category sensors\n"; + print "graph_info This graph shows the temperature in degrees Celsius of the hard drives in the machine.\n"; + print "$_.label $_\n" foreach @drives; + exit 0; + } +} + +foreach (@drives) { + my $dev; + $dev = $_ =~ /(.*)(?:_\d+)/ ? $1 : $_; + my $cmd = $smartctl.' -A '; + $cmd .= $ENV{'args_'.$_}.' ' if exists $ENV{'args_'.$_}; + $cmd .= '-d '.$ENV{'type_'.$_}.' ' if exists $ENV{'type_'.$_}; + if ($^O eq 'solaris') { + $cmd .= "/dev/rdsk/$dev"; + } else { + $cmd .= "/dev/$dev"; + } + my $output = `$cmd`; + if ($output =~ /Current Drive Temperature:\s*(\d+)/) { + print "$_.value $1\n"; + } elsif ($output =~ /^(194 Temperature_Celsius.*)/m) { + my @F = split ' ', $1; + print "$_.value $F[9]\n"; + } +}