* Fixed a bug in Convert-round() where the requested number of digits after the decimal place was coming back one too long. Also added logging that should have been there for a while now.

* Finished scan-filesystems!
* Realized that filesystem UUIDs are not always actual UUIDs, and so created an additonal column in filesystems -> filesystem_internal_uuid and created a normal filesystem_uuid table.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent 079f724e77
commit 9fa24750d6
  1. 1
      Anvil/Tools.pm
  2. 22
      Anvil/Tools/Convert.pm
  3. 12
      Anvil/Tools/Storage.pm
  4. 679
      scancore-agents/scan-filesystems/scan-filesystems
  5. 6
      scancore-agents/scan-filesystems/scan-filesystems.sql
  6. 34
      scancore-agents/scan-filesystems/scan-filesystems.xml
  7. 2
      scancore-agents/scan-hardware/scan-hardware

@ -1203,6 +1203,7 @@ sub _set_paths
stty => "/usr/bin/stty",
su => "/usr/bin/su",
'subscription-manager' => "/usr/sbin/subscription-manager",
swapon => "/usr/sbin/swapon",
systemctl => "/usr/bin/systemctl",
timeout => "/usr/bin/timeout",
touch => "/usr/bin/touch",

@ -1202,6 +1202,7 @@ sub round
# Take out any commas.
$rounded_number =~ s/,//g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { rounded_number => $rounded_number }});
# If there is a decimal place in the number, do the smart math. Otherwise, just pad the number with
# the requested number of zeros after the decimal place.
@ -1209,6 +1210,10 @@ sub round
{
# Split up the number.
my ($real, $decimal) = split/\./, $rounded_number, 2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
real => $real,
decimal => $decimal,
}});
# If there is anything other than one ',' and digits, error.
if (($real =~ /\D/) or ($decimal =~ /\D/))
@ -1222,24 +1227,27 @@ sub round
if ( length($decimal) == $places )
{
# Equal, return.
return $rounded_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { rounded_number => $rounded_number }});
return($rounded_number);
}
elsif ( length($decimal) < $places )
{
# Less, pad.
$rounded_number = sprintf("%.${places}f", $rounded_number);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { rounded_number => $rounded_number }});
}
else
{
# Greater than; I need to round the number. Start by getting the number of places I
# need to round.
my $round_diff = length($decimal) - $places;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { round_diff => $round_diff }});
# This keeps track of whether the next (left) digit needs to be incremented.
my $increase = 0;
# Now loop the number of times needed to round to the requested number of places.
for (1..$round_diff)
for (0..$round_diff)
{
# Reset 'increase'.
$increase = 0;
@ -1249,16 +1257,23 @@ sub round
{
my $last_digit = $1;
$decimal =~ s/$last_digit$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
last_digit => $last_digit,
decimal => $decimal,
}});
if ($last_digit > 4)
{
$increase = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { increase => $increase }});
if ($decimal eq "")
{
$real++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { real => $real }});
}
else
{
$decimal++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { decimal => $decimal }});
}
}
}
@ -1266,10 +1281,12 @@ sub round
if ($places == 0 )
{
$rounded_number = $real;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { rounded_number => $rounded_number }});
}
else
{
$rounded_number = $real.".".$decimal;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { rounded_number => $rounded_number }});
}
}
}
@ -1277,6 +1294,7 @@ sub round
{
# This is a whole number so just pad 0s as needed.
$rounded_number = sprintf("%.${places}f", $rounded_number);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { rounded_number => $rounded_number }});
}
# Return the number.

@ -2164,7 +2164,7 @@ sub parse_lsblk
$anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_type} = defined $hash_ref->{fstype} ? $hash_ref->{fstype} : "";
# This is the LVM formatted UUID, when it's an 'LVM2_member', so it should be easy to cross
# reference with: scan_lvm_lvs -> scan_lvm_lv_internal_uuid to map the LVs to a PV
$anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_uuid} = defined $hash_ref->{uuid} ? $hash_ref->{uuid} : "";
$anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_internal_uuid} = defined $hash_ref->{uuid} ? $hash_ref->{uuid} : "";
$anvil->{storage}{lsblk}{$kernel_device_name}{hot_plug} = defined $hash_ref->{hotplug} ? $hash_ref->{hotplug} : "";
$anvil->{storage}{lsblk}{$kernel_device_name}{logical_sector_size} = defined $hash_ref->{'log-sec'} ? $hash_ref->{'log-sec'} : 0;
$anvil->{storage}{lsblk}{$kernel_device_name}{model} = defined $hash_ref->{model} ? $hash_ref->{model} : "";
@ -2182,10 +2182,16 @@ sub parse_lsblk
$anvil->{storage}{lsblk}{$kernel_device_name}{size} = defined $hash_ref->{size} ? $hash_ref->{size} : 0;
$anvil->{storage}{lsblk}{$kernel_device_name}{'state'} = defined $hash_ref->{'state'} ? $hash_ref->{'state'} : "";
$anvil->{storage}{lsblk}{$kernel_device_name}{transport} = defined $hash_ref->{tran} ? $hash_ref->{tran} : "";
$anvil->{storage}{lsblk}{$kernel_device_name}{type} = $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_uuid} ? "partition" : "drive";
$anvil->{storage}{lsblk}{$kernel_device_name}{type} = $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_internal_uuid} ? "partition" : "drive";
$anvil->{storage}{lsblk}{$kernel_device_name}{vendor} = defined $hash_ref->{vendor} ? $hash_ref->{vendor} : "";
$anvil->{storage}{lsblk}{$kernel_device_name}{vendor} = $anvil->Words->clean_spaces({string => $anvil->{storage}{lsblk}{$kernel_device_name}{vendor}});
# Standardize the 'swap' partitions to '<swap>'
if (($anvil->{storage}{lsblk}{$kernel_device_name}{mount_point} eq "[SWAP]") or ((defined $hash_ref->{fstype}) && ($hash_ref->{fstype} eq "swap")))
{
$anvil->{storage}{lsblk}{$kernel_device_name}{mount_point} = "<swap>";
}
# There's precious little data that comes from SD cards.
if ($kernel_device_name =~ /^mmcblk/)
{
@ -2219,7 +2225,7 @@ sub parse_lsblk
"storage::lsblk::${kernel_device_name}::alignment_offset" => $anvil->{storage}{lsblk}{$kernel_device_name}{alignment_offset},
"storage::lsblk::${kernel_device_name}::device_type" => $anvil->{storage}{lsblk}{$kernel_device_name}{device_type},
"storage::lsblk::${kernel_device_name}::filesystem_type" => $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_type},
"storage::lsblk::${kernel_device_name}::filesystem_uuid" => $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_uuid},
"storage::lsblk::${kernel_device_name}::filesystem_internal_uuid" => $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_internal_uuid},
"storage::lsblk::${kernel_device_name}::hot_plug" => $anvil->{storage}{lsblk}{$kernel_device_name}{hot_plug},
"storage::lsblk::${kernel_device_name}::logical_sector_size" => $anvil->{storage}{lsblk}{$kernel_device_name}{logical_sector_size},
"storage::lsblk::${kernel_device_name}::model" => $anvil->{storage}{lsblk}{$kernel_device_name}{model},

