#!/usr/bin/perl
#
# This software was created by Alteeve's Niche! Inc. and has been released
# under the terms of the GNU GPL version 2.
#
# ScanCore Scan Agent for HPE type RAID controllers using the 'hpacucli' command line tool.
#
# https://alteeve.com
#
# Exit Codes:
# 0 - Success
# 1 - hpacucli not installed
# 2 - hpacucli is installed but it is not executable.
# 3 - No HPE type controllers found.
# 4 - Controller numeric value is invalid.
# 5 - Cache module numeric value is invalid.
# 6 - Array numeric value is invalid.
# 7 - Logical drive numeric value is invalid.
# 8 - Physical drive numeric value is invalid.
# 9 - Physical drive has no serial number.
#
# 255 - The host's UUID isn't in the hosts table yet, ScanCore itself hasn't been run.
#
# TODO:
# -
#
# NOTE:
# - Health values
# - Controller - Correctable errors = 1
# - Controller - Uncorrectable errors = 5
# - Controller - Status changes = 5
# - Drive group - partially degraded = 5
# - Drive group - degraded = 10
# - Cachevault - Replacement needed = 5
# - BBU - Replacement needed = 5
# - Temperature - Critical = 2
# - Temperature - Warning = 1
# Use my modules.
use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use Math::BigInt;
no warnings 'recursion';
# Disable buffering
$| = 1;
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
$< = $>;
$( = $);
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
my $anvil = Anvil::Tools->new();
# Make sure we're running as 'root'
# $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0))
{
# Not root
print $anvil->Words->string({key => "error_0005"})."\n";
$anvil->nice_exit({exit_code => 1});
}
# Here we store data and variables for this agent.
$anvil->data->{'scan-hpacucli'} = {
health => {
old => {},
new => {},
},
# This will keep track of devices with serial numbers so that it is easy to look up
# the UUID from the serial numbers and vice versa.
controllers => {
by_serial => {},
by_uuid => {},
},
physical_drives => {
by_serial => {},
by_uuid => {},
},
# Checking the drives for errors is expensive, so it is only done every hour (or
# there abouts). Change the interval if you want to check more or less often.
diagnostics_interval => 1800,
disable => 0,
ignore_maximum_temperature => 0,
language => "en_CA",
log_level => 1,
log_language => "en_CA",
log_file => "/var/log/ScanCore.log",
log_db_transactions => 0,
thresholds => {
# This is used for unknown sensors and really shouldn't be used at all.
'default' => {
high_warning => 50,
high_critical => 55,
low_warning => 15,
low_critical => 10,
jump => 5,
buffer => 3,
},
drives => {
# http://storage.toshiba.com/docs/product-datasheets/mk01grrb-r.pdf
# http://toshiba.semicon-storage.com/us/product/storage-products/enterprise-ssd/px02smb-px02smfxxx.html
high_warning => 50,
high_critical => 55,
low_warning => 5,
low_critical => 0,
jump => 5,
buffer => 2,
},
# I've not found official ranges on this yet... These are best-guess values
controller_temperature => {
high_warning => 100,
high_critical => 105,
low_warning => 15,
low_critical => 10,
jump => 10,
buffer => 5,
},
# I've not found official ranges on this yet... These are best-guess values
capacitor => {
high_warning => 50,
high_critical => 55,
low_warning => 15,
low_critical => 10,
jump => 5,
buffer => 3,
},
# https://support.hpe.com/hpsc/doc/public/display?docId=c04441382
cache => {
high_warning => 50,
high_critical => 55,
low_warning => 15,
low_critical => 10,
jump => 5,
buffer => 3,
},
},
sys => {
alert_sort => 2,
controller => {},
controller_count => 0,
# When a lock is requested, this is set to the time the lock was set.
# DB->do_db_write() and DB->do_db_read() will check this and if its age is >50% of
# scancore::locking::reap_age, it will renew the lock.
lock_active => 0,
process_diagnostics => 0,
},
queries => [],
};
$anvil->Storage->read_config();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches
$anvil->data->{switches}{force} = 0;
$anvil->data->{switches}{purge} = 0;
$anvil->Get->switches;
# Handle start-up tasks
my $problem = $anvil->ScanCore->agent_startup({agent => $THIS_FILE});
if ($problem)
{
$anvil->nice_exit({exit_code => 1});
}
if ($anvil->data->{switches}{purge})
{
# This can be called when doing bulk-database purges.
my $schema_file = $anvil->data->{path}{directories}{scan_agents}."/".$THIS_FILE."/".$THIS_FILE.".sql";
$anvil->Database->purge_data({
debug => 2,
tables => $anvil->Database->get_tables_from_schema({schema_file => $schema_file}),
});
$anvil->nice_exit({exit_code => 0});
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "scan_hpacucli_message_0001"});
# This does two things; It checks to see if hpacucli is installed (exits '1' if not, exits '2' if not
# executable) and then checks to see if any controllers are found in the system (exits '3' if not).
find_hp_controllers($anvil);
# If we're still alive, start gathering data.
gather_data($anvil);
# Figure out, other than temperatures, what should be added to or removed from health.
pre_process_health($anvil);
# Look for changes.
find_changes($anvil);
# Process temperatures! This also sets health values for warning and critical temperatures so make sure we
# always call this before process_health().
process_temperatures($anvil);
# Finally, process health weights.
process_health($anvil);
# Shut down.
$anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
#############################################################################################################
# Function below #
#############################################################################################################
# This reads in the last scan data from one of the databases and compares it against the just-read data. If
# anything changed, register an alert.
sub find_changes
{
my ($anvil) = @_;
# Read in the old data. As we compare and UPDATE if needed, then we'll delete. If any are not found,
# then it must be new and will be INSERTed. Any old records left over will have vanished.
read_last_scan($anvil);
### NOTE: We will loop through each section of data we scanned, deleting records as we process them
### that existed in the DB, and then marking as removed anything left in the databased data not
### seen in this scan.
process_controllers($anvil);
# Now that controllers have been proceesed, we can process drives (and their arrays)
process_drives($anvil);
# If we processed diagnostics, update
if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics})
{
my $query = "
UPDATE
scan_hpacucli_controllers
SET
scan_hpacucli_controller_last_diagnostics = ".time.",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_controller_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
}
return(0);
}
# This reads in all health wieghts previously set, alters ones as needed, INSERTs new ones and DELETEs old
# ones.
sub process_health
{
my ($anvil) = @_;
# This will hold our updates.
$anvil->data->{'scan-hpacucli'}{queries} = [];
# Read in previous health values.
my $query = "
SELECT
health_uuid,
health_agent_name,
health_source_name,
health_source_weight
FROM
health
WHERE
health_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
AND
health_agent_name = ".$anvil->Database->quote($THIS_FILE)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $health_uuid = $row->[0];
my $health_agent_name = $row->[1];
my $health_source_name = $row->[2];
my $health_source_weight = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
health_uuid => $health_uuid,
health_agent_name => $health_agent_name,
health_source_name => $health_source_name,
health_source_weight => $health_source_weight,
}});
$anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid} = $health_uuid;
$anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{value} = $health_source_weight;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::health::old::${health_source_name}::uuid" => $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid},
"scan-hpacucli::health::old::${health_source_name}::value" => $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{value},
}});
}
# Read in the new ones
foreach my $health_source_name (sort {$a cmp $b} keys %{$anvil->data->{'scan-hpacucli'}{health}{new}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
my $health_uuid = "";
if (exists $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name})
{
$health_uuid = $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid};
}
$health_uuid = $anvil->Database->insert_or_update_health({
debug => 2,
cache => $anvil->data->{'scan-hpacucli'}{queries},
health_uuid => $health_uuid,
health_host_uuid => $anvil->Get->host_uuid,
health_agent_name => $THIS_FILE,
health_source_name => $health_source_name,
health_source_weight => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }});
if (exists $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name})
{
# Delete the new old key, regardless of whether it has changed now.
delete $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name};
}
}
# Delete any old entries that are left.
foreach my $health_source_name (sort {$a cmp $b} keys %{$anvil->data->{'scan-hpacucli'}{health}{old}})
{
# Well set the source name to 'DELETED'.
my $health_uuid = $anvil->Database->insert_or_update_health({
debug => 2,
cache => $anvil->data->{'scan-hpacucli'}{queries},
'delete' => 1,
health_uuid => $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }});
}
# Now commit the changes.
$anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__});
$anvil->data->{'scan-hpacucli'}{queries} = [];
return(0);
}
# This reads in the various temperature sensors we read from this run and will set the temperature table
# and/or set/clear warnings/critical states.
sub process_temperatures
{
my ($anvil) = @_;
### NOTE: We use 'sensor_host' to hold the serial number of the device hosting the sensor.
# First, read in all existing entries. We'll compare and UPDATE or INSERT as needed and DELETE any
# stale entries.
my $query = "
SELECT
temperature_uuid,
temperature_sensor_name,
temperature_sensor_host,
temperature_value_c,
temperature_state,
temperature_is
FROM
temperature
WHERE
temperature_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
AND
temperature_agent_name = ".$anvil->Database->quote($THIS_FILE)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
# One or more records were found.
foreach my $row (@{$results})
{
my $temperature_sensor_name = $row->[1];
my $temperature_sensor_host = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_sensor_name => $temperature_sensor_name,
temperature_sensor_host => $temperature_sensor_host,
}});
$anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_uuid} = $row->[0];
$anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_value_c} = $row->[3];
$anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_state} = $row->[4];
$anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_is} = $row->[5];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_uuid" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_uuid},
"old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_value_c" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_value_c},
"old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_state" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_state},
"old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_is" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_is},
}});
}
# Loop through the temperature from this scan.
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{new}{temperature}})
{
foreach my $serial_number (sort {$a cmp $b} keys %{$anvil->data->{new}{temperature}{$variable}})
{
my $new_temperature_value_c = $anvil->data->{new}{temperature}{$variable}{$serial_number}{temperature_value_c};
my $new_temperature_state = $anvil->data->{new}{temperature}{$variable}{$serial_number}{temperature_state};
my $new_temperature_is = $anvil->data->{new}{temperature}{$variable}{$serial_number}{temperature_is};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
variable => $variable,
serial_number => $serial_number,
new_temperature_value_c => $new_temperature_value_c,
new_temperature_state => $new_temperature_state,
new_temperature_is => $new_temperature_is,
}});
# If the state is 'warning', set a health weight of 1 and set critical to 2.
my $health_source_name = "temperature:".$serial_number;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 0;
if ($new_temperature_state eq "warning")
{
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 1;
}
elsif ($new_temperature_state eq "critical")
{
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
my $temperature_uuid = "";
if (exists $anvil->data->{old}{temperature}{$variable}{$serial_number})
{
$temperature_uuid = $anvil->data->{old}{temperature}{$variable}{$serial_number}{temperature_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_uuid => $temperature_uuid }});
delete $anvil->data->{old}{temperature}{$variable}{$serial_number};
}
$temperature_uuid = $anvil->Database->insert_or_update_temperature({
cache => $anvil->data->{'scan-hpacucli'}{queries},
debug => 2,
temperature_uuid => $temperature_uuid,
temperature_host_uuid => $anvil->Get->host_uuid,
temperature_agent_name => $THIS_FILE,
temperature_sensor_host => $serial_number,
temperature_sensor_name => $variable,
temperature_value_c => $new_temperature_value_c,
temperature_state => $new_temperature_state,
temperature_is => $new_temperature_is,
temperature_weight => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_uuid => $temperature_uuid }});
}
}
# Now, if any undeleted old entries remain, delete them from the database.
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{old}{temperature}})
{
foreach my $serial_number (sort {$a cmp $b} keys %{$anvil->data->{old}{temperature}{$variable}})
{
my $temperature_uuid = $anvil->data->{old}{temperature}{$variable}{$serial_number}{temperature_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"variable" => $variable,
"serial_number" => $serial_number,
"temperature_uuid" => $temperature_uuid,
}});
# Mark the sensor as DELETEd.
$anvil->Database->insert_or_update_temperature({
cache => $anvil->data->{'scan-hpacucli'}{queries},
debug => 2,
'delete' => 1,
temperature_uuid => $temperature_uuid,
});
}
}
# Commit the queries.
$anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__});
$anvil->data->{'scan-hpacucli'}{queries} = [];
return(0);
}
# Process drives (and their arrays and logical drives).
sub process_drives
{
my ($anvil) = @_;
# Look for new, changed or deleted controllers.
$anvil->data->{'scan-hpacucli'}{queries} = [];
# This is to collected data from every sweep.
foreach my $scan_hpacucli_controller_serial_number (sort {$a cmp $b} keys %{$anvil->data->{controller}})
{
# Controller data;
next if $scan_hpacucli_controller_serial_number eq "metadata";
my $scan_hpacucli_controller_uuid = $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number,
scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid,
}});
# Array
foreach my $scan_hpacucli_array_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_array_name => $scan_hpacucli_array_name }});
# Data, there is no temperature
my $new_scan_hpacucli_array_type = "virtual";
my $new_scan_hpacucli_array_status = "virtual";
my $new_scan_hpacucli_array_error_message = "";
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{array_type})
{
$new_scan_hpacucli_array_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{array_type};
}
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{status})
{
# Array transitions (OK -> Eject -> Plug back in)
#scan-hpacucli 3117; - Data; status: [OK]
#scan-hpacucli 3117; - Data; status: [Failed Physical Drive]
#scan-hpacucli 3148; - Data; status: [OK]
$new_scan_hpacucli_array_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{status};
}
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message})
{
$new_scan_hpacucli_array_error_message = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message};
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_array_name => $scan_hpacucli_array_name,
new_scan_hpacucli_array_type => $new_scan_hpacucli_array_type,
new_scan_hpacucli_array_status => $new_scan_hpacucli_array_status,
new_scan_hpacucli_array_error_message => $new_scan_hpacucli_array_error_message,
}});
# Does this array exist already?
my $scan_hpacucli_array_uuid = $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name} ? $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name} : "";
if (($scan_hpacucli_array_uuid) && (exists $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}))
{
# Look for changes.
my $old_scan_hpacucli_array_controller_uuid = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid};
my $old_scan_hpacucli_controller_serial_number = $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$old_scan_hpacucli_array_controller_uuid};
my $old_scan_hpacucli_array_type = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_type};
my $old_scan_hpacucli_array_status = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status};
my $old_scan_hpacucli_array_error_message = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_error_message};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_scan_hpacucli_array_controller_uuid => $old_scan_hpacucli_array_controller_uuid,
old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number,
old_scan_hpacucli_array_type => $old_scan_hpacucli_array_type,
old_scan_hpacucli_array_status => $old_scan_hpacucli_array_status,
old_scan_hpacucli_array_error_message => $old_scan_hpacucli_array_error_message,
}});
# Delete the old one so we know we've seen it.
delete $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid};
# Has anything changed? Note that we don't check the name as that is how we
# find if it exists already or not.
if (($scan_hpacucli_controller_serial_number ne $old_scan_hpacucli_controller_serial_number) or
($new_scan_hpacucli_array_type ne $old_scan_hpacucli_array_type) or
($new_scan_hpacucli_array_status ne $old_scan_hpacucli_array_status) or
($new_scan_hpacucli_array_error_message ne $old_scan_hpacucli_array_error_message))
{
### Something changed.
# If the array is not OK, clear alerts.
if ($new_scan_hpacucli_array_status ne $old_scan_hpacucli_array_status)
{
my $cleared = 0;
my $message_key = "scan_hpacucli_note_0023";
# Came back or went OK?
if ($old_scan_hpacucli_array_status eq "VANISHED")
{
$message_key = "scan_hpacucli_note_0032";
}
elsif (lc($new_scan_hpacucli_array_status) eq "ok")
{
$cleared = 1;
$message_key = "scan_hpacucli_note_0024";
}
my $variables = {
name => $scan_hpacucli_array_name,
serial_number => $scan_hpacucli_controller_serial_number,
new_status => $new_scan_hpacucli_array_status,
old_status => $old_scan_hpacucli_array_status,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => "warning",
message => $message_key,
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# Did the controller change?
if ($scan_hpacucli_controller_serial_number ne $old_scan_hpacucli_controller_serial_number)
{
# yup. This is a notice as the new controller will have
# generated a warning alert.
my $variables = {
name => $scan_hpacucli_array_name,
new_serial_number => $scan_hpacucli_controller_serial_number,
old_serial_number => $old_scan_hpacucli_controller_serial_number,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0025", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0025",
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# Has the error message changed?
if ($new_scan_hpacucli_array_error_message ne $old_scan_hpacucli_array_error_message)
{
# Default is 'changed'
my $cleared = 0;
my $message_key = "scan_hpacucli_note_0026";
if (not $new_scan_hpacucli_array_error_message)
{
# Cleared
$cleared = 0;
$message_key = "scan_hpacucli_note_0027";
}
elsif (not $old_scan_hpacucli_array_error_message)
{
# New error
$message_key = "scan_hpacucli_note_0028";
}
my $variables = {
name => $scan_hpacucli_array_name,
new_error_message => $new_scan_hpacucli_array_error_message,
old_error_message => $old_scan_hpacucli_array_error_message,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => "warning",
message => $message_key,
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# Did the controller change?
if ($new_scan_hpacucli_array_type ne $old_scan_hpacucli_array_type)
{
# yup. This is a warning because it should never change.
my $variables = {
name => $scan_hpacucli_array_name,
new_type => $new_scan_hpacucli_array_type,
old_type => $old_scan_hpacucli_array_type,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0030", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0030",
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# UPDATE
my $query = "
UPDATE
scan_hpacucli_arrays
SET
scan_hpacucli_array_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid).",
scan_hpacucli_array_type = ".$anvil->Database->quote($new_scan_hpacucli_array_type).",
scan_hpacucli_array_status = ".$anvil->Database->quote($new_scan_hpacucli_array_status).",
scan_hpacucli_array_error_message = ".$anvil->Database->quote($new_scan_hpacucli_array_error_message).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_array_uuid = ".$anvil->Database->quote($scan_hpacucli_array_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
else
{
# New.
$scan_hpacucli_array_uuid = $anvil->Get->uuid();
$anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_uuid;
$anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid} = $scan_hpacucli_controller_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::controllers::by_serial::${scan_hpacucli_controller_serial_number}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number},
"scan-hpacucli::controllers::by_uuid::${scan_hpacucli_controller_uuid}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid},
}});
print $THIS_FILE." ".__LINE__."; - New Array: [$scan_hpacucli_array_name] (UUID: [$scan_hpacucli_array_uuid]); Type: [$new_scan_hpacucli_array_type], status: [$new_scan_hpacucli_array_status], error message: [$new_scan_hpacucli_array_error_message]\n";
# Alert the user if this isn't the virtual array.
if ($scan_hpacucli_array_name ne "ZZZZ")
{
# If the array is OK, it will be a notice.
my $alert_level = "notice";
my $message_key = "scan_hpacucli_note_0021";
if (lc($new_scan_hpacucli_array_status) ne "ok")
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0022";
}
my $variables = {
name => $scan_hpacucli_array_name,
type => $new_scan_hpacucli_array_type,
status => $new_scan_hpacucli_array_status,
error => $new_scan_hpacucli_array_error_message,
};
my $log_level = $alert_level eq "warning" ? 1 : 2;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => $alert_level,
message => $message_key,
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
my $query = "
INSERT INTO
scan_hpacucli_arrays
(
scan_hpacucli_array_uuid,
scan_hpacucli_array_host_uuid,
scan_hpacucli_array_controller_uuid,
scan_hpacucli_array_name,
scan_hpacucli_array_type,
scan_hpacucli_array_status,
scan_hpacucli_array_error_message,
modified_date
) VALUES (
".$anvil->Database->quote($scan_hpacucli_array_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_hpacucli_controller_uuid).",
".$anvil->Database->quote($scan_hpacucli_array_name).",
".$anvil->Database->quote($new_scan_hpacucli_array_type).",
".$anvil->Database->quote($new_scan_hpacucli_array_status).",
".$anvil->Database->quote($new_scan_hpacucli_array_error_message).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
# Logical Drive
foreach my $scan_hpacucli_logical_drive_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}})
{
# No thermal data
my $scan_hpacucli_logical_drive_uuid = $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} ? $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} : "";
my $new_scan_hpacucli_logical_drive_caching = "";
my $new_scan_hpacucli_logical_drive_os_device_name = "";
my $new_scan_hpacucli_logical_drive_type = "";
my $new_scan_hpacucli_logical_drive_raid_level = "";
my $new_scan_hpacucli_logical_drive_size = "";
my $new_scan_hpacucli_logical_drive_strip_size = "";
my $new_scan_hpacucli_logical_drive_stripe_size = "";
my $new_scan_hpacucli_logical_drive_status = "";
# If this is the virtual array, set the sizes to 0.
if ($scan_hpacucli_logical_drive_name eq "9999")
{
$new_scan_hpacucli_logical_drive_size = 0;
$new_scan_hpacucli_logical_drive_strip_size = 0;
$new_scan_hpacucli_logical_drive_stripe_size = 0;
}
### Gather the variables.
# Caching
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{caching})
{
$new_scan_hpacucli_logical_drive_caching = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{caching};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_caching => $new_scan_hpacucli_logical_drive_caching }});
}
# Disk name (in the OS)
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{disk_name})
{
$new_scan_hpacucli_logical_drive_os_device_name = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{disk_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_os_device_name => $new_scan_hpacucli_logical_drive_os_device_name }});
}
# Drive type
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{drive_type})
{
$new_scan_hpacucli_logical_drive_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{drive_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_type => $new_scan_hpacucli_logical_drive_type }});
}
# RAID level
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{fault_tolerance})
{
$new_scan_hpacucli_logical_drive_raid_level = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{fault_tolerance};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_raid_level => $new_scan_hpacucli_logical_drive_raid_level }});
}
# Drive size - Needs to be converted to bytes at initial processing.
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{size})
{
$new_scan_hpacucli_logical_drive_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{size};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new_scan_hpacucli_logical_drive_size" => $new_scan_hpacucli_logical_drive_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_size}).")",
}});
}
# Strip size
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{strip_size})
{
$new_scan_hpacucli_logical_drive_strip_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{strip_size};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new_scan_hpacucli_logical_drive_strip_size" => $new_scan_hpacucli_logical_drive_strip_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_strip_size}).")",
}});
}
# Stripe size
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{full_stripe_size})
{
$new_scan_hpacucli_logical_drive_stripe_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{full_stripe_size};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new_scan_hpacucli_logical_drive_stripe_size" => $new_scan_hpacucli_logical_drive_stripe_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_stripe_size}).")",
}});
}
# Status
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{status})
{
$new_scan_hpacucli_logical_drive_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{status};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_status => $new_scan_hpacucli_logical_drive_status }});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_scan_hpacucli_logical_drive_caching => $new_scan_hpacucli_logical_drive_caching,
new_scan_hpacucli_logical_drive_os_device_name => $new_scan_hpacucli_logical_drive_os_device_name,
new_scan_hpacucli_logical_drive_type => $new_scan_hpacucli_logical_drive_type,
new_scan_hpacucli_logical_drive_raid_level => $new_scan_hpacucli_logical_drive_raid_level,
new_scan_hpacucli_logical_drive_size => $new_scan_hpacucli_logical_drive_size,
new_scan_hpacucli_logical_drive_strip_size => $new_scan_hpacucli_logical_drive_strip_size,
new_scan_hpacucli_logical_drive_stripe_size => $new_scan_hpacucli_logical_drive_stripe_size,
new_scan_hpacucli_logical_drive_status => $new_scan_hpacucli_logical_drive_status,
}});
if (($scan_hpacucli_logical_drive_uuid) && (exists $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}))
{
my $old_scan_hpacucli_logical_drive_array_uuid = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid};
my $old_scan_hpacucli_logical_drive_name = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name};
my $old_scan_hpacucli_logical_drive_caching = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_caching};
my $old_scan_hpacucli_logical_drive_os_device_name = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_os_device_name};
my $old_scan_hpacucli_logical_drive_type = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_type};
my $old_scan_hpacucli_logical_drive_raid_level = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_raid_level};
my $old_scan_hpacucli_logical_drive_size = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_size};
my $old_scan_hpacucli_logical_drive_strip_size = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_strip_size};
my $old_scan_hpacucli_logical_drive_stripe_size = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_stripe_size};
my $old_scan_hpacucli_logical_drive_status = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_logical_drive_uuid => $scan_hpacucli_logical_drive_uuid,
old_scan_hpacucli_logical_drive_array_uuid => $old_scan_hpacucli_logical_drive_array_uuid,
old_scan_hpacucli_logical_drive_name => $old_scan_hpacucli_logical_drive_name,
old_scan_hpacucli_logical_drive_caching => $old_scan_hpacucli_logical_drive_caching,
old_scan_hpacucli_logical_drive_os_device_name => $old_scan_hpacucli_logical_drive_os_device_name,
old_scan_hpacucli_logical_drive_type => $old_scan_hpacucli_logical_drive_type,
old_scan_hpacucli_logical_drive_raid_level => $old_scan_hpacucli_logical_drive_raid_level,
old_scan_hpacucli_logical_drive_size => $old_scan_hpacucli_logical_drive_size,
old_scan_hpacucli_logical_drive_strip_size => $old_scan_hpacucli_logical_drive_strip_size,
old_scan_hpacucli_logical_drive_stripe_size => $old_scan_hpacucli_logical_drive_stripe_size,
old_scan_hpacucli_logical_drive_status => $old_scan_hpacucli_logical_drive_status,
}});
# Delete this so we know it was processed
delete $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid};
my $update = 0;
my $recovered = "";
if ($new_scan_hpacucli_logical_drive_caching ne $old_scan_hpacucli_logical_drive_caching)
{
# Did it go enabled or disabled?
$update = 1;
my $cleared = 0;
my $message_key = "scan_hpacucli_note_0034";
if (lc($new_scan_hpacucli_logical_drive_caching) eq "enabled")
{
# We're back.
$cleared = 1;
$message_key = "scan_hpacucli_note_0035";
}
if (lc($new_scan_hpacucli_logical_drive_caching) eq "disabled")
{
# Warn the user about a possible performance hit.
$message_key = "scan_hpacucli_note_0036";
}
# Send an alert telling the user that we've found a new controller.
my $variables = {
logical_drive => $scan_hpacucli_logical_drive_name,
array => $scan_hpacucli_array_name,
serial_number => $scan_hpacucli_controller_serial_number,
new_value => $new_scan_hpacucli_logical_drive_caching,
old_value => $old_scan_hpacucli_logical_drive_caching,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => "warning",
message => $message_key,
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
elsif ($new_scan_hpacucli_logical_drive_status ne $old_scan_hpacucli_logical_drive_status)
{
# NOTE: Auto-restored a drive that was re-inserted
# Example messages; "Interim Recovery Mode"
# "Recovering, 0% complete"
# LD transitions (OK -> Eject -> Plug back in)
$update = 1;
my $cleared = 0;
my $alert_level = "warning";
my $message_key = "scan_hpacucli_note_0037";
if ($old_scan_hpacucli_logical_drive_status eq "VANISHED")
{
# It's back
$cleared = 1;
$message_key = "scan_hpacucli_note_0045";
}
elsif (lc($new_scan_hpacucli_logical_drive_status) eq "ok")
{
# Back to healthy.
$cleared = 1;
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0038";
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_logical_drive_uuid.":rebuilding_logical_drive:".$scan_hpacucli_logical_drive_name, set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
}
elsif ($new_scan_hpacucli_logical_drive_status =~ /Recovering, (.*?)% complete/i)
{
# We'll set an alert so that one alert goes out when
# the rebuild starts.
$recovered = $1;
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_logical_drive_uuid.":rebuilding_logical_drive:".$scan_hpacucli_logical_drive_name, set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
recovered => $recovered,
changed => $changed,
}});
if ($changed)
{
# Let the user know the rebuild has started.
$message_key = "scan_hpacucli_note_0039";
}
else
{
# Still under way
$alert_level = "notice";
$message_key = "scan_hpacucli_note_0040";
}
}
elsif (lc($new_scan_hpacucli_logical_drive_status) eq "interim recovery mode")
{
# Drive just failed.
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0041";
}
# Send the alert
my $variables = {
logical_drive => $scan_hpacucli_logical_drive_name,
array => $scan_hpacucli_array_name,
serial_number => $scan_hpacucli_controller_serial_number,
new_value => $new_scan_hpacucli_logical_drive_status,
old_value => $old_scan_hpacucli_logical_drive_status,
recovered => $recovered,
};
my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => $alert_level,
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
elsif (($new_scan_hpacucli_logical_drive_os_device_name ne $old_scan_hpacucli_logical_drive_os_device_name) or
($new_scan_hpacucli_logical_drive_type ne $old_scan_hpacucli_logical_drive_type) or
($new_scan_hpacucli_logical_drive_raid_level ne $old_scan_hpacucli_logical_drive_raid_level) or
($new_scan_hpacucli_logical_drive_size ne $old_scan_hpacucli_logical_drive_size) or
($new_scan_hpacucli_logical_drive_strip_size ne $old_scan_hpacucli_logical_drive_strip_size) or
($new_scan_hpacucli_logical_drive_stripe_size ne $old_scan_hpacucli_logical_drive_stripe_size))
{
# Something else changed. This should normally never happen.
$update = 1;
my $variables = {
logical_drive => $scan_hpacucli_logical_drive_name,
array => $scan_hpacucli_array_name,
serial_number => $scan_hpacucli_controller_serial_number,
new_os_drive_name => $new_scan_hpacucli_logical_drive_os_device_name,
old_os_drive_name => $old_scan_hpacucli_logical_drive_os_device_name,
new_type => $new_scan_hpacucli_logical_drive_type,
old_type => $old_scan_hpacucli_logical_drive_type,
new_raid_level => $new_scan_hpacucli_logical_drive_raid_level,
old_raid_level => $old_scan_hpacucli_logical_drive_raid_level,
new_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_size}),
old_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_logical_drive_size}),
new_strip_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_strip_size}),
old_strip_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_logical_drive_strip_size}),
new_stripe_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_stripe_size}),
old_stripe_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_logical_drive_stripe_size}),
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0042", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0042",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# If something changed, UPDATE.
if ($update)
{
# Quote the numbers.
my $quoted_scan_hpacucli_logical_drive_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_size);
my $quoted_scan_hpacucli_logical_drive_strip_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_strip_size);
my $quoted_scan_hpacucli_logical_drive_stripe_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_stripe_size);
$quoted_scan_hpacucli_logical_drive_size =~ s/^'(.*?)'$/$1/;
$quoted_scan_hpacucli_logical_drive_strip_size =~ s/^'(.*?)'$/$1/;
$quoted_scan_hpacucli_logical_drive_stripe_size =~ s/^'(.*?)'$/$1/;
# Do the update
my $query = "
UPDATE
scan_hpacucli_logical_drives
SET
scan_hpacucli_logical_drive_array_uuid = ".$anvil->Database->quote($scan_hpacucli_array_uuid).",
scan_hpacucli_logical_drive_name = ".$anvil->Database->quote($scan_hpacucli_logical_drive_name).",
scan_hpacucli_logical_drive_caching = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_caching).",
scan_hpacucli_logical_drive_os_device_name = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_os_device_name).",
scan_hpacucli_logical_drive_type = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_type).",
scan_hpacucli_logical_drive_raid_level = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_raid_level).",
scan_hpacucli_logical_drive_size = $quoted_scan_hpacucli_logical_drive_size,
scan_hpacucli_logical_drive_strip_size = $quoted_scan_hpacucli_logical_drive_strip_size,
scan_hpacucli_logical_drive_stripe_size = $quoted_scan_hpacucli_logical_drive_stripe_size,
scan_hpacucli_logical_drive_status = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_status).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_logical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
else
{
# New, INSERT.
$scan_hpacucli_logical_drive_uuid = $anvil->Get->uuid();
$anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} = $scan_hpacucli_logical_drive_uuid;
$anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid} = $scan_hpacucli_logical_drive_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::logical_drives::by_name::${scan_hpacucli_logical_drive_name}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name},
"scan-hpacucli::logical_drives::by_uuid::${scan_hpacucli_logical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid},
}});
# Send an alert telling the user that we've found a new controller.
my $variables = {
name => $scan_hpacucli_array_name,
logical_drive => $scan_hpacucli_logical_drive_name,
new_caching => $new_scan_hpacucli_logical_drive_caching,
new_os_device_name => $new_scan_hpacucli_logical_drive_os_device_name,
new_type => $new_scan_hpacucli_logical_drive_type,
new_raid_level => $new_scan_hpacucli_logical_drive_raid_level,
new_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_size}),
new_strip_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_strip_size}),
new_stripe_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_stripe_size}),
new_status => $new_scan_hpacucli_logical_drive_status,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0033", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0033",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0003", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0003",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# Quote some stuff manually
my $quoted_scan_hpacucli_logical_drive_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_size);
my $quoted_scan_hpacucli_logical_drive_strip_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_strip_size);
my $quoted_scan_hpacucli_logical_drive_stripe_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_stripe_size);
$quoted_scan_hpacucli_logical_drive_size =~ s/^'(.*?)'$/$1/;
$quoted_scan_hpacucli_logical_drive_strip_size =~ s/^'(.*?)'$/$1/;
$quoted_scan_hpacucli_logical_drive_stripe_size =~ s/^'(.*?)'$/$1/;
# Now INERT variables.
my $query = "
INSERT INTO
scan_hpacucli_logical_drives
(
scan_hpacucli_logical_drive_uuid,
scan_hpacucli_logical_drive_host_uuid,
scan_hpacucli_logical_drive_array_uuid,
scan_hpacucli_logical_drive_name,
scan_hpacucli_logical_drive_caching,
scan_hpacucli_logical_drive_os_device_name,
scan_hpacucli_logical_drive_type,
scan_hpacucli_logical_drive_raid_level,
scan_hpacucli_logical_drive_size,
scan_hpacucli_logical_drive_strip_size,
scan_hpacucli_logical_drive_stripe_size,
scan_hpacucli_logical_drive_status,
modified_date
) VALUES (
".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_hpacucli_array_uuid).",
".$anvil->Database->quote($scan_hpacucli_logical_drive_name).",
".$anvil->Database->quote($new_scan_hpacucli_logical_drive_caching).",
".$anvil->Database->quote($new_scan_hpacucli_logical_drive_os_device_name).",
".$anvil->Database->quote($new_scan_hpacucli_logical_drive_type).",
".$anvil->Database->quote($new_scan_hpacucli_logical_drive_raid_level).",
$quoted_scan_hpacucli_logical_drive_size,
$quoted_scan_hpacucli_logical_drive_strip_size,
$quoted_scan_hpacucli_logical_drive_stripe_size,
".$anvil->Database->quote($new_scan_hpacucli_logical_drive_status).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
# Process logical drive variables now. Note that there are no temperatures.
foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}})
{
# Insert the variables.
my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{$scan_hpacucli_variable_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_name => $scan_hpacucli_variable_name,
new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value,
}});
# Have we seen this variable before?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::scan_hpacucli_logical_drives::source_uuid::${scan_hpacucli_logical_drive_uuid}::detail::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid},
}});
if ($anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid})
{
# Exists. Has it changed?
my $scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid};
my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid,
old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value,
}});
# delete this so that we know it was processed.
delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name};
if ($old_scan_hpacucli_variable_value ne $new_scan_hpacucli_variable_value)
{
# Now update. Alert the user as a warning, this
# should rarely ever change.
my $variables = {
logical_drive => $scan_hpacucli_logical_drive_name,
array => $scan_hpacucli_array_name,
serial_number => $scan_hpacucli_controller_serial_number,
variable_name => $scan_hpacucli_variable_name,
old_value => $old_scan_hpacucli_variable_value ? $old_scan_hpacucli_variable_value : "--",
new_value => $new_scan_hpacucli_variable_value ? $new_scan_hpacucli_variable_value : "--",
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0066", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0066",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# UPDATE
my $query = "
UPDATE
scan_hpacucli_variables
SET
scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_variable_uuid = ".$anvil->Database->quote($scan_hpacucli_variable_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
else
{
# New. Alert the user.
my $variables = {
name => $scan_hpacucli_variable_name,
value => $new_scan_hpacucli_variable_value,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0004", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0004",
variables => $variables,
show_header => 0,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# INSERT
my $query = "
INSERT INTO
scan_hpacucli_variables
(
scan_hpacucli_variable_uuid,
scan_hpacucli_variable_host_uuid,
scan_hpacucli_variable_source_table,
scan_hpacucli_variable_source_uuid,
scan_hpacucli_variable_is_temperature,
scan_hpacucli_variable_name,
scan_hpacucli_variable_value,
modified_date
) VALUES (
".$anvil->Database->quote($anvil->Get->uuid()).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
'scan_hpacucli_logical_drives',
".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).",
FALSE,
".$anvil->Database->quote($scan_hpacucli_variable_name).",
".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
# Physical Disks.
foreach my $port (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}})
{
foreach my $box (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}})
{
foreach my $bay (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}})
{
# Throw this into a function to get out of
# indent-hell.
process_a_drive($anvil, $scan_hpacucli_controller_serial_number, $scan_hpacucli_logical_drive_uuid, $scan_hpacucli_array_name, $scan_hpacucli_logical_drive_name, $port, $box, $bay);
}
}
}
}
}
# Look for deleted arrays.
foreach my $scan_hpacucli_array_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}})
{
my $old_scan_hpacucli_array_name = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_name};
my $old_scan_hpacucli_array_controller_uuid = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid};
my $old_scan_hpacucli_controller_serial_number = $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$old_scan_hpacucli_array_controller_uuid};
my $old_scan_hpacucli_array_status = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_scan_hpacucli_array_name => $old_scan_hpacucli_array_name,
old_scan_hpacucli_array_controller_uuid => $old_scan_hpacucli_array_controller_uuid,
old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number,
old_scan_hpacucli_array_status => $old_scan_hpacucli_array_status,
}});
next if $old_scan_hpacucli_array_name eq "ZZZZ";
next if $old_scan_hpacucli_array_status eq "VANISHED";
my $variables = {
name => $old_scan_hpacucli_array_name,
serial_number => $old_scan_hpacucli_controller_serial_number,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0031", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0031",
variables => $variables,
show_header => 0,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_arrays
SET
scan_hpacucli_array_status = 'VANISHED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_array_uuid = ".$anvil->Database->quote($scan_hpacucli_array_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
# Look for deleted logical drives.
foreach my $scan_hpacucli_logical_drive_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}})
{
# Look for changes
my $old_scan_hpacucli_logical_drive_array_uuid = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid};
my $old_scan_hpacucli_logical_drive_name = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name};
my $old_scan_hpacucli_logical_drive_status = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_logical_drive_uuid => $scan_hpacucli_logical_drive_uuid,
old_scan_hpacucli_logical_drive_array_uuid => $old_scan_hpacucli_logical_drive_array_uuid,
old_scan_hpacucli_logical_drive_name => $old_scan_hpacucli_logical_drive_name,
old_scan_hpacucli_logical_drive_status => $old_scan_hpacucli_logical_drive_status,
}});
next if $old_scan_hpacucli_logical_drive_name eq "9999";
next if $old_scan_hpacucli_logical_drive_status eq "VANISHED";
my $variables = {
logical_drive => $old_scan_hpacucli_logical_drive_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0044", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0044",
variables => $variables,
show_header => 0,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_logical_drives
SET
scan_hpacucli_logical_drive_status = 'VANISHED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_logical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
# Now commit the changes.
$anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__});
$anvil->data->{'scan-hpacucli'}{queries} = [];
return(0);
}
# Process a specific drive
sub process_a_drive
{
my ($anvil, $scan_hpacucli_controller_serial_number, $scan_hpacucli_logical_drive_uuid, $scan_hpacucli_array_name, $scan_hpacucli_logical_drive_name, $port, $box, $bay) = @_;
my $scan_hpacucli_physical_drive_uuid = "";
my $scan_hpacucli_physical_drive_serial_number = "";
my $new_scan_hpacucli_physical_drive_model = "";
my $new_scan_hpacucli_physical_drive_interface = "";
my $new_scan_hpacucli_physical_drive_status = "";
my $new_scan_hpacucli_physical_drive_size = 0;
my $new_scan_hpacucli_physical_drive_type = "";
my $new_scan_hpacucli_physical_drive_rpm = 0;
my $new_scan_hpacucli_physical_drive_temperature = "";
my $new_scan_hpacucli_physical_drive_last_failure_reason = "";
my $maximum_drive_temperature = 0;
# Serial Number
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{serial_number})
{
$scan_hpacucli_physical_drive_serial_number = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{serial_number};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number }});
}
# Model
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{model})
{
$new_scan_hpacucli_physical_drive_model = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{model};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_model => $new_scan_hpacucli_physical_drive_model }});
}
# Interface
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{interface_type})
{
$new_scan_hpacucli_physical_drive_interface = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{interface_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_interface => $new_scan_hpacucli_physical_drive_interface }});
}
# Status
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{status})
{
$new_scan_hpacucli_physical_drive_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{status};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_status => $new_scan_hpacucli_physical_drive_status }});
}
# Size
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{size})
{
$new_scan_hpacucli_physical_drive_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{size};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new_scan_hpacucli_physical_drive_size" => $new_scan_hpacucli_physical_drive_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_physical_drive_size}).")",
}});
}
# Type
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{drive_type})
{
$new_scan_hpacucli_physical_drive_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{drive_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_type => $new_scan_hpacucli_physical_drive_type }});
}
# RPM (0 if SSD)
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{rotational_speed})
{
$new_scan_hpacucli_physical_drive_rpm = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{rotational_speed};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_rpm => $new_scan_hpacucli_physical_drive_rpm }});
}
# Temperature
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{current_temperature})
{
$new_scan_hpacucli_physical_drive_temperature = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{current_temperature};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_temperature => $new_scan_hpacucli_physical_drive_temperature }});
}
# Last failure reason
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{last_failure_reason})
{
$new_scan_hpacucli_physical_drive_last_failure_reason = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{last_failure_reason};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason }});
}
# Maximum temperature
if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{maximum_temperature})
{
$maximum_drive_temperature = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{maximum_temperature};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { maximum_drive_temperature => $maximum_drive_temperature }});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number,
new_scan_hpacucli_physical_drive_model => $new_scan_hpacucli_physical_drive_model,
new_scan_hpacucli_physical_drive_interface => $new_scan_hpacucli_physical_drive_interface,
new_scan_hpacucli_physical_drive_status => $new_scan_hpacucli_physical_drive_status,
new_scan_hpacucli_physical_drive_size => $new_scan_hpacucli_physical_drive_size,
new_scan_hpacucli_physical_drive_type => $new_scan_hpacucli_physical_drive_type,
new_scan_hpacucli_physical_drive_rpm => $new_scan_hpacucli_physical_drive_rpm,
new_scan_hpacucli_physical_drive_temperature => $new_scan_hpacucli_physical_drive_temperature,
new_scan_hpacucli_physical_drive_last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason,
maximum_drive_temperature => $maximum_drive_temperature,
}});
# Delete the Port, Box and Bay values so that they don't get processed as their own variables.
delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{port};
delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{box};
delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{bay};
# Die if we don't have a serial number
if (not $scan_hpacucli_physical_drive_serial_number)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0011", variables => {
serial_number => $scan_hpacucli_controller_serial_number,
array_name => $scan_hpacucli_array_name,
logical_drive_name => $scan_hpacucli_logical_drive_name,
port => $port,
box => $box,
bay => $bay,
}});
$anvil->nice_exit({exit_code => 9});
}
# Have we seen this drive before?
if ($anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number})
{
# Yup! Look for changes.
$scan_hpacucli_physical_drive_uuid = $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_physical_drive_uuid => $scan_hpacucli_physical_drive_uuid }});
# Gather the old data.
my $old_scan_hpacucli_logical_drive_uuid = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_logical_drive_uuid};
my $old_scan_hpacucli_physical_drive_model = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_model};
my $old_scan_hpacucli_physical_drive_interface = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_interface};
my $old_scan_hpacucli_physical_drive_status = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_status};
my $old_scan_hpacucli_physical_drive_size = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_size};
my $old_scan_hpacucli_physical_drive_type = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_type};
my $old_scan_hpacucli_physical_drive_rpm = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_rpm};
my $old_scan_hpacucli_physical_drive_temperature = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_temperature};
my $old_scan_hpacucli_physical_drive_last_failure_reason = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_last_failure_reason};
my $old_scan_hpacucli_physical_drive_port = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_port};
my $old_scan_hpacucli_physical_drive_box = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_box};
my $old_scan_hpacucli_physical_drive_bay = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_bay};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_scan_hpacucli_logical_drive_uuid => $old_scan_hpacucli_logical_drive_uuid,
old_scan_hpacucli_physical_drive_model => $old_scan_hpacucli_physical_drive_model,
old_scan_hpacucli_physical_drive_interface => $old_scan_hpacucli_physical_drive_interface,
old_scan_hpacucli_physical_drive_status => $old_scan_hpacucli_physical_drive_status,
old_scan_hpacucli_physical_drive_size => $old_scan_hpacucli_physical_drive_size,
old_scan_hpacucli_physical_drive_type => $old_scan_hpacucli_physical_drive_type,
old_scan_hpacucli_physical_drive_rpm => $old_scan_hpacucli_physical_drive_rpm,
old_scan_hpacucli_physical_drive_temperature => $old_scan_hpacucli_physical_drive_temperature,
old_scan_hpacucli_physical_drive_last_failure_reason => $old_scan_hpacucli_physical_drive_last_failure_reason,
old_scan_hpacucli_physical_drive_port => $old_scan_hpacucli_physical_drive_port,
old_scan_hpacucli_physical_drive_box => $old_scan_hpacucli_physical_drive_box,
old_scan_hpacucli_physical_drive_bay => $old_scan_hpacucli_physical_drive_bay,
}});
# delete this so that we know it was processed.
delete $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid};
my $update = 0;
# Did the drive move between logical drives?
if ($scan_hpacucli_logical_drive_uuid ne $old_scan_hpacucli_logical_drive_uuid)
{
$update = 1;
# We'll need to get the host, controller serial number and array name
my $query = "
SELECT
a.host_name,
b.scan_hpacucli_controller_serial_number,
c.scan_hpacucli_array_name,
d.scan_hpacucli_logical_drive_name
FROM
hosts a,
scan_hpacucli_controllers b,
scan_hpacucli_arrays c,
scan_hpacucli_logical_drives d
WHERE
a.host_uuid = b.scan_hpacucli_controller_host_uuid
AND
b.scan_hpacucli_controller_uuid = c.scan_hpacucli_array_controller_uuid
AND
c.scan_hpacucli_array_uuid = d.scan_hpacucli_logical_drive_array_uuid
AND
c.scan_hpacucli_array_uuid = ".$anvil->Database->quote($old_scan_hpacucli_logical_drive_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
my $old_host_name = $results->[0]->[0] ? $results->[0]->[0] : "--";
my $old_scan_hpacucli_controller_serial_number = $results->[0]->[1] ? $results->[0]->[1] : "--";
my $old_scan_hpacucli_array_name = $results->[0]->[2] ? $results->[0]->[2] : "--";
my $old_scan_hpacucli_logical_drive_name = $results->[0]->[3] ? $results->[0]->[3] : "--";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_host_name => $old_host_name,
old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number,
old_scan_hpacucli_array_name => $old_scan_hpacucli_array_name,
old_scan_hpacucli_logical_drive_name => $old_scan_hpacucli_logical_drive_name,
}});
# Send an alert telling the drive has moved.
my $variables = {
drive_serial_number => $scan_hpacucli_physical_drive_serial_number,
old_host_name => $old_host_name,
new_host_name => $anvil->Get->host_name,
new_controller_serial_number => $scan_hpacucli_controller_serial_number,
old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number,
new_array_name => $scan_hpacucli_array_name,
old_array_name => $scan_hpacucli_array_name,
new_logical_drive_name => $scan_hpacucli_logical_drive_name,
old_logical_drive_name => $old_scan_hpacucli_logical_drive_name
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0047", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0047",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# Has the status changed?
if ($old_scan_hpacucli_physical_drive_status ne $new_scan_hpacucli_physical_drive_status)
{
$update = 1;
# Yup. Start with an alert about it being not OK, and change if it is now OK.
my $cleared = 0;
my $message_key = "scan_hpacucli_note_0048";
# Did it return?
if ($old_scan_hpacucli_physical_drive_status eq "VANISHED")
{
# The drive is back.
$message_key = "scan_hpacucli_note_0050";
}
elsif (lc($new_scan_hpacucli_physical_drive_status) eq "ok")
{
# Drive is OK again.
$cleared = 1;
$message_key = "scan_hpacucli_note_0051";
}
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
old_status => $old_scan_hpacucli_physical_drive_status,
new_status => $new_scan_hpacucli_physical_drive_status,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => "warning",
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# Did the temperature change? Whether it did or not, we need to record the current
# temperature state.
### NOTE: HP tells us the maximum temperature each of its drives can handle. This is
### a low number, so we need to tighten up some thresholds compared to usual
### ranges.
# Set defaults
my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_critical};
my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_warning};
my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_warning};
my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_critical};
my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{jump};
my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{buffer};
my $clear_high_critical = $high_critical - $buffer;
my $clear_high_warning = $high_warning - $buffer;
my $clear_low_critical = $low_critical - $buffer;
my $clear_low_warning = $low_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
high_critical => $high_critical,
high_warning => $high_warning,
low_warning => $low_warning,
low_critical => $low_critical,
jump => $jump,
buffer => $buffer,
clear_high_critical => $clear_high_critical,
clear_high_warning => $clear_high_warning,
clear_low_critical => $clear_low_critical,
clear_low_warning => $clear_low_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
# Did we get a maximum temperature from the drive?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
maximum_drive_temperature => $maximum_drive_temperature,
"scan-hpacucli::ignore_maximum_temperature" => $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature},
}});
if (($maximum_drive_temperature) && (not $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature}))
{
$high_critical = $maximum_drive_temperature;
$high_warning = $maximum_drive_temperature - 2;
$clear_high_critical = $high_critical - $buffer;
$clear_high_warning = $high_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
high_critical => $high_critical,
high_warning => $high_warning,
clear_high_critical => $clear_high_critical,
clear_high_warning => $clear_high_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
}
# Clear alerts, if needed. The order is important as clearing a warning will replace
# clearing a critical when a sensor goes critical -> ok in one scan. Once done, we'll
# check if we've crossed into a warning or critical state. If so, those will replace
# any cleared messages.
my $cleared = 0;
my $alert_level = "info";
my $message_key = "scan_hpacucli_note_0053";
my $delta = 0;
if ($new_scan_hpacucli_physical_drive_temperature)
{
if ($new_scan_hpacucli_physical_drive_temperature < $clear_high_critical)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$cleared = 1;
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0054";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
if ($new_scan_hpacucli_physical_drive_temperature < $clear_high_warning)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
# The temperature is no longer
# warning, and it didn't just go
# critical
$cleared = 1;
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0055";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
if ($new_scan_hpacucli_physical_drive_temperature > $clear_low_critical)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$cleared = 1;
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0056";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
if ($new_scan_hpacucli_physical_drive_temperature > $clear_low_warning)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$cleared = 1;
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0057";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
# Now see if the temperature has crossed into a warning or critical state.
my $temperature_state = "ok";
my $temperature_is = "nominal";
if ($new_scan_hpacucli_physical_drive_temperature > $high_critical)
{
# Crossed the high critical threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0060";
}
$temperature_state = "critical";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_physical_drive_temperature > $high_warning)
{
# Crossed the high warning threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0061";
}
$temperature_state = "warning";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_physical_drive_temperature < $low_critical)
{
# Dropped below the low critical threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0062";
}
$temperature_state = "critical";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"temperature_state" => $temperature_state,
"temperature_is" => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_physical_drive_temperature < $low_warning)
{
# Crossed the low warning threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0063";
}
$temperature_state = "warning";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
else
{
# Did it change enough to trigger a jump alert?
if ($new_scan_hpacucli_physical_drive_temperature > $old_scan_hpacucli_physical_drive_temperature)
{
# Jumped
$delta = $new_scan_hpacucli_physical_drive_temperature - $old_scan_hpacucli_physical_drive_temperature;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }});
if ($delta >= $jump)
{
# Big jump.
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0058";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
else
{
# Dropped
$delta = $old_scan_hpacucli_physical_drive_temperature - $new_scan_hpacucli_physical_drive_temperature;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }});
if ($delta >= $jump)
{
# Big drop.
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0059";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
}
# Record this for later processing into the 'temperature' table.
my $sensor_host_key = "physical_drive:".$scan_hpacucli_physical_drive_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }});
$anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_physical_drive_temperature;
$anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state} = $temperature_state;
$anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is} = $temperature_is;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c},
"new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state},
"new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is},
}});
}
# Now, if the temperature changed, update and send an alert if appropriate.
if ($new_scan_hpacucli_physical_drive_temperature ne $old_scan_hpacucli_physical_drive_temperature)
{
# Yup. Analyze
$update = 1;
# Send an alert telling the user that we've found a variable for this drive. Note
# that we add ' C' to the temperatures so that they get translated to '°F' if desired
# by the reader.
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
old_temperature => $old_scan_hpacucli_physical_drive_temperature ? $old_scan_hpacucli_physical_drive_temperature." °C" : "--",
new_temperature => $new_scan_hpacucli_physical_drive_temperature ? $new_scan_hpacucli_physical_drive_temperature." °C" : "--",
delta => $delta." °C",
high_critical_temperature => $high_critical." °C",
high_warning_temperature => $high_warning." °C",
low_critical_temperature => $low_critical." °C",
low_warning_temperature => $low_warning." °C",
};
my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => $alert_level,
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# Anything else?
if (($old_scan_hpacucli_physical_drive_model ne $new_scan_hpacucli_physical_drive_model) or
($old_scan_hpacucli_physical_drive_interface ne $new_scan_hpacucli_physical_drive_interface) or
($old_scan_hpacucli_physical_drive_size ne $new_scan_hpacucli_physical_drive_size) or
($old_scan_hpacucli_physical_drive_rpm ne $new_scan_hpacucli_physical_drive_rpm) or
($new_scan_hpacucli_physical_drive_last_failure_reason ne $old_scan_hpacucli_physical_drive_last_failure_reason) or
($port ne $old_scan_hpacucli_physical_drive_port) or
($box ne $old_scan_hpacucli_physical_drive_box) or
($bay ne $old_scan_hpacucli_physical_drive_bay))
{
# Something else changed. These normally shouldn't change...
$update = 1;
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
old_model => $old_scan_hpacucli_physical_drive_model,
new_model => $new_scan_hpacucli_physical_drive_model,
old_interface => $old_scan_hpacucli_physical_drive_interface,
new_interface => $new_scan_hpacucli_physical_drive_interface,
old_size => $anvil->Database->quote($old_scan_hpacucli_physical_drive_size),
new_size => $anvil->Database->quote($new_scan_hpacucli_physical_drive_size),
old_rpm => $old_scan_hpacucli_physical_drive_rpm,
new_rpm => $new_scan_hpacucli_physical_drive_rpm,
old_last_failure_reason => $old_scan_hpacucli_physical_drive_last_failure_reason ? $old_scan_hpacucli_physical_drive_last_failure_reason : "--",
new_last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason ? $new_scan_hpacucli_physical_drive_last_failure_reason : "--",
old_port => $old_scan_hpacucli_physical_drive_port,
new_port => $port,
old_box => $old_scan_hpacucli_physical_drive_box,
new_box => $box,
old_bay => $old_scan_hpacucli_physical_drive_bay,
new_bay => $bay,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0052", variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => "warning",
message => "scan_hpacucli_note_0052",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
if ($update)
{
# UPDATE
my $query = "
UPDATE
scan_hpacucli_physical_drives
SET
scan_hpacucli_physical_drive_logical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).",
scan_hpacucli_physical_drive_serial_number = ".$anvil->Database->quote($scan_hpacucli_physical_drive_serial_number).",
scan_hpacucli_physical_drive_model = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_model).",
scan_hpacucli_physical_drive_interface = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_interface).",
scan_hpacucli_physical_drive_status = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_status).",
scan_hpacucli_physical_drive_size = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_size).",
scan_hpacucli_physical_drive_type = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_type).",
scan_hpacucli_physical_drive_rpm = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_rpm).",
scan_hpacucli_physical_drive_temperature = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_temperature).",
scan_hpacucli_physical_drive_last_failure_reason = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_last_failure_reason).",
scan_hpacucli_physical_drive_port = ".$anvil->Database->quote($port).",
scan_hpacucli_physical_drive_box = ".$anvil->Database->quote($box).",
scan_hpacucli_physical_drive_bay = ".$anvil->Database->quote($bay).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_physical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
else
{
# New, INSERT it.
$scan_hpacucli_physical_drive_uuid = $anvil->Get->uuid();
$anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number} = $scan_hpacucli_physical_drive_uuid;
$anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid} = $scan_hpacucli_physical_drive_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::physical_drives::by_serial::${scan_hpacucli_physical_drive_serial_number}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number},
"scan-hpacucli::physical_drives::by_uuid::${scan_hpacucli_physical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid},
}});
# Send an alert telling the user we found a new drive.
my $variables = {
controller_serial_number => $scan_hpacucli_controller_serial_number,
array_name => $scan_hpacucli_array_name,
logical_drive_name => $scan_hpacucli_logical_drive_name,
port => $port,
box => $box,
bay => $bay,
drive_serial_number => $scan_hpacucli_physical_drive_serial_number,
model => $new_scan_hpacucli_physical_drive_model,
interface => $new_scan_hpacucli_physical_drive_interface,
status => $new_scan_hpacucli_physical_drive_status,
size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_physical_drive_size}),
type => $new_scan_hpacucli_physical_drive_type,
rpm => $new_scan_hpacucli_physical_drive_rpm,
temperature => $new_scan_hpacucli_physical_drive_temperature ? $new_scan_hpacucli_physical_drive_temperature." °C" : "--",
last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason ? $new_scan_hpacucli_physical_drive_last_failure_reason : "--",
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0046", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0046",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# Check for problems with this new drive.
if (lc($new_scan_hpacucli_physical_drive_status) ne "ok")
{
# There's a problem, send an alert.
my $variables = {
controller_serial_number => $scan_hpacucli_controller_serial_number,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0064", variables => $variables});
$anvil->Alert->register({
alert_level => "warning",
message => "scan_hpacucli_note_0064",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
# Check the temperature, if we read one.
if ($new_scan_hpacucli_physical_drive_temperature =~ /^\d+/)
{
### NOTE: HP tells us the maximum temperature each of its drives can handle. This is
### a low number, so we need to tighten up some thresholds compared to usual
### ranges.
# Set defaults
my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_critical};
my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_warning};
my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_warning};
my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_critical};
my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{jump};
my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{buffer};
my $clear_high_critical = $high_critical - $buffer;
my $clear_high_warning = $high_warning - $buffer;
my $clear_low_critical = $low_critical - $buffer;
my $clear_low_warning = $low_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
high_critical => $high_critical,
high_warning => $high_warning,
low_warning => $low_warning,
low_critical => $low_critical,
jump => $jump,
buffer => $buffer,
clear_high_critical => $clear_high_critical,
clear_high_warning => $clear_high_warning,
clear_low_critical => $clear_low_critical,
clear_low_warning => $clear_low_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
# Did we get a maximum temperature from the drive?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
maximum_drive_temperature => $maximum_drive_temperature,
"scan-hpacucli::ignore_maximum_temperature" => $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature},
}});
if (($maximum_drive_temperature) && (not $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature}))
{
$high_critical = $maximum_drive_temperature;
$high_warning = $maximum_drive_temperature - 2;
$clear_high_critical = $high_critical - $buffer;
$clear_high_warning = $high_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
high_critical => $high_critical,
high_warning => $high_warning,
clear_high_critical => $clear_high_critical,
clear_high_warning => $clear_high_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
}
# See if the temperature outside of the warning or critical thresholds.
my $temperature_state = "ok";
my $temperature_is = "nominal";
my $alert_level = "warning";
my $message_key = "";
if ($new_scan_hpacucli_physical_drive_temperature > $high_critical)
{
# Crossed the high critical threshold. This should always be unset because it
# is a new variable, but check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0060";
}
$temperature_state = "critical";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_physical_drive_temperature > $high_warning)
{
# Crossed the high warning threshold. This should always be unset because it
# is a new variable, but check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0061";
}
$temperature_state = "warning";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_physical_drive_temperature < $low_critical)
{
# Dropped below the low critical threshold. This should always be unset
# because it is a new variable, but check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0062";
}
$temperature_state = "critical";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_physical_drive_temperature < $low_warning)
{
# Crossed the low warning threshold. This should always be unset because it
# is a new variable, but check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0063";
}
$temperature_state = "warning";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
# Record this for later processing into the 'temperature' table.
my $sensor_host_key = "physical_drive:".$scan_hpacucli_physical_drive_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }});
$anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_physical_drive_temperature;
$anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state} = $temperature_state;
$anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is} = $temperature_is;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c},
"new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state},
"new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is},
}});
if ($message_key)
{
# Send an alert telling the user that we've found a drive outside nominal
# temperature. Note that we add ' C' to the temperatures so that they get
# translated to '°F' if desired by the reader.
my $variables = {
serial_number => $scan_hpacucli_controller_serial_number,
temperature => $new_scan_hpacucli_physical_drive_temperature ? $new_scan_hpacucli_physical_drive_temperature." °C" : "--",
high_critical_temperature => $high_critical." °C",
high_warning_temperature => $high_warning." °C",
low_critical_temperature => $low_critical." °C",
low_warning_temperature => $low_warning." °C",
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => $alert_level,
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0003", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0003",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
}
my $query = "
INSERT INTO
scan_hpacucli_physical_drives
(
scan_hpacucli_physical_drive_uuid,
scan_hpacucli_physical_drive_host_uuid,
scan_hpacucli_physical_drive_logical_drive_uuid,
scan_hpacucli_physical_drive_serial_number,
scan_hpacucli_physical_drive_model,
scan_hpacucli_physical_drive_interface,
scan_hpacucli_physical_drive_status,
scan_hpacucli_physical_drive_size,
scan_hpacucli_physical_drive_type,
scan_hpacucli_physical_drive_rpm,
scan_hpacucli_physical_drive_temperature,
scan_hpacucli_physical_drive_last_failure_reason,
scan_hpacucli_physical_drive_port,
scan_hpacucli_physical_drive_box,
scan_hpacucli_physical_drive_bay,
modified_date
) VALUES (
".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).",
".$anvil->Database->quote($scan_hpacucli_physical_drive_serial_number).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_model).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_interface).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_status).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_size).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_type).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_rpm).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_temperature).",
".$anvil->Database->quote($new_scan_hpacucli_physical_drive_last_failure_reason).",
".$anvil->Database->quote($port).",
".$anvil->Database->quote($box).",
".$anvil->Database->quote($bay).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
# Process physical drive variables now. Note that there are no temperatures.
foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}})
{
my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{$scan_hpacucli_variable_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan_hpacucli_variable_name" => $scan_hpacucli_variable_name,
"new_scan_hpacucli_variable_value" => $new_scan_hpacucli_variable_value,
}});
# Have we seen this variable before?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::scan_hpacucli_physical_drives::source_uuid::${scan_hpacucli_physical_drive_uuid}::detail::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid},
}});
if ($anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid})
{
# Exists. Has it changed?
my $scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid};
my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid,
old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value,
}});
# delete this so that we know it was processed.
delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name};
if ($old_scan_hpacucli_variable_value ne $new_scan_hpacucli_variable_value)
{
# Now update. Alert the user as a warning, these should rarely ever change.
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
variable_name => $scan_hpacucli_variable_name,
old_value => $old_scan_hpacucli_variable_value ? $old_scan_hpacucli_variable_value : "--",
new_value => $new_scan_hpacucli_variable_value ? $new_scan_hpacucli_variable_value : "--",
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0065", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0065",
variables => $variables,
show_header => 0,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# UPDATE
my $query = "
UPDATE
scan_hpacucli_variables
SET
scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_variable_uuid = ".$anvil->Database->quote($scan_hpacucli_variable_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
else
{
# Clear the hash key that was autovivified in the previous check so that it doesn't
# cause a loop when looking for vanished values.
delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name};
# New. Alert the user.
my $variables = {
name => $scan_hpacucli_variable_name,
value => $new_scan_hpacucli_variable_value,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0004", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0004",
variables => $variables,
show_header => 0,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# INSERT
my $query = "
INSERT INTO
scan_hpacucli_variables
(
scan_hpacucli_variable_uuid,
scan_hpacucli_variable_host_uuid,
scan_hpacucli_variable_source_table,
scan_hpacucli_variable_source_uuid,
scan_hpacucli_variable_is_temperature,
scan_hpacucli_variable_name,
scan_hpacucli_variable_value,
modified_date
) VALUES (
".$anvil->Database->quote($anvil->Get->uuid()).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
'scan_hpacucli_physical_drives',
".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid).",
FALSE,
".$anvil->Database->quote($scan_hpacucli_variable_name).",
".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
# Look for vanished variables for this drive.
foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}})
{
my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value};
my $old_scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_name => $scan_hpacucli_variable_name,
old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value,
old_scan_hpacucli_variable_uuid => $old_scan_hpacucli_variable_uuid,
}});
# If the old alarm state is already 'VANISHED', ignore it.
next if $old_scan_hpacucli_variable_value eq "VANISHED";
# Still here? Alert and UPDATE.
### NOTE: For now, we're going to use warning level because cache_modules
### should never vanish unless one failed. If that is the case, the
### admin already knows, but this will let other notification targets
### know that the change has happened.
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
name => $scan_hpacucli_variable_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0067", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0067",
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_variables
SET
scan_hpacucli_variable_value = 'VANISHED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_variable_uuid = ".$anvil->Database->quote($old_scan_hpacucli_variable_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
# If this was a diagnostics run, check for error counters
if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics})
{
# These are stored in the DB as standard variables, but we use the source is
# 'scan_hpacucli_physical_drive_diagnostics' to distinguish them.
if (exists $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard})
{
# We got the data
foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}})
{
# Store this in the main hash.
my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{'diagnostics'}{$scan_hpacucli_variable_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_name => $scan_hpacucli_variable_name,
new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value,
}});
### TODO
# If the variable name has 'error' in it and the value is numeric, see if it
# is > 5 and, if so, set the health.
# Have we seen this variable before?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::scan_hpacucli_physical_drive_diagnostics::source_uuid::${scan_hpacucli_physical_drive_uuid}::diagnostics::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid},
}});
if ($anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid})
{
# Exists. Has it changed?
my $scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid};
my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid,
old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value,
}});
# Delete this so that we know it was processed.
delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name};
if ($old_scan_hpacucli_variable_value ne $new_scan_hpacucli_variable_value)
{
# Now update. Alert the user as a warning, these should rarely ever change.
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
variable_name => $scan_hpacucli_variable_name,
old_value => $old_scan_hpacucli_variable_value ? $old_scan_hpacucli_variable_value : "--",
new_value => $new_scan_hpacucli_variable_value ? $new_scan_hpacucli_variable_value : "--",
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0065", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0065",
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# UPDATE
my $query = "
UPDATE
scan_hpacucli_variables
SET
scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_variable_uuid = ".$anvil->Database->quote($scan_hpacucli_variable_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
else
{
# Clear the hash key that was autovivified in the previous check so
# that it doesn't cause a loop when looking for vanished values.
delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name};
# New. Alert the user.
my $variables = {
name => $scan_hpacucli_variable_name,
value => $new_scan_hpacucli_variable_value,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0004", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0004",
show_header => 0,
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# INSERT
my $query = "
INSERT INTO
scan_hpacucli_variables
(
scan_hpacucli_variable_uuid,
scan_hpacucli_variable_host_uuid,
scan_hpacucli_variable_source_table,
scan_hpacucli_variable_source_uuid,
scan_hpacucli_variable_is_temperature,
scan_hpacucli_variable_name,
scan_hpacucli_variable_value,
modified_date
) VALUES (
".$anvil->Database->quote($anvil->Get->uuid()).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
'scan_hpacucli_physical_drive_diagnostics',
".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid).",
FALSE,
".$anvil->Database->quote($scan_hpacucli_variable_name).",
".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
}
# Look for vanished diagnostics variables.
foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}})
{
my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value};
my $old_scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_name => $scan_hpacucli_variable_name,
old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value,
old_scan_hpacucli_variable_uuid => $old_scan_hpacucli_variable_uuid,
}});
# If the old alarm state is already 'VANISHED', ignore it.
next if $old_scan_hpacucli_variable_value eq "VANISHED";
# Still here? Alert and UPDATE.
### NOTE: For now, we're going to use warning level because cache_modules
### should never vanish unless one failed. If that is the case, the
### admin already knows, but this will let other notification targets
### know that the change has happened.
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
name => $scan_hpacucli_variable_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0068", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0068",
show_header => 1,
variables => $variables,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_variables
SET
scan_hpacucli_variable_value = 'VANISHED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_variable_uuid = ".$anvil->Database->quote($old_scan_hpacucli_variable_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
return(0);
}
# Look for added, changed or deleted controllers.
sub process_controllers
{
my ($anvil) = @_;
# Look for new, changed or deleted controllers.
$anvil->data->{'scan-hpacucli'}{queries} = [];
foreach my $scan_hpacucli_controller_serial_number (sort {$a cmp $b} keys %{$anvil->data->{controller}})
{
# Controller data;
next if $scan_hpacucli_controller_serial_number eq "metadata";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number,
"scan-hpacucli::controllers::by_serial::$scan_hpacucli_controller_serial_number" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number},
}});
# Have we seen this controller before?
my $scan_hpacucli_controller_uuid = "";
my $controller_is_new = 0;
if ($anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number})
{
# Yup!
$scan_hpacucli_controller_uuid = $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid }});
}
else
{
# No, this is a new controller. Create a new UUID for it.
$scan_hpacucli_controller_uuid = $anvil->Get->uuid();
$controller_is_new = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid,
controller_is_new => $controller_is_new,
}});
# Add the keys for looking it up by UUID or serial number.
$anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_uuid;
$anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid} = $scan_hpacucli_controller_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::controllers::by_serial::$scan_hpacucli_controller_serial_number" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number},
"scan-hpacucli::controllers::by_uuid::$scan_hpacucli_controller_uuid" => $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid},
}});
}
# These are the values for the controller and cache tables. Anything else will go in the
# variables table which will be processed after the controller.
# Controller
my $new_scan_hpacucli_controller_model = "";
my $new_scan_hpacucli_controller_status = "";
my $new_scan_hpacucli_controller_last_diagnostics = $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics} ? time : "";
my $new_scan_hpacucli_controller_cache_present = "unknown";
my $new_scan_hpacucli_controller_drive_write_cache = "";
my $new_scan_hpacucli_controller_firmware_version = "";
my $new_scan_hpacucli_controller_unsafe_writeback_cache = "";
# Cache
my $new_scan_hpacucli_cache_module_size = "";
my $new_scan_hpacucli_cache_module_serial_number = "";
my $new_scan_hpacucli_cache_module_status = "";
my $new_scan_hpacucli_cache_module_type = "";
foreach my $type ("detail", "temperature")
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }});
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}})
{
# Pick up the variables for the controller
if (($type eq "detail") && ($variable eq "model_name"))
{
# Store and delete the value
$new_scan_hpacucli_controller_model = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_model => $new_scan_hpacucli_controller_model }});
next;
}
elsif (($type eq "detail") && ($variable eq "controller_status"))
{
# Store and delete the value
$new_scan_hpacucli_controller_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$new_scan_hpacucli_controller_status = lc($new_scan_hpacucli_controller_status);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_status => $new_scan_hpacucli_controller_status }});
next;
}
elsif (($type eq "detail") && ($variable eq "cache_board_present"))
{
# Store and delete the value
$new_scan_hpacucli_controller_cache_present = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$new_scan_hpacucli_controller_cache_present = lc($new_scan_hpacucli_controller_cache_present);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_cache_present => $new_scan_hpacucli_controller_cache_present }});
next;
}
elsif (($type eq "detail") && ($variable eq "drive_write_cache"))
{
# Store and delete the value
$new_scan_hpacucli_controller_drive_write_cache = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$new_scan_hpacucli_controller_drive_write_cache = lc($new_scan_hpacucli_controller_drive_write_cache);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache }});
next;
}
elsif (($type eq "detail") && ($variable eq "firmware_version"))
{
# Store and delete the value
$new_scan_hpacucli_controller_firmware_version = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_firmware_version => $new_scan_hpacucli_controller_firmware_version }});
next;
}
elsif (($type eq "detail") && ($variable eq "no_battery_write_cache"))
{
# Store and delete the value
$new_scan_hpacucli_controller_unsafe_writeback_cache = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$new_scan_hpacucli_controller_unsafe_writeback_cache = lc($new_scan_hpacucli_controller_unsafe_writeback_cache);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache }});
next;
}
# Pick up the data for the cache.
elsif (($type eq "detail") && ($variable eq "total_cache_size"))
{
# Store and delete the value
$new_scan_hpacucli_cache_module_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_size => $new_scan_hpacucli_cache_module_size }});
next;
}
elsif (($type eq "detail") && ($variable eq "cache_serial_number"))
{
# Store and delete the value
$new_scan_hpacucli_cache_module_serial_number = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_serial_number => $new_scan_hpacucli_cache_module_serial_number }});
next;
}
elsif (($type eq "detail") && ($variable eq "cache_status"))
{
# Store and delete the value
$new_scan_hpacucli_cache_module_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$new_scan_hpacucli_cache_module_status = lc($new_scan_hpacucli_cache_module_status);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_status => $new_scan_hpacucli_cache_module_status }});
next;
}
elsif (($type eq "detail") && ($variable eq "cache_backup_power_source"))
{
# Store and delete the value
$new_scan_hpacucli_cache_module_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
$new_scan_hpacucli_cache_module_type = lc($new_scan_hpacucli_cache_module_type);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_type => $new_scan_hpacucli_cache_module_type }});
next;
}
else
{
# Just for debug
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::data::${type}::${variable}" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable},
}});
}
}
}
# Pull out the rest of the variables now. If the controller is new, all variables will be
# INSERTed. If the controller exists, each variable will be examined and new ones will be
# INSERTed, existing ones will be checked for changes and UPDATEd as needed. If the
# controller is NOT new, then variables from the old data will be deleted as we go and any
# not found in the current data set will be left over. We'll use this to determine variables
# that have vanished. They will not be deleted, but their value will be set to 'VANISHED'.
if ($controller_is_new)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number,
new_scan_hpacucli_controller_model => $new_scan_hpacucli_controller_model,
new_scan_hpacucli_controller_cache_present => $new_scan_hpacucli_controller_cache_present,
new_scan_hpacucli_controller_drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache,
new_scan_hpacucli_controller_firmware_version => $new_scan_hpacucli_controller_firmware_version,
new_scan_hpacucli_controller_unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache,
}});
# Send an alert telling the user that we've found a new controller.
my $variables = {
model => $new_scan_hpacucli_controller_model,
serial_number => $scan_hpacucli_controller_serial_number,
status => $new_scan_hpacucli_controller_status,
drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache,
firmware_version => $new_scan_hpacucli_controller_firmware_version,
unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0001", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0001",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# INSERT
my $query = "
INSERT INTO
scan_hpacucli_controllers
(
scan_hpacucli_controller_uuid,
scan_hpacucli_controller_host_uuid,
scan_hpacucli_controller_serial_number,
scan_hpacucli_controller_model,
scan_hpacucli_controller_status,
scan_hpacucli_controller_last_diagnostics,
scan_hpacucli_controller_cache_present,
scan_hpacucli_controller_drive_write_cache,
scan_hpacucli_controller_firmware_version,
scan_hpacucli_controller_unsafe_writeback_cache,
modified_date
) VALUES (
".$anvil->Database->quote($scan_hpacucli_controller_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_hpacucli_controller_serial_number).",
".$anvil->Database->quote($new_scan_hpacucli_controller_model).",
".$anvil->Database->quote($new_scan_hpacucli_controller_status).",
".$anvil->Database->quote($new_scan_hpacucli_controller_last_diagnostics).",
".$anvil->Database->quote($new_scan_hpacucli_controller_cache_present).",
".$anvil->Database->quote($new_scan_hpacucli_controller_drive_write_cache).",
".$anvil->Database->quote($new_scan_hpacucli_controller_firmware_version).",
".$anvil->Database->quote($new_scan_hpacucli_controller_unsafe_writeback_cache).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
else
{
### NOTE: The serial number and model should never change (a changed SN/controller
### should be picked up as a new controller), but we check/update just to be
### safe.
# Controller already exists, check for changes.
my $old_scan_hpacucli_controller_serial_number = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number};
my $old_scan_hpacucli_controller_model = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model};
my $old_scan_hpacucli_controller_status = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status};
my $old_scan_hpacucli_controller_last_diagnostics = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_last_diagnostics};
my $old_scan_hpacucli_controller_cache_present = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_cache_present};
my $old_scan_hpacucli_controller_drive_write_cache = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_drive_write_cache};
my $old_scan_hpacucli_controller_firmware_version = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_firmware_version};
my $old_scan_hpacucli_controller_unsafe_writeback_cache = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_unsafe_writeback_cache};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number,
old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number,
old_scan_hpacucli_controller_model => $old_scan_hpacucli_controller_model,
old_scan_hpacucli_controller_status => $old_scan_hpacucli_controller_status,
old_scan_hpacucli_controller_last_diagnostics => $old_scan_hpacucli_controller_last_diagnostics,
old_scan_hpacucli_controller_cache_present => $old_scan_hpacucli_controller_cache_present,
old_scan_hpacucli_controller_drive_write_cache => $old_scan_hpacucli_controller_drive_write_cache,
old_scan_hpacucli_controller_firmware_version => $old_scan_hpacucli_controller_firmware_version,
old_scan_hpacucli_controller_unsafe_writeback_cache => $old_scan_hpacucli_controller_unsafe_writeback_cache,
}});
# Delete this from the old cache.
delete $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid};
# NOTE: We don't check if the last diagnostics changed because it will change every
# 10 minutes or so.
if (($scan_hpacucli_controller_serial_number ne $old_scan_hpacucli_controller_serial_number) or
($new_scan_hpacucli_controller_model ne $old_scan_hpacucli_controller_model) or
($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status) or
($new_scan_hpacucli_controller_cache_present ne $old_scan_hpacucli_controller_cache_present) or
($new_scan_hpacucli_controller_drive_write_cache ne $old_scan_hpacucli_controller_drive_write_cache) or
($new_scan_hpacucli_controller_firmware_version ne $old_scan_hpacucli_controller_firmware_version) or
($new_scan_hpacucli_controller_unsafe_writeback_cache ne $old_scan_hpacucli_controller_unsafe_writeback_cache))
{
# Send a warning level alert because the most likely change is 'status'. If,
# however, the status is now 'ok', then we'll clear the alert.
my $cleared = 0;
my $message_key = "scan_hpacucli_warning_0002";
if ($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status)
{
if (($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status) && ($old_scan_hpacucli_controller_status eq "VANISHED"))
{
# Controller has returned.
$message_key = "scan_hpacucli_warning_0003";
}
if (($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status) && ($new_scan_hpacucli_controller_status =~ /ok/i))
{
# Clear the alert, the controller is OK again.
$cleared = 1;
}
}
my $variables = {
new_serial_number => $scan_hpacucli_controller_serial_number,
old_serial_number => $old_scan_hpacucli_controller_serial_number,
new_model_name => $new_scan_hpacucli_controller_model,
old_model_name => $old_scan_hpacucli_controller_model,
new_status => $new_scan_hpacucli_controller_status,
old_status => $old_scan_hpacucli_controller_status,
new_cache_present => $new_scan_hpacucli_controller_cache_present,
old_cache_present => $old_scan_hpacucli_controller_cache_present,
new_drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache,
old_drive_write_cache => $old_scan_hpacucli_controller_drive_write_cache,
new_firmware_version => $new_scan_hpacucli_controller_firmware_version,
old_firmware_version => $old_scan_hpacucli_controller_firmware_version,
new_unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache,
old_unsafe_writeback_cache => $old_scan_hpacucli_controller_unsafe_writeback_cache,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => "warning",
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_controllers
SET
scan_hpacucli_controller_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).",
scan_hpacucli_controller_serial_number = ".$anvil->Database->quote($scan_hpacucli_controller_serial_number).",
scan_hpacucli_controller_model = ".$anvil->Database->quote($new_scan_hpacucli_controller_model).",
scan_hpacucli_controller_status = ".$anvil->Database->quote($new_scan_hpacucli_controller_status).",
scan_hpacucli_controller_cache_present = ".$anvil->Database->quote($new_scan_hpacucli_controller_cache_present).",
scan_hpacucli_controller_drive_write_cache = ".$anvil->Database->quote($new_scan_hpacucli_controller_drive_write_cache).",
scan_hpacucli_controller_firmware_version = ".$anvil->Database->quote($new_scan_hpacucli_controller_firmware_version).",
scan_hpacucli_controller_unsafe_writeback_cache = ".$anvil->Database->quote($new_scan_hpacucli_controller_unsafe_writeback_cache).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
# Now, if we had a cache module on this controller, see if we knew about it already.
my $scan_hpacucli_cache_module_uuid = "";
my $cache_is_new = 0;
if ($new_scan_hpacucli_cache_module_serial_number)
{
if ($anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number})
{
# Yup!
$scan_hpacucli_cache_module_uuid = $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid }});
}
else
{
# No, this is a new cache module. Create a new UUID for it.
$scan_hpacucli_cache_module_uuid = $anvil->Get->uuid();
$cache_is_new = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid,
cache_is_new => $cache_is_new,
}});
# Add the keys for looking it up by UUID or serial number.
$anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number} = $scan_hpacucli_cache_module_uuid;
$anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid} = $new_scan_hpacucli_cache_module_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::cache_modules::by_serial::$new_scan_hpacucli_cache_module_serial_number" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number},
"scan-hpacucli::cache_modules::by_uuid::$scan_hpacucli_cache_module_uuid" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid},
}});
}
if ($cache_is_new)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid,
new_scan_hpacucli_cache_module_size => $new_scan_hpacucli_cache_module_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_cache_module_size}).")",
new_scan_hpacucli_cache_module_serial_number => $new_scan_hpacucli_cache_module_serial_number,
new_scan_hpacucli_cache_module_status => $new_scan_hpacucli_cache_module_status,
new_scan_hpacucli_cache_module_type => $new_scan_hpacucli_cache_module_type,
}});
# Send an alert telling the user that we've found a new controller.
my $variables = {
serial_number => $new_scan_hpacucli_cache_module_serial_number,
cache_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_cache_module_size}),
status => $new_scan_hpacucli_cache_module_status,
type => $new_scan_hpacucli_cache_module_type,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0002", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0002",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0003"});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "notice",
message => "scan_hpacucli_note_0003",
variables => {},
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# INSERT
my $query = "
INSERT INTO
scan_hpacucli_cache_modules
(
scan_hpacucli_cache_module_uuid,
scan_hpacucli_cache_module_host_uuid,
scan_hpacucli_cache_module_controller_uuid,
scan_hpacucli_cache_module_serial_number,
scan_hpacucli_cache_module_status,
scan_hpacucli_cache_module_type,
scan_hpacucli_cache_module_size,
modified_date
) VALUES (
".$anvil->Database->quote($scan_hpacucli_cache_module_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_hpacucli_controller_uuid).",
".$anvil->Database->quote($new_scan_hpacucli_cache_module_serial_number).",
".$anvil->Database->quote($new_scan_hpacucli_cache_module_status).",
".$anvil->Database->quote($new_scan_hpacucli_cache_module_type).",
".$anvil->Database->quote($new_scan_hpacucli_cache_module_size).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
else
{
# Exists already, look for changes. The serial number should never change,
# buuuut...
my $old_scan_hpacucli_cache_module_controller_uuid = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_controller_uuid};
my $old_scan_hpacucli_cache_module_serial_number = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number};
my $old_scan_hpacucli_cache_module_status = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status};
my $old_scan_hpacucli_cache_module_type = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_type};
my $old_scan_hpacucli_cache_module_size = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_size};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_scan_hpacucli_cache_module_controller_uuid => $old_scan_hpacucli_cache_module_controller_uuid,
old_scan_hpacucli_cache_module_serial_number => $old_scan_hpacucli_cache_module_serial_number,
old_scan_hpacucli_cache_module_status => $old_scan_hpacucli_cache_module_status,
old_scan_hpacucli_cache_module_type => $old_scan_hpacucli_cache_module_type,
old_scan_hpacucli_cache_module_size => $old_scan_hpacucli_cache_module_size,
}});
# Delete this so we know we saw it.
delete $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid};
if (($scan_hpacucli_controller_uuid ne $old_scan_hpacucli_cache_module_controller_uuid) or
($new_scan_hpacucli_cache_module_serial_number ne $old_scan_hpacucli_cache_module_serial_number) or
($new_scan_hpacucli_cache_module_status ne $old_scan_hpacucli_cache_module_status) or
($new_scan_hpacucli_cache_module_type ne $old_scan_hpacucli_cache_module_type) or
($new_scan_hpacucli_cache_module_size ne $old_scan_hpacucli_cache_module_size))
{
# Something has changed, but what? Any change is likely bad, so we
# default to 'warning'.
my $cleared = 0;
my $message_key = "scan_hpacucli_warning_0004";
# Did the status return to 'ok'?
if (($old_scan_hpacucli_cache_module_status ne $new_scan_hpacucli_cache_module_status) && ($old_scan_hpacucli_cache_module_status eq "VANISHED"))
{
# The cache module is back
$message_key = "scan_hpacucli_warning_0005";
}
elsif (($old_scan_hpacucli_cache_module_status ne $new_scan_hpacucli_cache_module_status) && ($new_scan_hpacucli_cache_module_status eq "ok"))
{
# The status is good now, clear the alert
$cleared = 1;
}
# Convert the old controller UUID to a serial number.
my $query = "SELECT scan_hpacucli_controller_serial_number FROM scan_hpacucli_controllers WHERE scan_hpacucli_controller_uuid = ".$anvil->Database->quote($old_scan_hpacucli_cache_module_controller_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $old_scan_hpacucli_controller_serial_number = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$old_scan_hpacucli_controller_serial_number = "--" if not defined $old_scan_hpacucli_controller_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number }});
# Send the alert
my $variables = {
old_serial_number => $old_scan_hpacucli_cache_module_serial_number,
new_serial_number => $new_scan_hpacucli_cache_module_serial_number,
old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number,
new_controller_serial_number => $scan_hpacucli_controller_serial_number,
old_status => $old_scan_hpacucli_cache_module_status,
new_status => $old_scan_hpacucli_cache_module_status,
old_type => $new_scan_hpacucli_cache_module_type,
new_type => $old_scan_hpacucli_cache_module_type,
say_old_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_cache_module_size}),
say_new_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_cache_module_size}),
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0002", variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => "warning",
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0003"});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0003",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# Update the database.
$query = "
UPDATE
scan_hpacucli_cache_modules
SET
scan_hpacucli_cache_module_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).",
scan_hpacucli_cache_module_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid).",
scan_hpacucli_cache_module_serial_number = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_serial_number).",
scan_hpacucli_cache_module_status = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_status).",
scan_hpacucli_cache_module_type = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_type).",
scan_hpacucli_cache_module_size = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_size).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_cache_module_uuid = ".$anvil->Database->quote($scan_hpacucli_cache_module_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
}
# We do this after the cache so that the alerts make since when a new controller is found.
foreach my $type ("detail", "temperature")
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }});
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}})
{
my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable};
my $temperature = $type eq "temperature" ? "TRUE" : "FALSE";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
variable => $variable,
new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value,
temperature => $temperature,
}});
# Now, if the variable doesn't exist, INSERT it. If it does exist, see if it
# changed and UPDATE it if so.
if (exists $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable})
{
# Look for changes
my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable}{scan_hpacucli_variable_value};
my $variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable}{scan_hpacucli_variable_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value,
old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value,
variable_uuid => $variable_uuid,
}});
# Delete it so that we know it has been processed.
delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable};
# Set defaults
my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_critical};
my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_warning};
my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_warning};
my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_critical};
my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{jump};
my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{buffer};
my $clear_high_critical = $high_critical - $buffer;
my $clear_high_warning = $high_warning - $buffer;
my $clear_low_critical = $low_critical - $buffer;
my $clear_low_warning = $low_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
high_critical => $high_critical,
high_warning => $high_warning,
low_warning => $low_warning,
low_critical => $low_critical,
jump => $jump,
buffer => $buffer,
clear_high_critical => $clear_high_critical,
clear_high_warning => $clear_high_warning,
clear_low_critical => $clear_low_critical,
clear_low_warning => $clear_low_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
# Does this variable have defined limits?
if (exists $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical})
{
$high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical};
$high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_warning};
$low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_warning};
$low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_critical};
$jump = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{jump};
$buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{buffer};
$clear_high_critical = $high_critical - $buffer;
$clear_high_warning = $high_warning - $buffer;
$clear_low_critical = $low_critical - $buffer;
$clear_low_warning = $low_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
high_critical => $high_critical,
high_warning => $high_warning,
low_warning => $low_warning,
low_critical => $low_critical,
jump => $jump,
buffer => $buffer,
clear_high_critical => $clear_high_critical,
clear_high_warning => $clear_high_warning,
clear_low_critical => $clear_low_critical,
clear_low_warning => $clear_low_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
}
# If it's a temperature, we need to analyze it and store it,
# regardless of if it changed this pass.
my $cleared = 0;
my $temperature_state = "ok";
my $temperature_is = "nominal";
my $message_key = "scan_hpacucli_note_0009";
my $alert_level = "notice";
my $delta = 0;
if ($type eq "temperature")
{
# Change the log level to info as temperatures change often.
$alert_level = "info";
# Now see if the temperature has crossed into a
# warning or critical state.
if ($new_scan_hpacucli_variable_value > $high_critical)
{
# Crossed the high critical threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0005";
}
$temperature_state = "critical";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_variable_value > $high_warning)
{
# Crossed the high warning threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0006";
}
$temperature_state = "warning";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_variable_value < $low_critical)
{
# Dropped below the low critical threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0007";
}
$temperature_state = "critical";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_variable_value < $low_warning)
{
# Crossed the low warning threshold.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0008";
}
$temperature_state = "warning";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
else
{
# Did it change enough to trigger a jump
# alert?
if ($new_scan_hpacucli_variable_value > $old_scan_hpacucli_variable_value)
{
# Jumped
$delta = $new_scan_hpacucli_variable_value - $old_scan_hpacucli_variable_value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }});
if ($delta >= $jump)
{
# Big jump.
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0015";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
else
{
# Dropped
$delta = $old_scan_hpacucli_variable_value - $new_scan_hpacucli_variable_value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }});
if ($delta >= $jump)
{
# Big drop.
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0016";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
}
# Record this for later processing into the 'temperature'
# table.
my $sensor_host_key = "controller:$scan_hpacucli_controller_serial_number";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }});
$anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_variable_value;
$anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state} = $temperature_state;
$anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is} = $temperature_is;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::temperature::${variable}::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c},
"new::temperature::${variable}::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state},
"new::temperature::${variable}::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is},
}});
}
# Did the variable change?
if ($new_scan_hpacucli_variable_value ne $old_scan_hpacucli_variable_value)
{
# How has it changed?
if ($old_scan_hpacucli_variable_value eq "VANISHED")
{
$message_key = "scan_hpacucli_note_0010";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { message_key => $message_key }});
}
elsif ($type eq "temperature")
{
# Clear alerts, if needed. The order is important as
# clearing a warning will replace clearing a critical
# when a sensor goes critical -> ok in one scan. Once
# done, we'll check if we've crossed into a warning
# or critical state. If so, those will replace any
# cleared messages.
if ($new_scan_hpacucli_variable_value < $clear_high_critical)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$cleared = 1;
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0011";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
if ($new_scan_hpacucli_variable_value < $clear_high_warning)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
# The temperature is no longer
# warning, and it didn't just go
# critical
$cleared = 1;
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0012";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
if ($new_scan_hpacucli_variable_value > $clear_low_critical)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$cleared = 1;
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0013";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
if ($new_scan_hpacucli_variable_value > $clear_low_warning)
{
my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$cleared = 1;
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0014";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cleared => $cleared,
alert_level => $alert_level,
message_key => $message_key,
}});
}
}
}
# Send an alert telling the user that we've found a variable for this
# controller. Note that we add ' C' to the temperatures so that they get
# translated to '°F' if desired by the reader.
my $variables = {
sensor_name => $variable,
serial_number => $scan_hpacucli_controller_serial_number,
name => $variable,
old_value => $type eq "temperature" ? $old_scan_hpacucli_variable_value." °C" : $old_scan_hpacucli_variable_value,
new_value => $type eq "temperature" ? $new_scan_hpacucli_variable_value." °C" : $new_scan_hpacucli_variable_value,
high_critical_temperature => $high_critical." °C",
high_warning_temperature => $high_warning." °C",
low_critical_temperature => $low_critical." °C",
low_warning_temperature => $low_warning." °C",
delta => $delta,
};
my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => $cleared,
alert_level => $alert_level,
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# UPDATE
my $query = "
UPDATE
scan_hpacucli_variables
SET
scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_variable_uuid = ".$anvil->Database->quote($variable_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
else
{
# New, record.
my $message_key = "scan_hpacucli_note_0004";
my $alert_level = "notice";
# Set defaults
my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_critical};
my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_warning};
my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_warning};
my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_critical};
my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{jump};
my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{buffer};
my $clear_high_critical = $high_critical - $buffer;
my $clear_high_warning = $high_warning - $buffer;
my $clear_low_critical = $low_critical - $buffer;
my $clear_low_warning = $low_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"high_critical" => $high_critical,
"high_warning" => $high_warning,
"low_warning" => $low_warning,
"low_critical" => $low_critical,
"jump" => $jump,
"buffer" => $buffer,
"clear_high_critical" => $clear_high_critical,
"clear_high_warning" => $clear_high_warning,
"clear_low_critical" => $clear_low_critical,
"clear_low_warning" => $clear_low_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
if ($type eq "temperature")
{
# Does this variable have defined limits?
if (exists $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical})
{
$high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical};
$high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_warning};
$low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_warning};
$low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_critical};
$jump = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{jump};
$buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{buffer};
$clear_high_critical = $high_critical - $buffer;
$clear_high_warning = $high_warning - $buffer;
$clear_low_critical = $low_critical - $buffer;
$clear_low_warning = $low_warning - $buffer;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
high_critical => $high_critical,
high_warning => $high_warning,
low_warning => $low_warning,
low_critical => $low_critical,
jump => $jump,
buffer => $buffer,
clear_high_critical => $clear_high_critical,
clear_high_warning => $clear_high_warning,
clear_low_critical => $clear_low_critical,
clear_low_warning => $clear_low_warning,
}});
# Fine-tune the alert thresholds
if ($clear_high_critical < $high_warning)
{
$clear_high_critical = $high_warning + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }});
}
if ($clear_low_critical > $low_warning)
{
$clear_low_critical = $low_warning - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }});
}
}
# This is a temperature, so see if the temperature outside of
# the warning or critical thresholds. This is a new sensor,
# so nothing to compare against.
my $temperature_state = "ok";
my $temperature_is = "nominal";
if ($new_scan_hpacucli_variable_value > $high_critical)
{
# Crossed the high critical threshold. This should
# always be unset because it is a new variable, but
# check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0005";
}
$temperature_state = "critical";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_variable_value > $high_warning)
{
# Crossed the high warning threshold. This should
# always be unset because it is a new variable, but
# check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0006";
}
$temperature_state = "warning";
$temperature_is = "high";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_variable_value < $low_critical)
{
# Dropped below the low critical threshold. This
# should always be unset because it is a new
# variable, but check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_critical", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "critical";
$message_key = "scan_hpacucli_note_0007";
}
$temperature_state = "critical";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"temperature_state" => $temperature_state,
"temperature_is" => $temperature_is,
}});
}
elsif ($new_scan_hpacucli_variable_value < $low_warning)
{
# Crossed the low warning threshold. This should
# always be unset because it is a new variable, but
# check anyway.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_warning", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
$alert_level = "warning";
$message_key = "scan_hpacucli_note_0008";
}
$temperature_state = "warning";
$temperature_is = "low";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
temperature_state => $temperature_state,
temperature_is => $temperature_is,
}});
}
# Record this for later processing into the 'temperature'
# table.
my $sensor_host_key = "controller:".$scan_hpacucli_controller_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }});
$anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_variable_value;
$anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state} = $temperature_state;
$anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is} = $temperature_is;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::temperature::${variable}::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c},
"new::temperature::${variable}::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state},
"new::temperature::${variable}::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is},
}});
}
# Send an alert telling the user that we've found a variable for this
# controller.
my $variables = {
sensor_name => $variable,
serial_number => $scan_hpacucli_controller_serial_number,
name => $variable,
value => $type eq "temperature" ? $new_scan_hpacucli_variable_value." °C" : $new_scan_hpacucli_variable_value,
high_critical_temperature => $high_critical." °C",
high_warning_temperature => $high_warning." °C",
low_critical_temperature => $low_critical." °C",
low_warning_temperature => $low_warning." °C",
};
my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => $alert_level,
message => $message_key,
variables => $variables,
show_header => 0,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
# INSERT
my $query = "
INSERT INTO
scan_hpacucli_variables
(
scan_hpacucli_variable_uuid,
scan_hpacucli_variable_host_uuid,
scan_hpacucli_variable_source_table,
scan_hpacucli_variable_source_uuid,
scan_hpacucli_variable_is_temperature,
scan_hpacucli_variable_name,
scan_hpacucli_variable_value,
modified_date
) VALUES (
".$anvil->Database->quote($anvil->Get->uuid()).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
'scan_hpacucli_controllers',
".$anvil->Database->quote($scan_hpacucli_controller_uuid).",
".$anvil->Database->quote($temperature).",
".$anvil->Database->quote($variable).",
".$anvil->Database->quote($new_scan_hpacucli_variable_value).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
}
}
# Look for removed controllers
foreach my $scan_hpacucli_controller_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}})
{
# Controller vanished!
my $old_scan_hpacucli_controller_serial_number = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number};
my $old_scan_hpacucli_controller_model = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model};
my $old_scan_hpacucli_controller_status = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan_hpacucli_controller_uuid" => $scan_hpacucli_controller_uuid,
"old_scan_hpacucli_controller_serial_number" => $old_scan_hpacucli_controller_serial_number,
"old_scan_hpacucli_controller_model" => $old_scan_hpacucli_controller_model,
"old_scan_hpacucli_controller_status" => $old_scan_hpacucli_controller_status,
}});
# Delete it so that we know it has been processed.
delete $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid};
# If the old alarm state is already 'VANISHED', ignore it.
next if $old_scan_hpacucli_controller_status eq "VANISHED";
# Still here? Alert and UPDATE.
### NOTE: For now, we're going to use warning level because controllers should never vanish
### unless one failed. If that is the case, the admin already knows, but this will let
### other notification targets know that the change has happened.
my $variables = {
model => $old_scan_hpacucli_controller_model,
serial_number => $old_scan_hpacucli_controller_serial_number,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0017", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0017",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_controllers
SET
scan_hpacucli_controller_status = 'VANISHED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
# Look for removed cache modules
foreach my $scan_hpacucli_cache_module_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}})
{
# Controller vanished!
my $old_scan_hpacucli_cache_module_serial_number = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number};
my $old_scan_hpacucli_cache_module_status = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan_hpacucli_cache_module_uuid" => $scan_hpacucli_cache_module_uuid,
"old_scan_hpacucli_cache_module_serial_number" => $old_scan_hpacucli_cache_module_serial_number,
"old_scan_hpacucli_cache_module_status" => $old_scan_hpacucli_cache_module_status,
}});
# Delete it so that we know it has been processed.
delete $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid};
# If the old alarm state is already 'VANISHED', ignore it.
next if $old_scan_hpacucli_cache_module_status eq "VANISHED";
# Still here? Alert and UPDATE.
### NOTE: For now, we're going to use warning level because cache_modules should never vanish
### unless one failed. If that is the case, the admin already knows, but this will let
### other notification targets know that the change has happened.
my $variables = {
serial_number => $old_scan_hpacucli_cache_module_serial_number,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0018", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_note_0018",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_cache_modules
SET
scan_hpacucli_cache_module_status = 'VANISHED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_cache_module_uuid = ".$anvil->Database->quote($scan_hpacucli_cache_module_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
# Look for removed controller variables.
foreach my $scan_hpacucli_controller_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}})
{
# Get the serial numbre for this contrller
my $scan_hpacucli_controller_serial_number = $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan_hpacucli_controller_uuid" => $scan_hpacucli_controller_uuid,
"scan_hpacucli_controller_serial_number" => $scan_hpacucli_controller_serial_number,
}});
foreach my $type ("detail", "temperature")
{
foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}})
{
my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value};
my $old_scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"type" => $type,
"scan_hpacucli_variable_name" => $scan_hpacucli_variable_name,
"old_scan_hpacucli_variable_value" => $old_scan_hpacucli_variable_value,
"old_scan_hpacucli_variable_uuid" => $old_scan_hpacucli_variable_uuid,
}});
# If the old alarm state is already 'VANISHED', ignore it.
next if $old_scan_hpacucli_variable_value eq "VANISHED";
# Still here? Alert and UPDATE.
### NOTE: For now, we're going to use warning level because cache_modules
### should never vanish unless one failed. If that is the case, the
### admin already knows, but this will let other notification targets
### know that the change has happened.
my $message_key = $type eq "temperature" ? "scan_hpacucli_note_0019" : "scan_hpacucli_note_0020";
my $variables = {
serial_number => $scan_hpacucli_controller_serial_number,
name => $scan_hpacucli_variable_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => $message_key,
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++,
set_by => $THIS_FILE,
});
my $query = "
UPDATE
scan_hpacucli_variables
SET
scan_hpacucli_variable_value = 'VANISHED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_hpacucli_variable_uuid = ".$anvil->Database->quote($old_scan_hpacucli_variable_uuid)."
;";
# Now record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query;
}
}
}
# Now commit the changes.
$anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__});
$anvil->data->{'scan-hpacucli'}{queries} = [];
return(0);
}
# This reads in the last scan's data.
sub read_last_scan
{
my ($anvil) = @_;
# Read in the controller(s)
my $query = "
SELECT
scan_hpacucli_controller_uuid,
scan_hpacucli_controller_serial_number,
scan_hpacucli_controller_model,
scan_hpacucli_controller_status,
scan_hpacucli_controller_last_diagnostics,
scan_hpacucli_controller_cache_present,
scan_hpacucli_controller_drive_write_cache,
scan_hpacucli_controller_firmware_version,
scan_hpacucli_controller_unsafe_writeback_cache
FROM
scan_hpacucli_controllers
WHERE
scan_hpacucli_controller_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_hpacucli_controller_uuid = $row->[0];
my $scan_hpacucli_controller_serial_number = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid,
scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number,
}});
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_serial_number;
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model} = $row->[2];
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status} = $row->[3];
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_last_diagnostics} = $row->[4];
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_cache_present} = $row->[5];
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_drive_write_cache} = $row->[6];
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_firmware_version} = $row->[7];
$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_unsafe_writeback_cache} = $row->[8];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_serial_number" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number},
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_model" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model},
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_status" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status},
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_last_diagnostics" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_last_diagnostics},
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_cache_present" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_cache_present},
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_drive_write_cache" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_drive_write_cache},
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_firmware_version" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_firmware_version},
"sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_unsafe_writeback_cache" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_unsafe_writeback_cache},
}});
# Store the information about this controllers
$anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_uuid;
$anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid} = $scan_hpacucli_controller_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::controllers::by_serial::${scan_hpacucli_controller_serial_number}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number},
"scan-hpacucli::controllers::by_uuid::${scan_hpacucli_controller_uuid}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid},
}});
}
undef $results;
undef $count;
# Now load the cache data
$query = "
SELECT
scan_hpacucli_cache_module_uuid,
scan_hpacucli_cache_module_serial_number,
scan_hpacucli_cache_module_controller_uuid,
scan_hpacucli_cache_module_status,
scan_hpacucli_cache_module_type,
scan_hpacucli_cache_module_size
FROM
scan_hpacucli_cache_modules
WHERE
scan_hpacucli_cache_module_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_hpacucli_cache_module_uuid = $row->[0];
my $scan_hpacucli_cache_module_serial_number = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid,
scan_hpacucli_cache_module_serial_number => $scan_hpacucli_cache_module_serial_number,
}});
# Store the information about this cache_module
$anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_controller_uuid} = $row->[2];
$anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number} = $scan_hpacucli_cache_module_serial_number;
$anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status} = $row->[3];
$anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_type} = $row->[4];
$anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_size} = $row->[5];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_controller_uuid" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_controller_uuid},
"sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_serial_number" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number},
"sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_status" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status},
"sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_type" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_type},
"sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_size" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_size},
}});
$anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$scan_hpacucli_cache_module_serial_number} = $scan_hpacucli_cache_module_uuid;
$anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid} = $scan_hpacucli_cache_module_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::cache_modules::by_serial::${scan_hpacucli_cache_module_serial_number}" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$scan_hpacucli_cache_module_serial_number},
"scan-hpacucli::cache_modules::by_uuid::${scan_hpacucli_cache_module_uuid}" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid},
}});
}
undef $results;
undef $count;
# The array data...
$query = "
SELECT
scan_hpacucli_array_uuid,
scan_hpacucli_array_name,
scan_hpacucli_array_controller_uuid,
scan_hpacucli_array_type,
scan_hpacucli_array_status,
scan_hpacucli_array_error_message
FROM
scan_hpacucli_arrays
WHERE
scan_hpacucli_array_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_hpacucli_array_uuid = $row->[0];
my $scan_hpacucli_array_name = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_array_uuid => $scan_hpacucli_array_uuid,
scan_hpacucli_array_name => $scan_hpacucli_array_name,
}});
# Store the drive group data. (Drive groups have no SN)
$anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid} = $row->[2];
$anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_name} = $scan_hpacucli_array_name;
$anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_type} = $row->[3];
$anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status} = $row->[4];
$anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_error_message} = $row->[5];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_controller_uuid" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid},
"sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_name" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_name},
"sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_type" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_type},
"sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_status" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status},
"sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_error_message" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_error_message},
}});
# Store the information about this virtual drive.
$anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name} = $scan_hpacucli_array_uuid;
$anvil->data->{'scan-hpacucli'}{virtual_drives}{by_uuid}{$scan_hpacucli_array_uuid} = $scan_hpacucli_array_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::virtual_drives::by_name::${scan_hpacucli_array_name}" => $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name},
"scan-hpacucli::virtual_drives::by_uuid::${scan_hpacucli_array_uuid}" => $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_uuid}{$scan_hpacucli_array_uuid},
}});
}
undef $results;
undef $count;
# The drive group data...
$query = "
SELECT
scan_hpacucli_logical_drive_uuid,
scan_hpacucli_logical_drive_name,
scan_hpacucli_logical_drive_array_uuid,
scan_hpacucli_logical_drive_caching,
scan_hpacucli_logical_drive_os_device_name,
scan_hpacucli_logical_drive_type,
scan_hpacucli_logical_drive_raid_level,
scan_hpacucli_logical_drive_size,
scan_hpacucli_logical_drive_strip_size,
scan_hpacucli_logical_drive_stripe_size,
scan_hpacucli_logical_drive_status
FROM
scan_hpacucli_logical_drives
WHERE
scan_hpacucli_logical_drive_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_hpacucli_logical_drive_uuid = $row->[0];
my $scan_hpacucli_logical_drive_name = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_logical_drive_uuid => $scan_hpacucli_logical_drive_uuid,
scan_hpacucli_logical_drive_name => $scan_hpacucli_logical_drive_name,
}});
# Store the logical drive data. (LDs have no SN)
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name} = $scan_hpacucli_logical_drive_name;
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid} = $row->[2];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_caching} = $row->[3];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_os_device_name} = $row->[4];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_type} = $row->[5];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_raid_level} = $row->[6];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_size} = $row->[7];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_strip_size} = $row->[8];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_stripe_size} = $row->[9];
$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status} = $row->[10];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_array_uuid" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_name" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_caching" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_caching},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_os_device_name" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_os_device_name},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_type" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_type},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_raid_level" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_raid_level},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_size" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_size},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_strip_size" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_strip_size},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_stripe_size" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_stripe_size},
"sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_status" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status},
}});
# Store the information about this virtual drive.
$anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} = $scan_hpacucli_logical_drive_uuid;
$anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid} = $scan_hpacucli_logical_drive_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::logical_drives::by_name::${scan_hpacucli_logical_drive_name}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name},
"scan-hpacucli::logical_drives::by_uuid::${scan_hpacucli_logical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid},
}});
}
undef $results;
undef $count;
# And now, the physical drives.
$query = "
SELECT
scan_hpacucli_physical_drive_uuid,
scan_hpacucli_physical_drive_serial_number,
scan_hpacucli_physical_drive_logical_drive_uuid,
scan_hpacucli_physical_drive_model,
scan_hpacucli_physical_drive_interface,
scan_hpacucli_physical_drive_status,
scan_hpacucli_physical_drive_size,
scan_hpacucli_physical_drive_type,
scan_hpacucli_physical_drive_rpm,
scan_hpacucli_physical_drive_temperature,
scan_hpacucli_physical_drive_last_failure_reason,
scan_hpacucli_physical_drive_port,
scan_hpacucli_physical_drive_box,
scan_hpacucli_physical_drive_bay
FROM
scan_hpacucli_physical_drives
WHERE
scan_hpacucli_physical_drive_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_hpacucli_physical_drive_uuid = $row->[0];
my $scan_hpacucli_physical_drive_serial_number = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_physical_drive_uuid => $scan_hpacucli_physical_drive_uuid,
scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number,
}});
# Store the information about this physical drive
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_logical_drive_uuid} = $row->[2];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_serial_number} = $scan_hpacucli_physical_drive_serial_number;
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_model} = $row->[3];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_interface} = $row->[4];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_status} = $row->[5];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_size} = $row->[6];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_type} = $row->[7];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_rpm} = $row->[8];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_temperature} = $row->[9];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_last_failure_reason} = $row->[10];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_port} = $row->[11];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_box} = $row->[12];
$anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_bay} = $row->[13];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_logical_drive_uuid" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_logical_drive_uuid},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_serial_number" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_serial_number},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_model" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_model},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_interface" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_interface},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_status" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_status},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_size" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_size},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_type" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_type},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_rpm" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_rpm},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_temperature" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_temperature},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_last_failure_reason" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_last_failure_reason},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_port" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_port},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_box" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_box},
"sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_bay" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_bay},
}});
# Make it so that we can look up the serial number from the drive's UUID and vice versa
$anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number} = $scan_hpacucli_physical_drive_uuid;
$anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid} = $scan_hpacucli_physical_drive_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::physical_drives::by_serial::${scan_hpacucli_physical_drive_serial_number}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number},
"scan-hpacucli::physical_drives::by_uuid::${scan_hpacucli_physical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid},
}});
}
undef $results;
undef $count;
# Lastly, the variables.
$query = "
SELECT
scan_hpacucli_variable_uuid,
scan_hpacucli_variable_source_table,
scan_hpacucli_variable_source_uuid,
scan_hpacucli_variable_is_temperature,
scan_hpacucli_variable_name,
scan_hpacucli_variable_value
FROM
scan_hpacucli_variables
WHERE
scan_hpacucli_variable_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $scan_hpacucli_variable_uuid = $row->[0];
my $scan_hpacucli_variable_source_table = $row->[1];
my $scan_hpacucli_variable_source_uuid = $row->[2];
my $scan_hpacucli_variable_is_temperature = $row->[3];
my $scan_hpacucli_variable_name = $row->[4];
my $scan_hpacucli_variable_value = $row->[5];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid,
scan_hpacucli_variable_source_table => $scan_hpacucli_variable_source_table,
scan_hpacucli_variable_source_uuid => $scan_hpacucli_variable_source_uuid,
scan_hpacucli_variable_is_temperature => $scan_hpacucli_variable_is_temperature,
scan_hpacucli_variable_name => $scan_hpacucli_variable_name,
scan_hpacucli_variable_value => $scan_hpacucli_variable_value,
}});
# We store these differently for easier reference. Diagnostic data is stored in the special
# 'scan_hpacucli_physical_drive_diagnostics' source.
my $type = "detail";
if ($scan_hpacucli_variable_source_table eq "scan_hpacucli_physical_drive_diagnostics")
{
$type = "diagnostics";
}
if ($scan_hpacucli_variable_is_temperature eq "1")
{
$type = "temperature";
}
$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name} = {
scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid,
scan_hpacucli_variable_is_temperature => $scan_hpacucli_variable_is_temperature,
scan_hpacucli_variable_value => $scan_hpacucli_variable_value,
};
# Entries are so long that we log the one per variable.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::${scan_hpacucli_variable_source_table}::source_uuid::${scan_hpacucli_variable_source_uuid}::${type}::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::${scan_hpacucli_variable_source_table}::source_uuid::${scan_hpacucli_variable_source_uuid}::${type}::${scan_hpacucli_variable_name}::scan_hpacucli_variable_is_temperature" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_is_temperature},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::${scan_hpacucli_variable_source_table}::source_uuid::${scan_hpacucli_variable_source_uuid}::${type}::${scan_hpacucli_variable_name}::scan_hpacucli_variable_value" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value},
}});
}
undef $results;
undef $count;
# Return the number
return(0);
}
# This looks for anything other than temperature sensors that will feed into the health of the node.
sub pre_process_health
{
my ($anvil) = @_;
# This is to collected data from every sweep.
foreach my $scan_hpacucli_controller_serial_number (sort {$a cmp $b} keys %{$anvil->data->{controller}})
{
# We don't care about metadata
next if $scan_hpacucli_controller_serial_number eq "metadata";
# Controller data
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}})
{
if (($variable eq "battery_or_capacitor_status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{$variable}) ne "ok"))
{
# BBU/FBU problem, score of 2
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":data:".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
elsif (($variable eq "cache_status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{$variable}) ne "ok"))
{
# Cache isn't OK, score of 2
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":data:".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
elsif (($variable eq "controller_status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{$variable}) ne "ok"))
{
# The controller isn't OK, this is major, score of 10
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":data:".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 10;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
}
# Array
foreach my $scan_hpacucli_array_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}})
{
# Data
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}})
{
if (($variable eq "status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{$variable}) ne "ok"))
{
# Something is wrong with this array
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":array:".$scan_hpacucli_array_name.":".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 5;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
}
# Logical Drive
foreach my $logical_drive (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}})
{
# Data
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{detail}})
{
if (($variable eq "caching") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{detail}{$variable}) ne "enabled"))
{
# Not enabled is going to hurt performance.
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":array:".$scan_hpacucli_array_name.":logical_drive:".$logical_drive.":".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
elsif (($variable eq "status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{detail}{$variable}) ne "ok"))
{
# If the status isn't OK, it's degraded (or rebuilding, but
# still degraded).
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":array:".$scan_hpacucli_array_name.":logical_drive:".$logical_drive.":".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
}
# Physical Disks.
foreach my $port (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}})
{
foreach my $box (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}})
{
foreach my $bay (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}})
{
my $scan_hpacucli_physical_drive_serial_number = $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{serial_number};
# Data
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}})
{
next if $variable eq "serial_number";
next if $variable eq "port";
next if $variable eq "box";
next if $variable eq "bay";
if (($variable eq "status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{$variable}) ne "ok"))
{
# The drive is failed or is rebuilding. This adds 2.
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":physical_drive:".$scan_hpacucli_physical_drive_serial_number.":data:".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
}
# If this was a diagnostics run, check for error
# counters
if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics})
{
# If the diagnostics don't exist for the
# drive and the drive is OK, it's likely a
# 3rd party drive. If the status is not OK,
# there may not be diagnostic data.
if (exists $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard})
{
# We got the data
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}})
{
# Store this in the main hash.
if ((($variable eq "hardware_errors") or
($variable eq "predictive_failure_errors") or
($variable eq "read_errors_hard") or
($variable eq "write_errors_hard")) &&
($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} =~ /^\d+$/) &&
($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} > 0))
{
# How high is the error count?
my $score = 1;
if ($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} > 10)
{
# Eek
$score = 3;
}
elsif ($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} > 5)
{
# Getting a little high
$score = 2;
}
my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":physical_drive:".$scan_hpacucli_physical_drive_serial_number.":diagnostics:".$variable;
$anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = $score;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name},
}});
}
# Record the diagnostic data
# under the drive's hash.
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{'diagnostics'}{$variable} = $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable};
}
}
elsif (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{status}) eq "ok")
{
# No data for this drive. It might be
# a 3rd party drive. We'll warn the
# user that we can't predict failure.
my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":no_diagnostics", set_by => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
# Warn the user that we can't
# predict this drive's death.
my $variables = {
serial_number => $scan_hpacucli_physical_drive_serial_number,
port => $port,
box => $box,
bay => $bay,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_warning_0001", variables => $variables});
$anvil->Alert->register({
clear_alert => 0,
alert_level => "warning",
message => "scan_hpacucli_warning_0001",
variables => $variables,
show_header => 1,
sort_position => $anvil->data->{'scan-hpacucli'}{alert_sort}++,
set_by => $THIS_FILE,
});
}
}
}
}
}
}
}
}
}
return(0);
}
# This gets the basic information about the controller.
sub get_controller_info
{
my ($anvil, $controller) = @_;
my $model_name = "";
my $scan_hpacucli_controller_serial_number = "";
my $cache_serial_number = "";
my $scan_hpacucli_physical_drive_serial_number = "";
my $scan_hpacucli_array_name = "";
my $logical_drive = "";
my $port = "";
my $box = "";
my $bay = "";
my $in_array = 0;
my $shell_call = $anvil->data->{path}{exe}{hpacucli}." controller slot=".$controller." show config detail";
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output)
{
$line = $anvil->Words->clean_spaces({string => $line});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ((not $scan_hpacucli_controller_serial_number) && ($line =~ /^(.*?) in Slot $controller /))
{
$model_name = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { model_name => $model_name }});
}
if (($line =~ /^Serial Number: (.*?)$/) && (not $port) && (not $box) && (not $bay))
{
$scan_hpacucli_controller_serial_number = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number }});
# Record the model number
if ($model_name)
{
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{model_name} = $model_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::data::detail::model_name" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{model_name},
}});
}
# Make a reference between the slot and SN
$anvil->data->{controller}{metadata}{sn_to_slot}{$scan_hpacucli_controller_serial_number} = $controller;
$anvil->data->{controller}{metadata}{slot_to_sn}{$controller} = $scan_hpacucli_controller_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::metadata::sn_to_slot::${scan_hpacucli_controller_serial_number}" => $anvil->data->{controller}{metadata}{sn_to_slot}{$scan_hpacucli_controller_serial_number},
"controller::metadata::slot_to_sn::${controller}" => $anvil->data->{controller}{metadata}{slot_to_sn}{$controller},
}});
next;
}
next if not $scan_hpacucli_controller_serial_number;
if ($line =~ /Cache Serial Number: (.*?)$/i)
{
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{cache_serial_number} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::data::detail::cache_serial_number" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{cache_serial_number},
}});
next;
}
if ($line =~ /Array: (.*?)$/i)
{
$scan_hpacucli_array_name = $1;
$in_array = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_array_name => $scan_hpacucli_array_name,
in_array => $in_array,
}});
next;
}
if ($line =~ /Logical Drive: (.*?)$/i)
{
$logical_drive = $1;
$in_array = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
logical_drive => $logical_drive,
in_array => $in_array,
}});
next;
}
if ($line =~ /physicaldrive (.*?):(.*?):(.*)$/)
{
$port = $1;
$box = $2;
$bay = $3;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
port => $port,
box => $box,
bay => $bay,
}});
next;
}
elsif (($port) && (($line eq "Drive Type: Data") or ($line =~ /^Mirror Group \d+:$/)))
{
$port = "";
$box = "";
$bay = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
port => $port,
box => $box,
bay => $bay,
}});
}
if (lc($line) eq "unassigned")
{
$scan_hpacucli_array_name = "ZZZZ";
$logical_drive = "9999";
$port = "";
$box = "";
$bay = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_hpacucli_array_name => $scan_hpacucli_array_name,
logical_drive => $logical_drive,
port => $port,
box => $box,
bay => $bay,
}});
next;
}
# Lines I don't care about
next if $line =~ /^Slot: $controller$/i;
my $type = "detail";
if ($line =~ /^(.*?): (.*)$/)
{
my $variable = $1;
my $value = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
variable => $variable,
value => $value,
}});
# If the variable has units, pull them out.
if ($variable =~ / \(C\)$/i)
{
$variable =~ s/ \(C\)$//i;
$variable = $anvil->Words->clean_spaces({string => $variable});
$type = "temperature";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
variable => $variable,
value => $value,
type => $type,
}});
}
elsif ($variable =~ / \(F\)/i)
{
# Covert to °C
$variable =~ s/ \(F\)$//i;
$variable = $anvil->Words->clean_spaces({string => $variable});
$value = $anvil->Convert->fahrenheit_to_celsius({temperature => $value});
$type = "temperature";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
variable => $variable,
value => $value,
type => $type,
}});
}
elsif (($value =~ /^\d+ \wB$/) or ($value =~ /^\d+\.\d+ \wB$/))
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
variable => $variable,
">> value" => $value,
}});
if (($variable eq "Total Cache Size") or
($variable eq "Total Cache Memory Available") or
($variable eq "Strip Size") or
($variable eq "Size") or
($variable eq "Full Stripe Size"))
{
# HP reports in MB, etc, but means MiB.
$value = $anvil->Convert->human_readable_to_bytes({size => $value, base2 => 1});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
variable => $variable,
"<< value" => $value,
}});
}
}
# Save it.
if (exists $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{$type}{$variable})
{
# Conflict! This is a dirty way to keep them separate
$variable .= " 2";
}
$variable = process_variable_name($anvil, $variable);
# What am I saving?
if (($port) && ($box) && ($bay))
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"line" => $line,
}});
# Physical drive info
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{$type}{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::logical_drive::${logical_drive}::physical_drive::port::${port}::box::${box}::bay::${bay}::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{$type}{$variable},
}});
# Map the SN to it's current location.
if ($line =~ /Serial Number: (.*?)$/)
{
$scan_hpacucli_physical_drive_serial_number = $1;
my $location = $port.":".$box.":".$bay;
$anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number} = {
array => $scan_hpacucli_array_name,
logical_drive => $logical_drive,
port => $port,
box => $box,
bay => $bay,
};
$anvil->data->{physical_drive}{by_location}{$location} = $scan_hpacucli_physical_drive_serial_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::array" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{array},
"physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::logical_drive" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{logical_drive},
"physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::port" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{port},
"physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::box" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{box},
"physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::bay" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{bay},
"physical_drive::by_location::$location" => $anvil->data->{physical_drive}{by_location}{$location},
}});
}
}
elsif ($logical_drive)
{
# Logical drive
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{$type}{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::logical_drive::${logical_drive}::data::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{$type}{$variable},
}});
}
elsif ($scan_hpacucli_array_name)
{
# Array
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{$type}{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::data::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{$type}{$variable},
}});
}
else
{
# Controller data
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::data::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable},
}});
}
}
elsif ($in_array)
{
# Messages about a degraded array can be here.
# ie: "One of the drives on this array have failed or has been removed."
if ($line =~ /this array have failed/)
{
# We'll concatonate in case there are multiple errors.
if (not exists $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message})
{
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message} = "";
}
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message} .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::data::detail::error_message" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message},
}});
}
}
}
# If I didn't find a serial number, something went wrong.
if (not $scan_hpacucli_controller_serial_number)
{
# Error out.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0004", variables => { controller => $controller }});
$anvil->nice_exit({exit_code => 6});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number }});
return($scan_hpacucli_controller_serial_number);
}
# This will do a details diagnostics check, if enough time has passed.
sub get_diagnostics
{
my ($anvil, $controller) = @_;
# Every 'scan-hpacucli::diagnostics_interval' seconds, run a full diagnostics to check for drives in
# pre-failure.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::process_diagnostics" => $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics} }});
if (not $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics})
{
# Is it time?
my $query = "SELECT scan_hpacucli_controller_last_diagnostics FROM scan_hpacucli_controllers WHERE scan_hpacucli_controller_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
# The actual query -----------------. .------- Row 0
# Query this DB --. | | .-- Columns 0
my $last_diagnostics = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$last_diagnostics = 0 if not defined $last_diagnostics;
my $current_time = time;
my $last_scan_was = $current_time - $last_diagnostics;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
last_diagnostics => $last_diagnostics,
current_time => $current_time,
last_scan_was => $last_scan_was,
"scan-hpacucli::diagnostics_interval" => $anvil->data->{'scan-hpacucli'}{diagnostics_interval},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::diagnostics_interval" => $last_diagnostics,
}});
if ($anvil->data->{'scan-hpacucli'}{diagnostics_interval} !~ /^\d+$/)
{
# Invalid value, override.
$anvil->data->{'scan-hpacucli'}{diagnostics_interval} = 1800;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan-hpacucli::diagnostics_interval" => $anvil->data->{'scan-hpacucli'}{diagnostics_interval},
}});
}
if ($last_scan_was > $anvil->data->{'scan-hpacucli'}{diagnostics_interval})
{
$anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sys::process_diagnostics" => $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics},
}});
}
}
# Well, is it?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sys::process_diagnostics" => $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics},
}});
if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics})
{
# Yup! We use hpacucli's diagnostics to gather all data.
my $shell_call = "
cd /tmp/
".$anvil->data->{path}{exe}{hpacucli}." controller slot=".$controller." diag file=/tmp/ADUReport.zip
".$anvil->data->{path}{exe}{'unzip'}." -o /tmp/ADUReport.zip -d /tmp/
if [ -e '/tmp/ADUReport.xml' ];
then
".$anvil->data->{path}{exe}{rm}." -f /tmp/ADUReport.zip
".$anvil->data->{path}{exe}{rm}." -f /tmp/ADUReport.htm
".$anvil->data->{path}{exe}{rm}." -f /tmp/ADUReport.xml
".$anvil->data->{path}{exe}{rm}." -f /tmp/report.checksum
fi
";
# Write a log message to warn the user that we're starting a long process.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_log_0003", variables => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
}
undef $output;
undef $return_code;
# Did it work?
if (not -r "/tmp/ADUReport.txt")
{
# Something went wrong.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0005", variables => { path => "/tmp/ADUReport.txt" }});
$anvil->nice_exit({exit_code => 4});
}
# Get this controller's serial number
my $scan_hpacucli_controller_serial_number = $anvil->data->{controller}{metadata}{slot_to_sn}{$controller};
# Parse!
my $in_cache_config_status = 0;
my $in_physical_drive = 0;
my $scan_hpacucli_physical_drive_serial_number = "";
my $port = "";
my $box = "";
my $bay = "";
my $skip_blank_line = 0;
$shell_call = "/tmp/ADUReport.txt";
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output)
{
$line = $anvil->Words->clean_spaces({string => $line});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if (not $line)
{
if ($skip_blank_line)
{
next;
}
$in_cache_config_status = 0;
$in_physical_drive = 0;
$scan_hpacucli_physical_drive_serial_number = "";
$port = "";
$box = "";
$bay = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
in_cache_config_status => $in_cache_config_status,
in_physical_drive => $in_physical_drive,
scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number,
port => $port,
box => $box,
bay => $bay,
}});
next;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
$skip_blank_line = 0;
if ($line =~ /: Cache Config Status$/i)
{
$in_cache_config_status = 1;
$skip_blank_line = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_cache_config_status => $in_cache_config_status }});
next;
}
if ($line =~ /: Physical Drive \(.*?\) (.*?):(.*?):(.*?) : Monitor and Performance Statistics \(Since Factory\)/)
{
$port = $1;
$box = $2;
$bay = $3;
$skip_blank_line = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
port => $port,
box => $box,
bay => $bay,
}});
}
if ($in_cache_config_status)
{
if ($line =~ /Parity Read Errors (\d+) \(/)
{
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_read_errors} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::diagnostics::cache::parity_read_errors" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_read_errors},
}});
}
if ($line =~ /Parity Write Errors (\d+) \(/)
{
$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_write_errors} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"controller::${scan_hpacucli_controller_serial_number}::diagnostics::cache::parity_write_errors" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_write_errors},
}});
}
}
if (($port) && ($box) && ($bay))
{
my $location = $port.":".$box.":".$bay;
$scan_hpacucli_physical_drive_serial_number = $anvil->data->{physical_drive}{by_location}{$location};
if ($line =~ /Read Errors Hard (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::read_errors_hard" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard},
}});
}
if ($line =~ /Read Errors Retry Recovered (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_retry_recovered} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::read_errors_retry_recovered" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_retry_recovered},
}});
}
if ($line =~ /Read Errors ECC Corrected (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_ecc_corrected} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::read_errors_ecc_corrected" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_ecc_corrected},
}});
}
if ($line =~ /Write Errors Hard (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_hard} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::write_errors_hard" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_hard},
}});
}
if ($line =~ /Write Errors Retry Recovered (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_retry_recovered} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::write_errors_retry_recovered" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_retry_recovered},
}});
}
if ($line =~ /Format Errors (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{format_errors} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::format_errors" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{format_errors},
}});
}
if ($line =~ /Write Errors After Remap (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_after_remap} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::write_errors_after_remap" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_after_remap},
}});
}
if ($line =~ /Hardware Errors (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{hardware_errors} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::hardware_errors" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{hardware_errors},
}});
}
if ($line =~ /Predictive Failure Errors (0x.*?)$/)
{
my $hex = $1;
$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{predictive_failure_errors} = hex($hex);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hex" => $hex,
"physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::predictive_failure_errors" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{predictive_failure_errors},
}});
}
}
}
}
return(0);
}
# This gathers the various data from the controller(s).
sub gather_data
{
my ($anvil) = @_;
### TODO: This assumes the controllers go 0, 1, ... n. If this is wrong, we'll need to call
### 'hpacucli controller all show' and parse the output as our outer loop.
# Loops through reach found controller.
foreach my $count (1..$anvil->data->{'scan-hpacucli'}{sys}{controller_count})
{
my $controller = $count - 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { controller => $controller }});
# Read in controller data.
my $scan_hpacucli_controller_serial_number = get_controller_info($anvil, $controller);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number }});
get_diagnostics($anvil, $controller);
}
return(0);
}
# This processes variable names to flatten them and remove spaces and special characters.
sub process_variable_name
{
my ($anvil, $variable) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "<< variable" => $variable }});
$variable = lc($variable);
$variable =~ s/ /_/g;
$variable =~ s/-/_/g;
$variable =~ s/&/and/g;
$variable =~ s/\//_or_/g;
$variable =~ s/_%/_percent/g;
$variable =~ s/{_}+/_/g;
$variable =~ s/^_+//g;
$variable =~ s/_+$//g;
$variable =~ s/(\w)\(/$1_\(/;
$variable =~ s/\((.*?)\)/-_$1/g;
$variable =~ s/_+/_/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ">> variable" => $variable }});
return($variable);
}
# This does two things; It checks to see if hpacucli is installed (exits '1' if not, exits '2' if not
# executable) and then checks to see if any controllers are found in the system (exits '3' if not).
sub find_hp_controllers
{
my ($anvil) = @_;
# This will keep track of how many controllers we find.
my $controller_count = 0;
# First, do we have hpacucli installed?
if (not -e $anvil->data->{path}{exe}{hpacucli})
{
# Nope, exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "scan_hpacucli_error_0001", variables => { path => $anvil->data->{path}{exe}{hpacucli} }});
$anvil->nice_exit({exit_code => 1});
}
# Make sure it is executable
if (not -x $anvil->data->{path}{exe}{hpacucli})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0002", variables => { path => $anvil->data->{path}{exe}{hpacucli} }});
$anvil->nice_exit({exit_code => 2});
}
# Still alive? Good! Look for controllers now.
my $shell_call = $anvil->data->{path}{exe}{hpacucli}." controller all show";
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /.*? Slot (\d+) .*?\(sn: (.*?)\)/i)
{
my $controller_number = $1;
my $controller_serial_number = $2;
$controller_count++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
controller_number => $controller_number,
controller_serial_number => $controller_serial_number,
controller_count => $controller_count,
}});
}
}
# Have we any controllers?
if ($controller_count > 0)
{
$anvil->data->{'scan-hpacucli'}{sys}{controller_count} = $controller_count;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "scan_hpacucli_log_0001", variables => { count => $anvil->data->{'scan-hpacucli'}{sys}{controller_count} }});
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0003", variables => { path => $anvil->data->{path}{exe}{hpacucli} }});
$anvil->nice_exit({exit_code => 3});
}
return(0);
}