MOON
Server: Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4
System: Linux csr818.wilogic.com 2.6.18-419.el5xen #1 SMP Fri Feb 24 22:50:37 UTC 2017 x86_64
User: digitals (531)
PHP: 5.4.45
Disabled: NONE
Upload Files
File: //scripts.20110531.215904.25158/smartcheck
#!/usr/bin/perl
# cpanel - smartcheck                             Copyright(c) 2010 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

BEGIN { unshift @INC, '/usr/local/cpanel'; }

use strict;
use warnings;
use Cpanel::iContact          ();
use Cpanel::DataStore         ();
use Cpanel::CPAN::Getopt::Param ();
use Cpanel::StringFunc::Trim  ();
use Cpanel::SafeRun::Dynamic  ();

my %smart = (
    'url'         => 'http://smartmontools.sourceforge.net/',
    'version_cmd' => '-V',
    'version_rgx' => 'smartctl version ',
    '2.1'         => {
        'smart_enabled_cmd' => '-i',
        'smart_enabled_rgx' => 'Drive supports S.M.A.R.T. and is enabled',
        'errors_only'       => '-l',
        'ok_drive_rgx'      => [qw(/sd /hd)],
    },
    '5.x' => {
        'smart_enabled_cmd' => '-i',
        'smart_enabled_rgx' => 'SMART support is: Enabled',
        'errors_only'       => '-q errorsonly -H -l selftest -l error',
        'ok_drive_rgx'      => [qw(/sd /hd)],
    },
);

my $cust_d_file = '/var/cpanel/smartcheck_custom_dash_d.yaml';
my $custom_d    = Cpanel::DataStore::fetch_ref($cust_d_file);

my $param = Cpanel::CPAN::Getopt::Param->new(
    {
        'help_coderef' => sub {
            print <<"SMARTCHECK_HELP";
$0 - check the status of your harddrive(s) with smartctl.

   --help    this screen
   --quiet   bare minimum output
   --noemail output to screen only, do not send email

If you have a harddrive that keeps getting this output:
  "Checking /dev/sda....S.M.A.R.T does not appear to be enabled for this device."
but you are certain it has SMART support enabled then smartctl was unable to guess your drive's type.

You can specify a drive's type via smartctl's -d flag.

You can tell $0 to use a specific -d flag for a given drive via a simple YAML file:
  $cust_d_file

It should be a simple key/value hash where the key is the drive and the value is the value of that drive's -d

For example to tell smartctl that /dev/sda is an ata we create this file:

  # cat $cust_d_file
  ---
  /dev/sda: ata
  #

Then the next time its run we'll see this output instead:

Checking /dev/sda....
    Adding custom '-d ata' flag for /dev/sda from $cust_d_file
Ok

While YAML files are plain text, its best to use a YAML aware tool to edit them.

2 simple command line commands to do this are:

To write the hash to the file:
  perl -MYAML::Syck=DumpFile -e 'DumpFile("$cust_d_file", {"/dev/sda"=>"ata"});'

To dump the current has to the screen:
  perl -MYAML::Syck=LoadFile -MData::Dumper -e 'print Dumper(LoadFile("$cust_d_file"));'
SMARTCHECK_HELP
            exit;
        },
    }
);

eval { require Digest::MD5::File; } or die 'Skipping smartcheck: Digest::MD5::File install still pending';

my %drive_lookup;
my $msg       = '';
my $didhowdy  = 0;
my $quiet     = $param->get_param('quiet') ? 1 : 0;
my $nomail    = $param->get_param('nomail') ? 1 : 0;
my $debug     = 0;
my $bin       = '/usr/local/cpanel/3rdparty/bin/smartctl';
my $last_sent = '/var/cpanel/last_smartcheck_msg_alert';

if ( !-l $bin ) {
    if ( -e $bin ) {
        unlink $bin or die "Could not remove old cPanel smartctl: $!";
    }
    for my $smartctl (qw(/usr/sbin/smartctl /usr/local/sbin/smartctl)) {
        if ( -e $smartctl ) {
            system 'ln', '-s', $smartctl, $bin;
            last;
        }
    }
}

my $link = readlink($bin) || 'smartctl';

exit if !-e $bin;                             # or -l or -x instead ???
exit if -e '/var/cpanel/disablesmartcheck';

my $vrs = '';
Cpanel::SafeRun::Dynamic::livesaferun(
    'prog'      => [ $bin, split( /\s+/, $smart{'version_cmd'} ) ],
    'formatter' => sub {
        my ( $line, $quit_saferun_loop_sr ) = @_;
        if ( $line =~ m/\Q$smart{'version_rgx'}\E(\d+(?:\.\d+))+/ ) {
            $vrs = $1;
            ${$quit_saferun_loop_sr} = 1;
        }
        return '';
    },
);
$smart{'BINVER'} = $vrs || '';

# default to the oldest "new" config if not parseable or available
$vrs = '5.x' if !defined $vrs || !$vrs || !exists $smart{$vrs};