@ -49,6 +49,7 @@ if (($< != 0) && ($> != 0))
# These are the threasholds for when to alert when swap is running out.
$anvil->data->{scancore}{'scan-filesystems'}{disable} = 0;
$anvil->data->{'scan-filesystems'}{alert_sort} = 2;
$anvil->data->{switches}{force} = 0;
$anvil->Storage->read_config();
@ -104,268 +105,503 @@ sub find_changes
{
my ($anvil) = @_;
=cut
foreach my $scan_filesystem_type (keys %{$anvil->data->{filesystem}{scan_filesystem_type}})
{
my $scan_filesystem_kernel_name = $anvil->data->{filesystem}{scan_filesystem_type}{$scan_filesystem_type}{name};
my $scan_filesystem_mount_point = $anvil->data->{filesystem}{scan_filesystem_type}{$scan_filesystem_type}{used_by_vg};
my $scan_filesystem_media_type = $anvil->data->{filesystem}{scan_filesystem_type}{$scan_filesystem_type}{attributes};
my $scan_filesystem_size = $anvil->data->{filesystem}{scan_filesystem_type}{$scan_filesystem_type}{size};
my $scan_filesystem_free = $anvil->data->{filesystem}{scan_filesystem_type}{$scan_filesystem_type}{free_space};
foreach my $filesystem_internal_uuid (sort {$a cmp $b} keys %{$anvil->data->{new}{partition}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { filesystem_uuid => $filesystem_internal_uuid }});
# Skip LVM devices as they're tracked by 'scan-lvm'.
next if $anvil->data->{new}{partition}{$filesystem_internal_uuid}{type} eq "LVM2_member";
my $new_kernel_name = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{kernel_name};
my $new_type = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{type};
my $new_mount_point = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{mount_point};
my $new_transport = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{transport};
my $new_media_type = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{media_type};
my $new_vendor = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{vendor};
my $new_model = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{model};
my $new_serial_number = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{serial_number};
my $new_description = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{description};
my $new_size = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{size};
my $new_used = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{used};
my $new_free = $new_size - $new_used;
my $new_free_percent = $anvil->Convert->round({number => ((($new_size - $new_used)/$new_size) * 100), places => 1});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_filesystem_type => $scan_filesystem_type,
scan_filesystem_kernel_name => $scan_filesystem_kernel_name,
scan_filesystem_mount_point => $scan_filesystem_mount_point,
scan_filesystem_media_type => $scan_filesystem_media_type,
scan_filesystem_size => $anvil->Convert->add_commas({number => $scan_filesystem_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_filesystem_size}),
scan_filesystem_free => $anvil->Convert->add_commas({number => $scan_filesystem_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_filesystem_free}),
new_kernel_name => $new_kernel_name,
new_type => $new_type,
new_mount_point => $new_mount_point,
new_transport => $new_transport,
new_media_type => $new_media_type,
new_vendor => $new_vendor,
new_model => $new_model,
new_serial_number => $new_serial_number,
new_description => $new_description,
new_size => $anvil->Convert->add_commas({number => $new_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_size}),
new_used => $anvil->Convert->add_commas({number => $new_used})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_used}),
new_free => $anvil->Convert->add_commas({number => $new_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_free}),
new_free_percent => $new_free_percent,
}});
# Have we seen this before?
if (exists $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid})
{
# Yup, anything changed?
my $scan_filesystem_uuid = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_uuid};
my $old_scan_filesystem_kernel_name = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_kernel_name};
my $old_scan_filesystem_mount_point = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_mount_point};
my $old_scan_filesystem_media_type = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_media_type};
my $old_scan_filesystem_size = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_size};
my $old_scan_filesystem_free = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_free};
# Have we seen this partition before?
if (exists $anvil->data->{sql}{scan_filesystems}{scan_filesystem_internal_uuid}{$filesystem_internal_uuid})
{
my $filesystem_uuid = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_internal_uuid}{$filesystem_internal_uuid}{filesystem_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { filesystem_uuid => $filesystem_uuid }});
# Note: We do not edit the description as the user may do so later in the WebUI
my $old_kernel_name = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_kernel_name};
my $old_type = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_type};
my $old_mount_point = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_mount_point};
my $old_transport = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_transport};
my $old_media_type = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_media_type};
my $old_vendor = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_vendor};
my $old_model = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_model};
my $old_serial_number = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_serial_number};
my $old_size = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_size};
my $old_used = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_used};
my $old_free = $old_size - $old_used;
my $old_free_percent = $anvil->Convert->round({number => ((($old_size - $old_used)/$old_size) * 100), places => 1});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_scan_filesystem_kernel_name => $old_scan_filesystem_kernel_name,
old_scan_filesystem_mount_point => $old_scan_filesystem_mount_point,
old_scan_filesystem_media_type => $old_scan_filesystem_media_type,
old_scan_filesystem_size => $anvil->Convert->add_commas({number => $old_scan_filesystem_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_filesystem_size}),
old_scan_filesystem_free => $anvil->Convert->add_commas({number => $old_scan_filesystem_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_filesystem_free}),
filesystem_uuid => $filesystem_uuid,
old_kernel_name => $old_kernel_name,
old_type => $old_type,
old_mount_point => $old_mount_point,
old_transport => $old_transport,
old_media_type => $old_media_type,
old_vendor => $old_vendor,
old_model => $old_model,
old_serial_number => $old_serial_number,
old_size => $anvil->Convert->add_commas({number => $old_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_size}),
old_used => $anvil->Convert->add_commas({number => $old_used})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_used}),
old_free => $anvil->Convert->add_commas({number => $old_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_free}),
old_free_percent => $old_free_percent,
}});
my $update = 0;
if ($scan_filesystem_kernel_name ne $old_scan_filesystem_kernel_name)
{
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($old_scan_filesystem_kernel_name eq "DELETED")
{
# A lost PV is back
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $scan_filesystem_kernel_name,
filesystem_internal_uuid => $filesystem_internal_uuid,
new_kernel_name => $new_kernel_name,
old_kernel_name => $old_kernel_name,
new_type => $new_type,
old_type => $old_type,
new_mount_point => $new_mount_point,
old_mount_point => $old_mount_point,
new_transport => $new_transport,
old_transport => $old_transport,
new_media_type => $new_media_type,
old_media_type => $old_media_type,
new_vendor => $new_vendor,
old_vendor => $old_vendor,
new_model => $new_model,
old_model => $old_model,
new_serial_number => $new_serial_number,
old_serial_number => $old_serial_number,
new_hr_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_size}),
old_hr_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_size}),
new_byte_size => $anvil->Convert->add_commas({number => $new_size}),
old_byte_size => $anvil->Convert->add_commas({number => $old_size}),
new_hr_used => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_used}),
old_hr_used => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_used}),
new_byte_used => $anvil->Convert->add_commas({number => $new_used}),
old_byte_used => $anvil->Convert->add_commas({number => $old_used}),
new_hr_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_free}),
old_hr_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_free}),
new_byte_free => $anvil->Convert->add_commas({number => $new_free}),
old_byte_free => $anvil->Convert->add_commas({number => $old_free}),
new_free_percent => $new_free_percent,
old_free_percent => $old_free_percent,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0001", variables => $variables});
$anvil->Alert->register({clear_alert => 1, alert_level => "warning", message => "scan_filesystem_alert_0001", variables => $variables, set_by => $THIS_FILE});
}
else
if ($new_kernel_name ne $old_kernel_name)
{
# Device (name) changed... This shouldn't normally happen.
my $variables = {
pv_uuid => $scan_filesystem_type,
new_name => $scan_filesystem_kernel_name,
old_name => $old_scan_filesystem_kernel_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0002", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_filesystem_alert_0002", variables => $variables, set_by => $THIS_FILE});
}
# Kernel device name changed.
$update = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0005", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0005",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
if ($scan_filesystem_mount_point ne $old_scan_filesystem_mount_point)
if ($new_type ne $old_type)
{
# If the old value was blank, then this PV was added to a VG and that's fine.
# File system type has changed. WAT?
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if (not $old_scan_filesystem_mount_point)
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0006", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0006",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
if ($new_mount_point ne $old_mount_point)
{
# Added to a VG
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $scan_filesystem_kernel_name,
vg_name => $scan_filesystem_mount_point,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0004", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_filesystem_alert_0004", variables => $variables, set_by => $THIS_FILE});
# Mount point has changed
$update = 1;
# Is this a returning filesystem?
if ($old_mount_point eq "REMOVED")
{
# Yup, returned
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0015", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0015",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
else
{
# The VG was probably renamed.
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $scan_filesystem_kernel_name,
new_vg_name => $scan_filesystem_mount_point,
old_vg_name => $old_scan_filesystem_mount_point,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0005", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_filesystem_alert_0005", variables => $variables, set_by => $THIS_FILE});
# Nope, it's a remount
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0007", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0007",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
}
if ($scan_filesystem_media_type ne $old_scan_filesystem_media_type)
if ($new_transport ne $old_transport)
{
# Attribute bits changed.
# Transport changed?! Could it be a dd to a new device?
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $scan_filesystem_kernel_name,
new_attributes => $scan_filesystem_media_type,
old_attributes => $old_scan_filesystem_media_type,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0006", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_filesystem_alert_0006", variables => $variables, set_by => $THIS_FILE});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0008", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0008",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
if ($scan_filesystem_size ne $old_scan_filesystem_size)
if ($new_media_type ne $old_media_type)
{
# PE size changed, likely grew.
# Media changed?! Could it be a dd to a new device?
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $scan_filesystem_kernel_name,
new_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_filesystem_size}),
new_size_bytes => $anvil->Convert->add_commas({number => $scan_filesystem_size}),
old_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_filesystem_size}),
old_size_bytes => $anvil->Convert->add_commas({number => $old_scan_filesystem_size}),
};
if ($scan_filesystem_size > $old_scan_filesystem_size)
{
# Yup
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0007", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_filesystem_alert_0007", variables => $variables, set_by => $THIS_FILE});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0009", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0009",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
else
if ($new_vendor ne $old_vendor)
{
# Uhhhh... We'll make this a warning as it shouldn't happen.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0008", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_filesystem_alert_0008", variables => $variables, set_by => $THIS_FILE});
}
# Vendor changed?! Could it be a dd to a new device?
$update = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0010", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0010",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
if ($scan_filesystem_free ne $old_scan_filesystem_free)
if ($new_model ne $old_model)
{
# PE size changed, likely shrunk.
# Model changed?! Could it be a dd to a new device?
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $scan_filesystem_kernel_name,
new_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_filesystem_free}),
new_free_bytes => $anvil->Convert->add_commas({number => $scan_filesystem_free}),
old_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_filesystem_free}),
old_free_bytes => $anvil->Convert->add_commas({number => $old_scan_filesystem_free}),
};
if ($scan_filesystem_free < $old_scan_filesystem_free)
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0011", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0011",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
if ($new_serial_number ne $old_serial_number)
{
# Yup
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0009", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_filesystem_alert_0009", variables => $variables, set_by => $THIS_FILE});
# Serial Number changed?! Could it be a dd to a new device?
$update = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0012", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0012",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
else
if ($new_size ne $old_size)
{
# Uhhhh... We'll make this a warning as it shouldn't happen.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0010", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_filesystem_alert_0010", variables => $variables, set_by => $THIS_FILE});
# Size changed, could be an LV resize or dd.
$update = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0013", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0013",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
if ($new_used ne $old_used)
{
# This is expected to nearly constantly change.
$update = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_filesystem_alert_0014", variables => $variables});
$anvil->Alert->register({
alert_level => "info",
message => "scan_filesystem_alert_0014",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($update)
{
# Save the changed.
my $query = "
UPDATE
scan_filesystems
SET
scan_filesystem_kernel_name = ".$anvil->Database->quote($scan_filesystem_kernel_name).",
scan_filesystem_mount_point = ".$anvil->Database->quote($scan_filesystem_mount_point).",
scan_filesystem_media_type = ".$anvil->Database->quote($scan_filesystem_media_type).",
scan_filesystem_size = ".$anvil->Database->quote($scan_filesystem_size).",
scan_filesystem_free = ".$anvil->Database->quote($scan_filesystem_free).",
scan_filesystem_type = ".$anvil->Database->quote($new_type).",
scan_filesystem_kernel_name = ".$anvil->Database->quote($new_kernel_name).",
scan_filesystem_mount_point = ".$anvil->Database->quote($new_mount_point).",
scan_filesystem_transport = ".$anvil->Database->quote($new_transport).",
scan_filesystem_media_type = ".$anvil->Database->quote($new_media_type).",
scan_filesystem_vendor = ".$anvil->Database->quote($new_vendor).",
scan_filesystem_model = ".$anvil->Database->quote($new_model).",
scan_filesystem_serial_number = ".$anvil->Database->quote($new_serial_number).",
scan_filesystem_description = ".$anvil->Database->quote($new_description).",
scan_filesystem_size = ".$anvil->Database->quote($new_size).",
scan_filesystem_used = ".$anvil->Database->quote($new_used).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
scan_filesystem_uuid = ".$anvil->Database->quote($scan_filesystem_uuid)."
scan_filesystem_uuid = ".$anvil->Database->quote($filesystem_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
}
# Delete the loaded entry so we can check for missing PVs later.
delete $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid};
# Delete the SQL entry so we can tell which disappeared.
delete $anvil->data->{sql}{scan_filesystems}{scan_filesystem_internal_uuid}{$filesystem_internal_uuid};
delete $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid};
}
else
{
# New PV
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $scan_filesystem_kernel_name,
vg_name => $scan_filesystem_mount_point ? $scan_filesystem_mount_point : "--",
attributes => $scan_filesystem_media_type,
pv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_filesystem_size}),
pv_size_bytes => $anvil->Convert->add_commas({number => $scan_filesystem_size}),
pv_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_filesystem_free}),
pv_free_bytes => $anvil->Convert->add_commas({number => $scan_filesystem_free}),
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0019", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_filesystem_alert_0019", variables => $variables, set_by => $THIS_FILE});
# It's new, add it.
my $scan_filesystem_uuid = $anvil->Get->uuid();
my $query = "
INSERT INTO
scan_filesystems
(
scan_filesystem_uuid,
scan_filesystem_type,
scan_filesystem_host_uuid,
scan_filesystem_internal_uuid,
scan_filesystem_type,
scan_filesystem_kernel_name,
scan_filesystem_mount_point,
scan_filesystem_transport,
scan_filesystem_media_type,
scan_filesystem_vendor,
scan_filesystem_model,
scan_filesystem_serial_number,
scan_filesystem_description,
scan_filesystem_size,
scan_filesystem_free,
scan_filesystem_used,
modified_date
) VALUES (
".$anvil->Database->quote($scan_filesystem_uuid).",
".$anvil->Database->quote($scan_filesystem_type).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_filesystem_kernel_name).",
".$anvil->Database->quote($scan_filesystem_mount_point).",
".$anvil->Database->quote($scan_filesystem_media_type).",
".$anvil->Database->quote($scan_filesystem_size).",
".$anvil->Database->quote($scan_filesystem_free).",
".$anvil->Database->quote($filesystem_internal_uuid).",
".$anvil->Database->quote($new_type).",
".$anvil->Database->quote($new_kernel_name).",
".$anvil->Database->quote($new_mount_point).",
".$anvil->Database->quote($new_transport).",
".$anvil->Database->quote($new_media_type).",
".$anvil->Database->quote($new_vendor).",
".$anvil->Database->quote($new_model).",
".$anvil->Database->quote($new_serial_number).",
".$anvil->Database->quote($new_description).",
".$anvil->Database->quote($new_size).",
".$anvil->Database->quote($new_used).",
".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
);";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
# Register the notice level alert.
my $variables = {
filesystem_internal_uuid => $filesystem_internal_uuid,
new_kernel_name => $new_kernel_name,
new_type => $new_type,
new_mount_point => $new_mount_point,
new_transport => $new_transport,
new_media_type => $new_media_type,
new_vendor => $new_vendor,
new_model => $new_model,
new_serial_number => $new_serial_number,
new_description => $new_description,
new_hr_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_size}),
new_byte_size => $anvil->Convert->add_commas({number => $new_size}),
new_hr_used => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_used}),
new_byte_used => $anvil->Convert->add_commas({number => $new_used}),
new_hr_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_free}),
new_byte_free => $anvil->Convert->add_commas({number => $new_free}),
new_free_percent => $new_free_percent,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0001", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0001",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
}
# Any missing PVs?
foreach my $scan_filesystem_type (keys %{$anvil->data->{sql}{scan_filesystems}{scan_filesystem_type}})
# Now that we know the partition is in the database; If the free percent is less than 5, set
# a warning alert. If it's less than 15%, set a notice alert. Otherwise, if the free space is
# greater than 25%, clear any existing warnings.
my $percent_free_warn = 5;
my $percent_free_notice = 15;
my $percent_free_clear = 25;
my $variables = {
filesystem_internal_uuid => $filesystem_internal_uuid,
new_kernel_name => $new_kernel_name,
new_type => $new_type,
new_mount_point => $new_mount_point,
new_hr_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_size}),
new_byte_size => $anvil->Convert->add_commas({number => $new_size}),
new_hr_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_free}),
new_byte_free => $anvil->Convert->add_commas({number => $new_free}),
new_free_percent => $new_free_percent,
};
if ($new_free_percent < $percent_free_warn)
{
# This one is missing.
my $scan_filesystem_uuid = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_uuid};
my $old_scan_filesystem_kernel_name = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_kernel_name};
# See if we've warned the user.
my $changed = $anvil->Alert->check_alert_sent({
clear => 0,
record_locator => $filesystem_internal_uuid.":very_low_space",
set_by => $THIS_FILE,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
# First time we've fallen under 5%
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0002", variables => $variables});
$anvil->Alert->register({
alert_level => "warning",
message => "scan_filesystem_alert_0002",
sort_position => 1,
variables => $variables,
set_by => $THIS_FILE,
});
}
}
elsif ($new_free_percent < $percent_free_notice)
{
# Send the low space notice, if needed.
my $changed = $anvil->Alert->check_alert_sent({
clear => 0,
record_locator => $filesystem_internal_uuid.":low_space",
set_by => $THIS_FILE,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }});
if ($changed)
{
# First time we've fallen under 5%
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0003", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_filesystem_alert_0003",
sort_position => 1,
variables => $variables,
set_by => $THIS_FILE,
});
}
}
elsif ($new_free_percent < $percent_free_clear)
{
# Send the low space cleared message, if needed.
my $very_low_changed = $anvil->Alert->check_alert_sent({
clear => 1,
record_locator => $filesystem_internal_uuid.":very_low_space",
set_by => $THIS_FILE,
});
my $low_changed = $anvil->Alert->check_alert_sent({
clear => 1,
record_locator => $filesystem_internal_uuid.":low_space",
set_by => $THIS_FILE,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:scan_filesystem_type' => $scan_filesystem_type,
's2:scan_filesystem_uuid' => $scan_filesystem_uuid,
's3:old_scan_filesystem_kernel_name' => $old_scan_filesystem_kernel_name,
very_low_changed => $very_low_changed,
low_changed => $low_changed,
}});
next if $old_scan_filesystem_kernel_name eq "DELETED";
if (($very_low_changed) or ($low_changed))
{
# Clear the alert
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0004", variables => $variables});
$anvil->Alert->register({
alert_level => $very_low_changed ? "warning" : "notice",
clear_alert => 1,
message => "scan_filesystem_alert_0004",
sort_position => 1,
variables => $variables,
set_by => $THIS_FILE,
});
}
}
}
# Register an alert
my $variables = {
pv_uuid => $scan_filesystem_type,
pv_name => $old_scan_filesystem_kernel_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0003", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_filesystem_alert_0003", variables => $variables, set_by => $THIS_FILE});
# Look now for lost file systems.
foreach my $filesystem_uuid (keys %{$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}})
{
# Is this one we already know has left?
next if $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_mount_point} eq "REMOVED";
my $old_kernel_name = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_kernel_name};
my $old_type = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_type};
my $old_mount_point = $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$filesystem_uuid}{scan_filesystem_mount_point};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
filesystem_uuid => $filesystem_uuid,
old_kernel_name => $old_kernel_name,
old_type => $old_type,
old_mount_point => $old_mount_point,
}});
# Update it PV name to be 'DELTED'
my $query = "
UPDATE
scan_filesystems
SET
scan_filesystem_kernel_name = 'DELETED',
scan_filesystem_mount_point = 'REMOVED',
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
scan_filesystem_uuid = ".$anvil->Database->quote($scan_filesystem_uuid)."
scan_filesystem_uuid = ".$anvil->Database->quote($filesystem_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
my $update = 0;
my $variables = {
old_kernel_name => $old_kernel_name,
old_type => $old_type,
old_mount_point => $old_mount_point,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_filesystem_alert_0016", variables => $variables});
$anvil->Alert->register({
alert_level => "info",
message => "scan_filesystem_alert_0016",
sort_position => $anvil->data->{'scan-filesystems'}{alert_sort}++,
variables => $variables,
set_by => $THIS_FILE,
});
}
=cut
return(0);
}
@ -379,7 +615,7 @@ sub read_last_scan
my $query = "
SELECT
scan_filesystem_uuid,
scan_filesystem_host_uuid,
scan_filesystem_internal_uuid,
scan_filesystem_type,
scan_filesystem_kernel_name,
scan_filesystem_mount_point,
@ -393,6 +629,8 @@ SELECT
scan_filesystem_used
FROM
scan_filesystems
WHERE
scan_filesystem_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
@ -407,7 +645,8 @@ FROM
# We've got an entry in the 'scan_filesystems' table, so now we'll look for data in the node and
# services tables.
my $scan_filesystem_uuid = $row->[0];
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_host_uuid} = $row->[1];
my $scan_filesystem_internal_uuid = $row->[1];
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_internal_uuid} = $scan_filesystem_internal_uuid;
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_type} = $row->[2];
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_kernel_name} = $row->[3];
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_mount_point} = $row->[4];
@ -419,8 +658,9 @@ FROM
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_description} = $row->[10];
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_size} = $row->[11];
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_used} = $row->[12];
$anvil->data->{sql}{scan_filesystems}{scan_filesystem_internal_uuid}{$scan_filesystem_internal_uuid}{filesystem_uuid} = $scan_filesystem_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_uuid" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_uuid},
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_internal_uuid" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_internal_uuid},
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_kernel_name" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_kernel_name},
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_mount_point" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_mount_point},
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_transport" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_transport},
@ -431,7 +671,7 @@ FROM
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_description" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_description},
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_size" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_size}}),
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_used" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_used}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_used}}),
"sql::scan_filesystems::scan_filesystem_uuid::${scan_filesystem_uuid}::scan_filesystem_host_uuid" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_uuid}{$scan_filesystem_uuid}{scan_filesystem_host_uuid},
"sql::scan_filesystems::scan_filesystem_internal_uuid::${scan_filesystem_internal_uuid}::filesystem_uuid" => $anvil->data->{sql}{scan_filesystems}{scan_filesystem_internal_uuid}{$scan_filesystem_internal_uuid}{filesystem_uuid},
}});
}
@ -443,24 +683,28 @@ sub collect_data
my ($anvil) = @_;
### NOTE: If a drive is unmounted, we can't trust the sizes.
$anvil->Storage->parse_lsblk({debug => 2});
$anvil->Storage->parse_df({debug => 2});
$anvil->Storage->parse_lsblk({debug => 3});
$anvil->Storage->parse_df({debug => 3});
foreach my $kernel_device_name (sort {$a cmp $b} keys %{$anvil->{storage}{lsblk}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { kernel_device_name => $kernel_device_name }});
if ($anvil->{storage}{lsblk}{$kernel_device_name}{type} eq "partition")
{
$anvil->data->{new}{partition}{$kernel_device_name}{type} = $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_type};
$anvil->data->{new}{partition}{$kernel_device_name}{mount_point} = $anvil->{storage}{lsblk}{$kernel_device_name}{mount_point};
$anvil->data->{new}{partition}{$kernel_device_name}{transport} = $anvil->{storage}{lsblk}{$kernel_device_name}{transport};
$anvil->data->{new}{partition}{$kernel_device_name}{media_type} = $anvil->{storage}{lsblk}{$kernel_device_name}{rotating_drive} ? "platter" : "solid_state"; # This could be network as well someday
$anvil->data->{new}{partition}{$kernel_device_name}{vendor} = $anvil->{storage}{lsblk}{$kernel_device_name}{vendor};
$anvil->data->{new}{partition}{$kernel_device_name}{model} = $anvil->{storage}{lsblk}{$kernel_device_name}{model};
$anvil->data->{new}{partition}{$kernel_device_name}{serial_number} = $anvil->{storage}{lsblk}{$kernel_device_name}{serial_number};
$anvil->data->{new}{partition}{$kernel_device_name}{description} = $anvil->{storage}{lsblk}{$kernel_device_name}{partition_label};
$anvil->data->{new}{partition}{$kernel_device_name}{size} = 0;
$anvil->data->{new}{partition}{$kernel_device_name}{used} = 0;
if (($anvil->data->{new}{partition}{$kernel_device_name}{mount_point}) && (exists $anvil->{storage}{df}{$kernel_device_name}))
my $filesystem_internal_uuid = $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_internal_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { filesystem_internal_uuid => $filesystem_internal_uuid }});
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{kernel_name} = $kernel_device_name;
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{type} = $anvil->{storage}{lsblk}{$kernel_device_name}{filesystem_type};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{mount_point} = $anvil->{storage}{lsblk}{$kernel_device_name}{mount_point};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{transport} = $anvil->{storage}{lsblk}{$kernel_device_name}{transport};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{media_type} = $anvil->{storage}{lsblk}{$kernel_device_name}{rotating_drive} ? "platter" : "solid_state"; # This could be network as well someday
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{vendor} = $anvil->{storage}{lsblk}{$kernel_device_name}{vendor};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{model} = $anvil->{storage}{lsblk}{$kernel_device_name}{model};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{serial_number} = $anvil->{storage}{lsblk}{$kernel_device_name}{serial_number};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{description} = $anvil->{storage}{lsblk}{$kernel_device_name}{partition_label};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{size} = $anvil->{storage}{lsblk}{$kernel_device_name}{size};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{used} = 0;
if (($anvil->data->{new}{partition}{$filesystem_internal_uuid}{mount_point}) && (exists $anvil->{storage}{df}{$kernel_device_name}))
{
# Look for space usage from 'df'
my $df_mount_point = $anvil->{storage}{df}{$kernel_device_name}{mount_point};
@ -478,9 +722,9 @@ sub collect_data
# This is a check to see if the calculated free space matches the reported free
# space.
$anvil->data->{new}{partition}{$kernel_device_name}{size} = $df_size;
$anvil->data->{new}{partition}{$kernel_device_name}{used} = $df_used;
my $calculated_free = $anvil->data->{new}{partition}{$kernel_device_name}{size} - $anvil->data->{new}{partition}{$kernel_device_name}{used};
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{size} = $df_size;
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{used} = $df_used;
my $calculated_free = $anvil->data->{new}{partition}{$filesystem_internal_uuid}{size} - $anvil->data->{new}{partition}{$filesystem_internal_uuid}{used};
my $difference = $df_free - $calculated_free;
$difference =~ s/^-//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
@ -489,18 +733,45 @@ sub collect_data
}});
}
# If this is swap, there won't be any information from 'df', so get the used space
# from swapon.
if ($anvil->{storage}{lsblk}{$kernel_device_name}{mount_point} eq "<swap>")
{
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{swapon}." --show=UUID,USED --bytes --noheadings"});
$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 ($line =~ /^$filesystem_internal_uuid (\d+)$/)
{
$anvil->data->{new}{partition}{$filesystem_internal_uuid}{used} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"new::partition::${filesystem_internal_uuid}::used" => $anvil->Convert->add_commas({number => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{used}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{used}}).")"
}});
last;
}
}
}
# Record the partition
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:new::partition::${kernel_device_name}::type" => $anvil->data->{new}{partition}{$kernel_device_name}{type},
"s2:new::partition::${kernel_device_name}::mount_point" => $anvil->data->{new}{partition}{$kernel_device_name}{mount_point},
"s3:new::partition::${kernel_device_name}::transport" => $anvil->data->{new}{partition}{$kernel_device_name}{transport},
"s4:new::partition::${kernel_device_name}::media_type" => $anvil->data->{new}{partition}{$kernel_device_name}{media_type},
"s5:new::partition::${kernel_device_name}::vendor" => $anvil->data->{new}{partition}{$kernel_device_name}{vendor},
"s6:new::partition::${kernel_device_name}::model" => $anvil->data->{new}{partition}{$kernel_device_name}{model},
"s7:new::partition::${kernel_device_name}::serial_number" => $anvil->data->{new}{partition}{$kernel_device_name}{serial_number},
"s8:new::partition::${kernel_device_name}::description" => $anvil->data->{new}{partition}{$kernel_device_name}{description},
"s9:new::partition::${kernel_device_name}::size" => $anvil->Convert->add_commas({number => $anvil->data->{new}{partition}{$kernel_device_name}{size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{partition}{$kernel_device_name}{size}}).")",
"s10:new::partition::${kernel_device_name}::used" => $anvil->Convert->add_commas({number => $anvil->data->{new}{partition}{$kernel_device_name}{used}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{partition}{$kernel_device_name}{used}}).")",
"s1:new::partition::${filesystem_internal_uuid}::kernel_name" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{kernel_name},
"s2:new::partition::${filesystem_internal_uuid}::type" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{type},
"s3:new::partition::${filesystem_internal_uuid}::mount_point" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{mount_point},
"s4:new::partition::${filesystem_internal_uuid}::transport" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{transport},
"s5:new::partition::${filesystem_internal_uuid}::media_type" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{media_type},
"s6:new::partition::${filesystem_internal_uuid}::vendor" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{vendor},
"s7:new::partition::${filesystem_internal_uuid}::model" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{model},
"s8:new::partition::${filesystem_internal_uuid}::serial_number" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{serial_number},
"s9:new::partition::${filesystem_internal_uuid}::description" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{description},
"s10:new::partition::${filesystem_internal_uuid}::filesystem_internal_uuid" => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{filesystem_internal_uuid},
"s10:new::partition::${filesystem_internal_uuid}::size" => $anvil->Convert->add_commas({number => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{size}}).")",
"s11:new::partition::${filesystem_internal_uuid}::used" => $anvil->Convert->add_commas({number => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{used}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{partition}{$filesystem_internal_uuid}{used}}).")",
}});
}
}

@ -3,8 +3,9 @@
-- This table stores physical volume information
CREATE TABLE scan_filesystems (
scan_filesystem_uuid uuid primary key, -- This comes from the file system's UUID
scan_filesystem_uuid uuid primary key,
scan_filesystem_host_uuid uuid not null, -- The host that the file system is mounted on. Note that some FSes, like those from USB, can move between hosts.
scan_filesystem_internal_uuid text not null, -- This comes from the file system's UUID, which is not actually always a UUID.
scan_filesystem_type text not null, -- This is the name of the file system type.
scan_filesystem_kernel_name text not null, -- This is the backing device of the file system.
scan_filesystem_mount_point text not null, -- This is the name of the mount point.
@ -26,6 +27,7 @@ CREATE TABLE history.scan_filesystems (
history_id bigserial,
scan_filesystem_uuid uuid,
scan_filesystem_host_uuid uuid,
scan_filesystem_internal_uuid text,
scan_filesystem_type text,
scan_filesystem_kernel_name text,
scan_filesystem_mount_point text,
@ -50,6 +52,7 @@ BEGIN
INSERT INTO history.scan_filesystems
(scan_filesystem_uuid,
scan_filesystem_host_uuid,
scan_filesystem_internal_uuid,
scan_filesystem_type,
scan_filesystem_kernel_name,
scan_filesystem_mount_point,
@ -65,6 +68,7 @@ BEGIN
VALUES
(history_scan_filesystems.scan_filesystem_uuid,
history_scan_filesystems.scan_filesystem_host_uuid,
history_scan_filesystems.scan_filesystem_internal_uuid,
history_scan_filesystems.scan_filesystem_type,
history_scan_filesystems.scan_filesystem_kernel_name,
history_scan_filesystems.scan_filesystem_mount_point,

@ -14,7 +14,39 @@ NOTE: All string keys MUST be prefixed with the agent name! ie: 'scan_filesystem
<language name="en_CA" long_name="Canadian English" description="ScanCore scan agent that monitors file systems and the devices backing them.">
<!-- Alert entries -->
<key name="scan_filesystem_alert_0001"></key>
<key name="scan_filesystem_alert_0001">A new partition was found!
- Kernel device path: [#!variable!new_kernel_name!#]
- Filesystem UUID: .. [#!variable!filesystem_uuid!#]
- Filesystem type: .. [#!variable!new_type!#]
- Mount point: ...... [#!variable!new_mount_point!#]
- Transport (bus): .. [#!variable!new_transport!#]
- Media type: ....... [#!variable!new_media_type!#]
- Device vendor: .... [#!variable!new_vendor!#]
- Device model: ..... [#!variable!new_model!#]
- Serial Number: .... [#!variable!new_serial_number!#]
- Description: ...... [#!variable!new_description!#]
- Size: ............. [#!variable!new_hr_size!#] (#!variable!new_byte_size!# bytes)
- Used: ............. [#!variable!new_hr_used!#] (#!variable!new_byte_used!# bytes)
- Free: ............. [#!variable!new_hr_free!#] (#!variable!new_free_percent!#% / #!variable!new_byte_free!# bytes)
</key>
<key name="scan_filesystem_alert_0002">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] at the mount point: [#!variable!new_mount_point!#] (UUID: [#!variable!filesystem_uuid!#]) is very low on space! There is only: [#!variable!new_hr_free!#] (#!variable!new_free_percent!#%) out of: [#!variable!new_hr_size!#] left free!</key>
<key name="scan_filesystem_alert_0003">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] at the mount point: [#!variable!new_mount_point!#] (UUID: [#!variable!filesystem_uuid!#]) is getting low on space. There is: [#!variable!new_hr_free!#] (#!variable!new_free_percent!#%) out of: [#!variable!new_hr_size!#] left free.</key>
<key name="scan_filesystem_alert_0004">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] at the mount point: [#!variable!new_mount_point!#] (UUID: [#!variable!filesystem_uuid!#]) is no longer low on space. There is now: [#!variable!new_hr_free!#] (#!variable!new_free_percent!#%) out of: [#!variable!new_hr_size!#] free.</key>
<key name="scan_filesystem_alert_0005">The: [#!variable!new_type!#] file system's kernel device name has changed from: [#!variable!old_kernel_name!#] to: [#!variable!new_kernel_name!#].</key>
<key name="scan_filesystem_alert_0006">The: [#!variable!old_type!#] file system: [#!variable!new_kernel_name!#] has somehow changed to be of the filesystem type: [#!variable!new_type!#]. This is unexpected.</key>
<key name="scan_filesystem_alert_0007">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] mount point has changed from: [#!variable!old_mount_point!#] to: [#!variable!new_kernel_name!#].</key>
<key name="scan_filesystem_alert_0008">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] transport has changed from: [#!variable!old_transport!#] to: [#!variable!new_transport!#]. Was the file system cloned to a new device?</key>
<key name="scan_filesystem_alert_0009">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] media type has changed from: [#!variable!old_media_type!#] to: [#!variable!new_media_type!#]. Was the file system cloned to a new device?</key>
<key name="scan_filesystem_alert_0010">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] vendor has changed from: [#!variable!old_vendor!#] to: [#!variable!new_vendor!#]. Was the file system cloned to a new device?</key>
<key name="scan_filesystem_alert_0011">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] model has changed from: [#!variable!old_model!#] to: [#!variable!new_model!#]. Was the file system cloned to a new device?</key>
<key name="scan_filesystem_alert_0012">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] model has changed from: [#!variable!old_serial_number!#] to: [#!variable!new_serial_number!#]. Was the file system cloned to a new device?</key>
<key name="scan_filesystem_alert_0013">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] size has changed from: [#!variable!old_hr_size!#] (#!variable!old_byte_size!# bytes) to: [#!variable!new_hr_size!#] (#!variable!new_byte_size!# bytes). Was the file system resized or cloned to a new device?</key>
<key name="scan_filesystem_alert_0014">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] used / free space has changed (this is expected to change almost constantly);
From: [#!variable!old_hr_used!#] (#!variable!old_byte_used!# bytes) used, [#!variable!old_hr_free!#] (#!variable!old_free_percent!#% / #!variable!old_byte_free!# bytes) free
To: . [#!variable!new_hr_used!#] (#!variable!new_byte_used!# bytes) used, [#!variable!new_hr_free!#] (#!variable!new_free_percent!#% / #!variable!new_byte_free!# bytes) free
</key>
<key name="scan_filesystem_alert_0015">The: [#!variable!new_type!#] file system: [#!variable!new_kernel_name!#] that was removed is back and mounted at: [#!variable!new_mount_point!#].</key>
<key name="scan_filesystem_alert_0016">The: [#!variable!old_type!#] file system: [#!variable!old_kernel_name!#] mounted at: [#!variable!old_mount_point!#] has been removed or unplugged.</key>
<!-- Log entries -->
<key name="scan_filesystem_log_0001">Starting: [#!variable!program!#].</key>

@ -10,6 +10,8 @@
#
# TODO:
# - Finish System->parse_lwhw(), lots of good stuff in there.
# - We can figure out what is using swap with:
# - for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB
#
use strict;

Loading…
Cancel
Save