# unsupported SCSI was here

my @mounts;
Cpanel::SafeRun::Dynamic::livesaferun(
    'prog'      => ['mount'],
    'formatter' => sub {
        my ( $line, $quit_saferun_loop_sr ) = @_;
        push @mounts, $line;
        return '';
    },
);

open my $fstab, '/etc/fstab' or die "Could not open /etc/fstab: $!";

for my $mount_lines ( @mounts, <$fstab> ) {
    next if $mount_lines =~ m{ (?:cdrom | floppy | noauto) }xms;
    my ($drive) = $mount_lines =~ /^(\/\S+)/;
    if ($drive) {
        $drive =~ s{\d+$}{}g;
        $drive_lookup{$drive} = 1;
    }
}

close $fstab;

for my $dsk ( sort keys %drive_lookup ) {
    next if !grep { $dsk =~ m/\Q$_\E/ } @{ $smart{$vrs}->{'ok_drive_rgx'} };

    if ( !$didhowdy ) {
        print "Using smartcheck config $vrs for smartctl($smart{'BINVER'})\n"
          if !$quiet;
        $didhowdy++;
    }

    print "Checking $dsk...." unless $quiet;
    if ( exists $custom_d->{$dsk} && $custom_d->{$dsk} =~ m{^\S+$} ) {
        print "\n\tAdding custom '-d $custom_d->{$dsk}' flag for $dsk from $cust_d_file\n";
        $smart{$vrs}->{'smart_enabled_cmd'} = "-d $custom_d->{$dsk} $smart{$vrs}->{'smart_enabled_cmd'}";
    }

    my $disk_enabled = '';
    Cpanel::SafeRun::Dynamic::livesaferun(
        'prog'      => [ $bin, split( /\s+/, $smart{$vrs}->{'smart_enabled_cmd'} ), $dsk ],
        'formatter' => sub {
            my ( $line, $quit_saferun_loop_sr ) = @_;
            $disk_enabled .= $line;
            return '';
        },
    );

    if ( $disk_enabled =~ m/\Q$smart{$vrs}->{'smart_enabled_rgx'}\E/i ) {
        my $error = '';
        Cpanel::SafeRun::Dynamic::livesaferun(
            'prog'      => [ $bin, split( /\s+/, $smart{$vrs}->{'errors_only'} ), $dsk ],
            'formatter' => sub {
                my ( $line, $quit_saferun_loop_sr ) = @_;
                $error .= $line;
                return '';
            },
        );
        $error = Cpanel::StringFunc::Trim::ws_trim($error);

        if ($error) {
            $msg .= <<"MSG_END";
                S.M.A.R.T Errors on $dsk
                From Command: $link $smart{$vrs}->{'errors_only'} $dsk
                $error
                ----END $dsk--
                
MSG_END
            print "\nErrors:\n $error\n\n" if !$quiet;
        }
        else {
            print "Ok\n" if !$quiet;
        }
    }
    else {
        print "S.M.A.R.T does not appear to be enabled for this device.\n"
          if !$quiet;
    }
}

if ( $msg && -e $last_sent ) {
    $msg = '' if Digest::MD5::File::file_md5_hex($last_sent) eq Digest::MD5::md5_hex($msg);
}

if ( $msg ne '' ) {
    if ( open my $last_fh, '>', $last_sent ) {
        print {$last_fh} $msg;
        close $last_fh;
    }
    else {
        warn "Could not open $last_sent for writing: $!";
    }

    my $subject = '[cPanel smartcheck] Possible Hard Drive Failure Soon';
    my $smsg    = <<"SMART_END";
IMPORTANT: Do not ignore this email! !!!! READ IT THOUROUGHLY !!

Your system's smartctl utility has detected some errors. 
(see the "---- smartctl report --" section below for details).
You should investigate those errors according to `man smartctl` 
and documentation at $smart{'url'} 
including their mailing list. You can disable this check by doing: 
 `touch /var/cpanel/disablesmartcheck` 
and reenable it at anytime by removing that file.
If you do find issues you should consider using smartd to 
monitor your drives instead of/along with this script.

This email was generated by the cPanel smartcheck script and is 
reporting errors from your S.M.A.R.T enabled drives with the 
given commands below. It is up to you to investigate further 
and take appropriate steps:

  !!!! Do not submit tickets or bug reports if you get this email.
    Use the avenues outlined in this email to deal with your
    system's S.M.A.R.T setup. !!

To begin your troubleshooting you may want to run
 `/scripts/smartcheck --nomail` as root via SSH.

---- smartctl report --
$msg
SMART_END

    if ( !$nomail ) {
        Cpanel::iContact::icontact(
            'application' => 'smartcheck',
            'level'       => 3,
            'subject'     => $subject,
            'message'     => $msg,
            'msgtype'     => '',
        );
    }

    if ($debug) {
        print "This was emailed unless you used --nomail:\n" . "Subject: $subject\n\n$smsg";
    }
}