Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1449 lines
78 KiB

#!/usr/bin/perl
#
# This scans the LVM (logical volume management) components (PV, VG and LV).
#
# Examples;
#
# Exit codes;
# 0 = Normal exit.
# 1 = Startup failure (not running as root, no DB, bad file read, etc)
#
# NOTE:
# - LVM created UUIDs before RFC 4122, so the internal UUIDs are incompatible with modern UUIDs. As such,
# they are treated as more of a "serial number" in this agent.
#
# TODO:
# -
#
use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use JSON;
# 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});
}
# These are the threasholds for when to alert when swap is running out.
$anvil->data->{scancore}{'scan-lvm'}{disable} = 0;
$anvil->data->{switches}{force} = 0;
$anvil->Storage->read_config();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches
$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});
}
# Find the block devices on this host.
collect_data($anvil);
# Load stored data.
read_last_scan($anvil);
# Loog for changes
find_changes($anvil);
# Check storage for storage groups.
check_storage_groups($anvil);
# Shut down.
$anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Functions #
#############################################################################################################
sub check_storage_groups
{
my ($anvil) = @_;
# Are we in an Anvil!? If so, are there any storage groups yet?
my $anvil_uuid = $anvil->Cluster->get_anvil_uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
if ($anvil_uuid)
{
# If we're node 1, we'll try to assemble the storage group. Onle node 1 does this to help avoid race
# conditions. This both loads storage group data and assembles ungrouped VGs into storage groups,
# when possible.
$anvil->Database->get_anvils();
my $host_uuid = $anvil->Get->host_uuid;
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:anvil_name' => $anvil_name,
's2:node1_host_uuid' => $node1_host_uuid,
's3:node2_host_uuid' => $node2_host_uuid,
's4:host_uuid' => $host_uuid,
}});
if ($host_uuid eq $node1_host_uuid)
{
# Are there any storage groups yet? If not, try to assemble one.
my $query = "SELECT COUNT(*) FROM storage_groups WHERE storage_group_anvil_uuid = ".$anvil->Database->quote($anvil_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
$anvil->Cluster->assemble_storage_groups({
debug => 2,
anvil_uuid => $anvil_uuid,
});
}
}
}
return(0);
}
sub find_changes
{
my ($anvil) = @_;
# Changes in PVs?
find_changes_in_pvs($anvil);
# Changes in VGs?
find_changes_in_vgs($anvil);
# Changes in LVs?
find_changes_in_lvs($anvil);
return(0);
}
sub find_changes_in_lvs
{
my ($anvil) = @_;
foreach my $scan_lvm_lv_internal_uuid (keys %{$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}})
{
my $scan_lvm_lv_name = $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{name};
my $scan_lvm_lv_attributes = $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{attributes};
my $scan_lvm_lv_on_vg = $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_vg};
my $scan_lvm_lv_size = $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{size};
my $scan_lvm_lv_path = $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{device_path};
my $scan_lvm_lv_on_pvs = $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_pvs};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_lv_internal_uuid => $scan_lvm_lv_internal_uuid,
scan_lvm_lv_name => $scan_lvm_lv_name,
scan_lvm_lv_attributes => $scan_lvm_lv_attributes,
scan_lvm_lv_on_vg => $scan_lvm_lv_on_vg,
scan_lvm_lv_size => $anvil->Convert->add_commas({number => $scan_lvm_lv_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_lv_size}),
scan_lvm_lv_path => $scan_lvm_lv_path,
scan_lvm_lv_on_pvs => $scan_lvm_lv_on_pvs,
}});
# Have we seen this before?
if (exists $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid})
{
# Yup, anything changed?
my $scan_lvm_lv_uuid = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_uuid};
my $old_scan_lvm_lv_name = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_name};
my $old_scan_lvm_lv_attributes = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_attributes};
my $old_scan_lvm_lv_on_vg = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_vg};
my $old_scan_lvm_lv_size = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_size};
my $old_scan_lvm_lv_path = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_path};
my $old_scan_lvm_lv_on_pvs = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_pvs};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_lv_uuid => $scan_lvm_lv_uuid,
old_scan_lvm_lv_name => $old_scan_lvm_lv_name,
old_scan_lvm_lv_attributes => $old_scan_lvm_lv_attributes,
old_scan_lvm_lv_on_vg => $old_scan_lvm_lv_on_vg,
old_scan_lvm_lv_size => $anvil->Convert->add_commas({number => $old_scan_lvm_lv_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_lv_size}),
old_scan_lvm_lv_path => $old_scan_lvm_lv_path,
old_scan_lvm_lv_on_pvs => $old_scan_lvm_lv_on_pvs,
}});
my $update = 0;
if ($scan_lvm_lv_name ne $old_scan_lvm_lv_name)
{
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($old_scan_lvm_lv_name eq "DELETED")
{
# A lost LV is back
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $scan_lvm_lv_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0021", variables => $variables});
$anvil->Alert->register({clear_alert => 1, alert_level => "warning", message => "scan_lvm_alert_0021", variables => $variables, set_by => $THIS_FILE});
}
else
{
# LV name changed.
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
new_lv_name => $scan_lvm_lv_name,
old_lv_name => $old_scan_lvm_lv_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0022", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0022", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_lv_attributes ne $old_scan_lvm_lv_attributes)
{
# Attribute bits changed.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $scan_lvm_lv_name,
new_attributes => $scan_lvm_lv_attributes,
old_attributes => $old_scan_lvm_lv_attributes,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0023", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0023", variables => $variables, set_by => $THIS_FILE});
}
if ($scan_lvm_lv_on_vg ne $old_scan_lvm_lv_on_vg)
{
# This happens when an VG is renamed.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $scan_lvm_lv_name,
new_lv_on_vg => $scan_lvm_lv_on_vg,
old_lv_on_vg => $old_scan_lvm_lv_on_vg,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0024", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0024", variables => $variables, set_by => $THIS_FILE});
}
if ($scan_lvm_lv_size ne $old_scan_lvm_lv_size)
{
# VG size change; Did it grow or shrink?
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $scan_lvm_lv_name,
new_lv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_lv_size}),
new_lv_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_lv_size}),
old_lv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_lv_size}),
old_lv_size_bytes => $anvil->Convert->add_commas({number => $old_scan_lvm_lv_size}),
};
if ($scan_lvm_lv_size > $old_scan_lvm_lv_size)
{
# Grew, probably added a new PV
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0025", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0025", variables => $variables, set_by => $THIS_FILE});
}
else
{
# Shrank,
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0026", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0026", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_lv_path ne $old_scan_lvm_lv_path)
{
# VG size changed, Grows when an LV is removed, shrings when an existing LV is extended or a new LV is created.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $scan_lvm_lv_name,
new_lv_path => $scan_lvm_lv_path,
old_lv_path => $old_scan_lvm_lv_path,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0027", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0027", variables => $variables, set_by => $THIS_FILE});
}
if ($scan_lvm_lv_on_pvs ne $old_scan_lvm_lv_on_pvs)
{
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $scan_lvm_lv_name,
new_lv_on_pvs => $scan_lvm_lv_path,
old_lv_on_pvs => $old_scan_lvm_lv_path,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0028", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0028", variables => $variables, set_by => $THIS_FILE});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($update)
{
my $query = "
UPDATE
scan_lvm_lvs
SET
scan_lvm_lv_name = ".$anvil->Database->quote($scan_lvm_lv_name).",
scan_lvm_lv_attributes = ".$anvil->Database->quote($scan_lvm_lv_attributes).",
scan_lvm_lv_on_vg = ".$anvil->Database->quote($scan_lvm_lv_on_vg).",
scan_lvm_lv_size = ".$anvil->Database->quote($scan_lvm_lv_size).",
scan_lvm_lv_path = ".$anvil->Database->quote($scan_lvm_lv_path).",
scan_lvm_lv_on_pvs = ".$anvil->Database->quote($scan_lvm_lv_on_pvs).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_lvm_lv_uuid = ".$anvil->Database->quote($scan_lvm_lv_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_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid};
}
else
{
# New VG
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $scan_lvm_lv_name,
attributes => $scan_lvm_lv_attributes,
lv_on_vg => $scan_lvm_lv_on_vg,
lv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_lv_size}),
lv_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_lv_size}),
lv_path => $scan_lvm_lv_path,
lv_on_pvs => $scan_lvm_lv_on_pvs,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0029", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0029", variables => $variables, set_by => $THIS_FILE});
my $scan_lvm_lv_uuid = $anvil->Get->uuid();
my $query = "
INSERT INTO
scan_lvm_lvs
(
scan_lvm_lv_uuid,
scan_lvm_lv_internal_uuid,
scan_lvm_lv_host_uuid,
scan_lvm_lv_name,
scan_lvm_lv_on_vg,
scan_lvm_lv_attributes,
scan_lvm_lv_size,
scan_lvm_lv_path,
scan_lvm_lv_on_pvs,
modified_date
) VALUES (
".$anvil->Database->quote($scan_lvm_lv_uuid).",
".$anvil->Database->quote($scan_lvm_lv_internal_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_lvm_lv_name).",
".$anvil->Database->quote($scan_lvm_lv_on_vg).",
".$anvil->Database->quote($scan_lvm_lv_attributes).",
".$anvil->Database->quote($scan_lvm_lv_size).",
".$anvil->Database->quote($scan_lvm_lv_path).",
".$anvil->Database->quote($scan_lvm_lv_on_pvs).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
}
}
# Any missing LVs?
foreach my $scan_lvm_lv_internal_uuid (keys %{$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}})
{
# This one is missing.
my $scan_lvm_lv_uuid = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_uuid};
my $old_scan_lvm_lv_name = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_lv_uuid => $scan_lvm_lv_uuid,
old_scan_lvm_lv_name => $old_scan_lvm_lv_name,
}});
next if $old_scan_lvm_lv_name eq "DELETED";
# Register an alert
my $variables = {
lv_uuid => $scan_lvm_lv_internal_uuid,
lv_name => $old_scan_lvm_lv_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0031", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0031", variables => $variables, set_by => $THIS_FILE});
# Update it PV name to be 'DELTED'
my $query = "
UPDATE
scan_lvm_lvs
SET
scan_lvm_lv_name = 'DELETED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_lvm_lv_uuid = ".$anvil->Database->quote($scan_lvm_lv_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);
}
sub find_changes_in_vgs
{
my ($anvil) = @_;
foreach my $scan_lvm_vg_internal_uuid (keys %{$anvil->data->{lvm}{scan_lvm_vg_internal_uuid}})
{
my $scan_lvm_vg_name = $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{name};
my $scan_lvm_vg_attributes = $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{attributes};
my $scan_lvm_vg_extent_size = $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{extent_size};
my $scan_lvm_vg_size = $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{size};
my $scan_lvm_vg_free = $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{free_space};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_vg_internal_uuid => $scan_lvm_vg_internal_uuid,
scan_lvm_vg_name => $scan_lvm_vg_name,
scan_lvm_vg_attributes => $scan_lvm_vg_attributes,
scan_lvm_vg_extent_size => $anvil->Convert->add_commas({number => $scan_lvm_vg_extent_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_extent_size}),
scan_lvm_vg_size => $anvil->Convert->add_commas({number => $scan_lvm_vg_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size}),
scan_lvm_vg_free => $anvil->Convert->add_commas({number => $scan_lvm_vg_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_free}),
}});
# Have we seen this before?
if (exists $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid})
{
# Yup, anything changed?
my $scan_lvm_vg_uuid = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_uuid};
my $old_scan_lvm_vg_name = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_name};
my $old_scan_lvm_vg_attributes = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_attributes};
my $old_scan_lvm_vg_extent_size = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_extent_size};
my $old_scan_lvm_vg_size = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_size};
my $old_scan_lvm_vg_free = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_free};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_vg_uuid => $scan_lvm_vg_uuid,
old_scan_lvm_vg_name => $old_scan_lvm_vg_name,
old_scan_lvm_vg_attributes => $old_scan_lvm_vg_attributes,
old_scan_lvm_vg_extent_size => $anvil->Convert->add_commas({number => $old_scan_lvm_vg_extent_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_vg_extent_size}),,
old_scan_lvm_vg_size => $anvil->Convert->add_commas({number => $old_scan_lvm_vg_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_vg_size}),
old_scan_lvm_vg_free => $anvil->Convert->add_commas({number => $old_scan_lvm_vg_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_vg_free}),
}});
my $update = 0;
if ($scan_lvm_vg_name ne $old_scan_lvm_vg_name)
{
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($old_scan_lvm_vg_name eq "DELETED")
{
# A lost PV is back
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
vg_name => $scan_lvm_vg_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0011", variables => $variables});
$anvil->Alert->register({clear_alert => 1, alert_level => "warning", message => "scan_lvm_alert_0011", variables => $variables, set_by => $THIS_FILE});
}
else
{
# Device (name) changed... This can happen if the vg was renamed
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
new_vg_name => $scan_lvm_vg_name,
old_vg_name => $old_scan_lvm_vg_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0012", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0012", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_vg_attributes ne $old_scan_lvm_vg_attributes)
{
# Attribute bits changed.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
vg_name => $scan_lvm_vg_name,
new_attributes => $scan_lvm_vg_attributes,
old_attributes => $old_scan_lvm_vg_attributes,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0013", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0013", variables => $variables, set_by => $THIS_FILE});
}
if ($scan_lvm_vg_extent_size ne $old_scan_lvm_vg_extent_size)
{
# This should never happen...
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
vg_name => $scan_lvm_vg_name,
new_vg_extent_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_extent_size}),
new_vg_extent_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_vg_extent_size}),
old_vg_extent_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_vg_extent_size}),
old_vg_extent_size_bytes => $anvil->Convert->add_commas({number => $old_scan_lvm_vg_extent_size}),
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0014", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0014", variables => $variables, set_by => $THIS_FILE});
}
if ($scan_lvm_vg_size ne $old_scan_lvm_vg_size)
{
# VG size change; Did it grow or shrink?
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
vg_name => $scan_lvm_vg_name,
new_vg_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size}),
new_vg_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_vg_size}),
old_vg_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_vg_size}),
old_vg_size_bytes => $anvil->Convert->add_commas({number => $old_scan_lvm_vg_size}),
};
if ($scan_lvm_vg_size > $old_scan_lvm_vg_size)
{
# Grew, probably added a new PV
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0015", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0015", variables => $variables, set_by => $THIS_FILE});
}
else
{
# Shrank, wat?
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0016", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0016", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_vg_free ne $old_scan_lvm_vg_free)
{
# VG size changed, Grows when an LV is removed, shrings when an existing LV is extended or a new LV is created.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
vg_name => $scan_lvm_vg_name,
new_vg_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_free}),
new_vg_free_bytes => $anvil->Convert->add_commas({number => $scan_lvm_vg_free}),
old_vg_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_vg_free}),
old_vg_free_bytes => $anvil->Convert->add_commas({number => $old_scan_lvm_vg_free}),
};
if ($scan_lvm_vg_free < $old_scan_lvm_vg_free)
{
# Likely a new LV was created or an existing one was extended.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0017", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0017", variables => $variables, set_by => $THIS_FILE});
}
else
{
# An old LV was probably removed.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0018", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0018", variables => $variables, set_by => $THIS_FILE});
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($update)
{
my $query = "
UPDATE
scan_lvm_vgs
SET
scan_lvm_vg_name = ".$anvil->Database->quote($scan_lvm_vg_name).",
scan_lvm_vg_attributes = ".$anvil->Database->quote($scan_lvm_vg_attributes).",
scan_lvm_vg_extent_size = ".$anvil->Database->quote($scan_lvm_vg_extent_size).",
scan_lvm_vg_size = ".$anvil->Database->quote($scan_lvm_vg_size).",
scan_lvm_vg_free = ".$anvil->Database->quote($scan_lvm_vg_free).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_lvm_vg_uuid = ".$anvil->Database->quote($scan_lvm_vg_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_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid};
}
else
{
# New VG
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
vg_name => $scan_lvm_vg_name,
attributes => $scan_lvm_vg_attributes,
extent_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_extent_size}),
extent_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_vg_extent_size}),
vg_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_size}),
vg_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_vg_size}),
vg_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_vg_free}),
vg_free_bytes => $anvil->Convert->add_commas({number => $scan_lvm_vg_free}),
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0020", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0020", variables => $variables, set_by => $THIS_FILE});
my $scan_lvm_vg_uuid = $anvil->Get->uuid();
my $query = "
INSERT INTO
scan_lvm_vgs
(
scan_lvm_vg_uuid,
scan_lvm_vg_internal_uuid,
scan_lvm_vg_host_uuid,
scan_lvm_vg_name,
scan_lvm_vg_extent_size,
scan_lvm_vg_attributes,
scan_lvm_vg_size,
scan_lvm_vg_free,
modified_date
) VALUES (
".$anvil->Database->quote($scan_lvm_vg_uuid).",
".$anvil->Database->quote($scan_lvm_vg_internal_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_lvm_vg_name).",
".$anvil->Database->quote($scan_lvm_vg_extent_size).",
".$anvil->Database->quote($scan_lvm_vg_attributes).",
".$anvil->Database->quote($scan_lvm_vg_size).",
".$anvil->Database->quote($scan_lvm_vg_free).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
}
}
# Any missing VGs?
foreach my $scan_lvm_vg_internal_uuid (keys %{$anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}})
{
# This one is missing.
my $scan_lvm_vg_uuid = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_uuid};
my $old_scan_lvm_vg_name = $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_vg_uuid => $scan_lvm_vg_uuid,
old_scan_lvm_vg_name => $old_scan_lvm_vg_name,
}});
next if $old_scan_lvm_vg_name eq "DELETED";
# Register an alert
my $variables = {
vg_uuid => $scan_lvm_vg_internal_uuid,
vg_name => $old_scan_lvm_vg_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0030", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0030", variables => $variables, set_by => $THIS_FILE});
# Update it PV name to be 'DELTED'
my $query = "
UPDATE
scan_lvm_vgs
SET
scan_lvm_vg_name = 'DELETED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_lvm_vg_uuid = ".$anvil->Database->quote($scan_lvm_vg_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);
}
sub find_changes_in_pvs
{
my ($anvil) = @_;
foreach my $scan_lvm_pv_internal_uuid (keys %{$anvil->data->{lvm}{scan_lvm_pv_internal_uuid}})
{
my $scan_lvm_pv_name = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{name};
my $scan_lvm_pv_used_by_vg = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{used_by_vg};
my $scan_lvm_pv_attributes = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{attributes};
my $scan_lvm_pv_size = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{size};
my $scan_lvm_pv_free = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{free_space};
my $scan_lvm_pv_sector_size = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{sector_size};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_pv_internal_uuid => $scan_lvm_pv_internal_uuid,
scan_lvm_pv_name => $scan_lvm_pv_name,
scan_lvm_pv_used_by_vg => $scan_lvm_pv_used_by_vg,
scan_lvm_pv_attributes => $scan_lvm_pv_attributes,
scan_lvm_pv_size => $anvil->Convert->add_commas({number => $scan_lvm_pv_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_size}),
scan_lvm_pv_free => $anvil->Convert->add_commas({number => $scan_lvm_pv_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_free}),
scan_lvm_pv_sector_size => $anvil->Convert->add_commas({number => $scan_lvm_pv_sector_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_sector_size}),
}});
# Have we seen this before?
if (exists $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid})
{
# Yup, anything changed?
my $scan_lvm_pv_uuid = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_uuid};
my $old_scan_lvm_pv_name = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_name};
my $old_scan_lvm_pv_used_by_vg = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_used_by_vg};
my $old_scan_lvm_pv_attributes = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_attributes};
my $old_scan_lvm_pv_size = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_size};
my $old_scan_lvm_pv_free = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_free};
my $old_scan_lvm_pv_sector_size = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_sector_size};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_scan_lvm_pv_name => $old_scan_lvm_pv_name,
old_scan_lvm_pv_used_by_vg => $old_scan_lvm_pv_used_by_vg,
old_scan_lvm_pv_attributes => $old_scan_lvm_pv_attributes,
old_scan_lvm_pv_size => $anvil->Convert->add_commas({number => $old_scan_lvm_pv_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_pv_size}),
old_scan_lvm_pv_free => $anvil->Convert->add_commas({number => $old_scan_lvm_pv_free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_pv_free}),
old_scan_lvm_pv_sector_size => $anvil->Convert->add_commas({number => $old_scan_lvm_pv_sector_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_pv_sector_size}),
}});
my $update = 0;
if ($scan_lvm_pv_name ne $old_scan_lvm_pv_name)
{
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($old_scan_lvm_pv_name eq "DELETED")
{
# A lost PV is back
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0001", variables => $variables});
$anvil->Alert->register({clear_alert => 1, alert_level => "warning", message => "scan_lvm_alert_0001", variables => $variables, set_by => $THIS_FILE});
}
else
{
# Device (name) changed... This shouldn't normally happen.
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
new_pv_name => $scan_lvm_pv_name,
old_pv_name => $old_scan_lvm_pv_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0002", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0002", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_pv_used_by_vg ne $old_scan_lvm_pv_used_by_vg)
{
# If the old value was blank, then this PV was added to a VG and that's fine.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if (not $old_scan_lvm_pv_used_by_vg)
{
# Added to a VG
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
vg_name => $scan_lvm_pv_used_by_vg,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0004", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0004", variables => $variables, set_by => $THIS_FILE});
}
else
{
# The VG was probably renamed.
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
new_vg_name => $scan_lvm_pv_used_by_vg,
old_vg_name => $old_scan_lvm_pv_used_by_vg,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0005", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0005", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_pv_attributes ne $old_scan_lvm_pv_attributes)
{
# Attribute bits changed.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
new_attributes => $scan_lvm_pv_attributes,
old_attributes => $old_scan_lvm_pv_attributes,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0006", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0006", variables => $variables, set_by => $THIS_FILE});
}
if ($scan_lvm_pv_size ne $old_scan_lvm_pv_size)
{
# PE size changed, likely grew.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
new_pv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_size}),
new_pv_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_pv_size}),
old_pv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_pv_size}),
old_pv_size_bytes => $anvil->Convert->add_commas({number => $old_scan_lvm_pv_size}),
};
if ($scan_lvm_pv_size > $old_scan_lvm_pv_size)
{
# Yup
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0007", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0007", variables => $variables, set_by => $THIS_FILE});
}
else
{
# Uhhhh... We'll make this a warning as it shouldn't happen.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0008", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0008", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_pv_free ne $old_scan_lvm_pv_free)
{
# PE size changed, likely shrunk.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
new_pv_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_free}),
new_pv_free_bytes => $anvil->Convert->add_commas({number => $scan_lvm_pv_free}),
old_pv_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_pv_free}),
old_pv_free_bytes => $anvil->Convert->add_commas({number => $old_scan_lvm_pv_free}),
};
if ($scan_lvm_pv_free < $old_scan_lvm_pv_free)
{
# Yup
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0009", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0009", variables => $variables, set_by => $THIS_FILE});
}
else
{
# Uhhhh... We'll make this a warning as it shouldn't happen.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0010", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0010", variables => $variables, set_by => $THIS_FILE});
}
}
if ($scan_lvm_pv_sector_size ne $old_scan_lvm_pv_sector_size)
{
# This is always a warning as the sector size should never change.
$update = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
new_pv_sector_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_sector_size}),
new_pv_sector_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_pv_sector_size}),
old_pv_sector_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_lvm_pv_sector_size}),
old_pv_sector_size_bytes => $anvil->Convert->add_commas({number => $old_scan_lvm_pv_sector_size}),
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0032", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0032", variables => $variables, set_by => $THIS_FILE});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }});
if ($update)
{
my $query = "
UPDATE
scan_lvm_pvs
SET
scan_lvm_pv_name = ".$anvil->Database->quote($scan_lvm_pv_name).",
scan_lvm_pv_used_by_vg = ".$anvil->Database->quote($scan_lvm_pv_used_by_vg).",
scan_lvm_pv_attributes = ".$anvil->Database->quote($scan_lvm_pv_attributes).",
scan_lvm_pv_size = ".$anvil->Database->quote($scan_lvm_pv_size).",
scan_lvm_pv_free = ".$anvil->Database->quote($scan_lvm_pv_free).",
scan_lvm_pv_sector_size = ".$anvil->Database->quote($scan_lvm_pv_sector_size).",
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_lvm_pv_uuid = ".$anvil->Database->quote($scan_lvm_pv_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_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid};
}
else
{
# New PV
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $scan_lvm_pv_name,
vg_name => $scan_lvm_pv_used_by_vg ? $scan_lvm_pv_used_by_vg : "--",
attributes => $scan_lvm_pv_attributes,
pv_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_size}),
pv_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_pv_size}),
pv_free => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_free}),
pv_free_bytes => $anvil->Convert->add_commas({number => $scan_lvm_pv_free}),
pv_sector_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $scan_lvm_pv_sector_size}),
pv_sector_size_bytes => $anvil->Convert->add_commas({number => $scan_lvm_pv_sector_size}),
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0019", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0019", variables => $variables, set_by => $THIS_FILE});
my $scan_lvm_pv_uuid = $anvil->Get->uuid();
my $query = "
INSERT INTO
scan_lvm_pvs
(
scan_lvm_pv_uuid,
scan_lvm_pv_internal_uuid,
scan_lvm_pv_host_uuid,
scan_lvm_pv_name,
scan_lvm_pv_used_by_vg,
scan_lvm_pv_attributes,
scan_lvm_pv_size,
scan_lvm_pv_free,
scan_lvm_pv_sector_size,
modified_date
) VALUES (
".$anvil->Database->quote($scan_lvm_pv_uuid).",
".$anvil->Database->quote($scan_lvm_pv_internal_uuid).",
".$anvil->Database->quote($anvil->Get->host_uuid).",
".$anvil->Database->quote($scan_lvm_pv_name).",
".$anvil->Database->quote($scan_lvm_pv_used_by_vg).",
".$anvil->Database->quote($scan_lvm_pv_attributes).",
".$anvil->Database->quote($scan_lvm_pv_size).",
".$anvil->Database->quote($scan_lvm_pv_free).",
".$anvil->Database->quote($scan_lvm_pv_sector_size).",
".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
);";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
}
}
# Any missing PVs?
foreach my $scan_lvm_pv_internal_uuid (keys %{$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}})
{
# This one is missing.
my $scan_lvm_pv_uuid = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_uuid};
my $old_scan_lvm_pv_name = $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:scan_lvm_pv_internal_uuid' => $scan_lvm_pv_internal_uuid,
's2:scan_lvm_pv_uuid' => $scan_lvm_pv_uuid,
's3:old_scan_lvm_pv_name' => $old_scan_lvm_pv_name,
}});
next if $old_scan_lvm_pv_name eq "DELETED";
# Register an alert
my $variables = {
pv_uuid => $scan_lvm_pv_internal_uuid,
pv_name => $old_scan_lvm_pv_name,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0003", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_lvm_alert_0003", variables => $variables, set_by => $THIS_FILE});
# Update it PV name to be 'DELTED'
my $query = "
UPDATE
scan_lvm_pvs
SET
scan_lvm_pv_name = 'DELETED',
modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)."
WHERE
scan_lvm_pv_uuid = ".$anvil->Database->quote($scan_lvm_pv_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 the last scan's data.
sub read_last_scan
{
my ($anvil) = @_;
# Load PV data
my $query = "
SELECT
scan_lvm_pv_uuid,
scan_lvm_pv_internal_uuid,
scan_lvm_pv_name,
scan_lvm_pv_used_by_vg,
scan_lvm_pv_attributes,
scan_lvm_pv_size,
scan_lvm_pv_free,
scan_lvm_pv_sector_size
FROM
scan_lvm_pvs
WHERE
scan_lvm_pv_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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})
{
# We've got an entry in the 'scan_lvm_pv' table, so now we'll look for data in the node and
# services tables.
my $scan_lvm_pv_uuid = $row->[0];
my $scan_lvm_pv_internal_uuid = $row->[1];
my $scan_lvm_pv_name = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_pv_uuid => $scan_lvm_pv_uuid,
scan_lvm_pv_internal_uuid => $scan_lvm_pv_internal_uuid,
scan_lvm_pv_name => $scan_lvm_pv_name,
}});
# If there's an existing entry, delete this one, it's somehow a duplicate.
if (exists $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid})
{
# Duplicate!
my $variables = {
pv_name => $scan_lvm_pv_name,
pv_uuid => $scan_lvm_pv_uuid,
internal_uuid => $scan_lvm_pv_internal_uuid,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0033", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0033", variables => $variables, set_by => $THIS_FILE});
my $query = "DELETE FROM scan_lvm_pvs WHERE scan_lvm_pv_uuid = ".$anvil->Database->quote($scan_lvm_pv_uuid).";\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
next;
}
# Save
$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_uuid} = $scan_lvm_pv_uuid;
$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_name} = $scan_lvm_pv_name;
$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_used_by_vg} = $row->[3];
$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_attributes} = $row->[4];
$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_size} = $row->[5];
$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_free} = $row->[6];
$anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_sector_size} = $row->[7];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_lvm_pvs::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::scan_lvm_pv_uuid" => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_uuid},
"sql::scan_lvm_pvs::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::scan_lvm_pv_name" => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_name},
"sql::scan_lvm_pvs::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::scan_lvm_pv_used_by_vg" => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_used_by_vg},
"sql::scan_lvm_pvs::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::scan_lvm_pv_attributes" => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_attributes},
"sql::scan_lvm_pvs::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::scan_lvm_pv_size" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_size}}),
"sql::scan_lvm_pvs::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::scan_lvm_pv_free" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_free}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_free}}),
"sql::scan_lvm_pvs::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::scan_lvm_pv_sector_size" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_sector_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_lvm_pvs}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{scan_lvm_pv_sector_size}}),
}});
}
undef $count;
undef $results;
# Load VG data
$query = "
SELECT
scan_lvm_vg_uuid,
scan_lvm_vg_internal_uuid,
scan_lvm_vg_name,
scan_lvm_vg_attributes,
scan_lvm_vg_extent_size,
scan_lvm_vg_size,
scan_lvm_vg_free
FROM
scan_lvm_vgs
WHERE
scan_lvm_vg_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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})
{
# We've got an entry in the 'scan_lvm_vg' table, so now we'll look for data in the node and
# services tables.
my $scan_lvm_vg_uuid = $row->[0];
my $scan_lvm_vg_internal_uuid = $row->[1];
my $scan_lvm_vg_name = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_vg_uuid => $scan_lvm_vg_uuid,
scan_lvm_vg_internal_uuid => $scan_lvm_vg_internal_uuid,
scan_lvm_vg_name => $scan_lvm_vg_name,
}});
# If there's an existing entry, delete this one, it's somehow a duplicate.
if (exists $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid})
{
# Duplicate!
my $variables = {
vg_name => $scan_lvm_vg_name,
vg_uuid => $scan_lvm_vg_uuid,
internal_uuid => $scan_lvm_vg_internal_uuid,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0034", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0034", variables => $variables, set_by => $THIS_FILE});
my $query = "DELETE FROM scan_lvm_vgs WHERE scan_lvm_vg_uuid = ".$anvil->Database->quote($scan_lvm_vg_uuid).";\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
next;
}
# Save
$anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_uuid} = $scan_lvm_vg_uuid;
$anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_name} = $scan_lvm_vg_name;
$anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_attributes} = $row->[3];
$anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_extent_size} = $row->[4];
$anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_size} = $row->[5];
$anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_free} = $row->[6];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_lvm_vgs::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_uuid" => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_uuid},
"sql::scan_lvm_vgs::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_name" => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_name},
"sql::scan_lvm_vgs::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_attributes" => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_attributes},
"sql::scan_lvm_vgs::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_extent_size" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_extent_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_extent_size}}),
"sql::scan_lvm_vgs::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_size" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_size}}),
"sql::scan_lvm_vgs::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::scan_lvm_vg_free" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_free}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_lvm_vgs}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{scan_lvm_vg_free}}),
}});
}
undef $count;
undef $results;
# Load LV data
$query = "
SELECT
scan_lvm_lv_uuid,
scan_lvm_lv_internal_uuid,
scan_lvm_lv_name,
scan_lvm_lv_attributes,
scan_lvm_lv_on_vg,
scan_lvm_lv_size,
scan_lvm_lv_path,
scan_lvm_lv_on_pvs
FROM
scan_lvm_lvs
WHERE
scan_lvm_lv_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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})
{
# We've got an entry in the 'scan_lvm_lv' table, so now we'll look for data in the node and
# services tables.
my $scan_lvm_lv_uuid = $row->[0];
my $scan_lvm_lv_internal_uuid = $row->[1];
my $scan_lvm_lv_name = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_lvm_lv_uuid => $scan_lvm_lv_uuid,
scan_lvm_lv_internal_uuid => $scan_lvm_lv_internal_uuid,
scan_lvm_lv_name => $scan_lvm_lv_name,
}});
# If there's an existing entry, delete this one, it's somehow a duplicate.
if (exists $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid})
{
# Duplicate! Is one of them DELETED?
my $existing_name = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_name};
my $existing_uuid = $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
existing_name => $existing_name,
existing_uuid => $existing_uuid,
}});
if ($anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_name} eq "DELETED")
{
# Delete the one we already read.
my $variables = {
lv_name => $existing_name,
lv_uuid => $existing_uuid,
internal_uuid => $scan_lvm_lv_internal_uuid,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0035", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0034", variables => $variables, set_by => $THIS_FILE});
my $query = "DELETE FROM scan_lvm_lvs WHERE scan_lvm_lv_uuid = ".$anvil->Database->quote($existing_uuid).";\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
delete $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid};
}
else
{
# Delete the new one
my $variables = {
lv_name => $scan_lvm_lv_name,
lv_uuid => $scan_lvm_lv_uuid,
internal_uuid => $scan_lvm_lv_internal_uuid,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_alert_0035", variables => $variables});
$anvil->Alert->register({alert_level => "notice", message => "scan_lvm_alert_0034", variables => $variables, set_by => $THIS_FILE});
my $query = "DELETE FROM scan_lvm_lvs WHERE scan_lvm_lv_uuid = ".$anvil->Database->quote($scan_lvm_lv_uuid).";\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
next;
}
}
# Save
$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_uuid} = $scan_lvm_lv_uuid;
$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_name} = $scan_lvm_lv_name;
$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_attributes} = $row->[3];
$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_vg} = $row->[4];
$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_size} = $row->[5];
$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_path} = $row->[6];
$anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_pvs} = $row->[7];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_uuid" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_uuid},
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_name" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_name},
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_attributes" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_attributes},
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_on_vg" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_vg},
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_size" => $anvil->Convert->add_commas({number => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_size}}),
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_path" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_path},
"sql::scan_lvm_lvs::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::scan_lvm_lv_on_pvs" => $anvil->data->{sql}{scan_lvm_lvs}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{scan_lvm_lv_on_pvs},
}});
}
return(0);
}
sub collect_data
{
my ($anvil) = @_;
### TODO: Swap oput '--separator \#!\#' for '--reportformat json'
collect_pvs_data($anvil);
collect_vgs_data($anvil);
collect_lvs_data($anvil);
return(0);
}
sub collect_pvs_data
{
my ($anvil) = @_;
my $shell_call = $anvil->data->{path}{exe}{pvscan};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({timeout => 15, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{pvs}." --noheadings --units b --reportformat json -o pv_uuid,pv_name,vg_name,pv_attr,pv_size,pv_free";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({timeout => 15, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
my $json = JSON->new->allow_nonref;
my $pvs_data = $json->decode($output);
my $default_sector_size = 512;
foreach my $hash_ref (@{$pvs_data->{report}->[0]->{pv}})
{
my $scan_lvm_pv_internal_uuid = $hash_ref->{pv_uuid};
$anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{name} = $hash_ref->{pv_name};
$anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{used_by_vg} = $hash_ref->{vg_name};
$anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{attributes} = $hash_ref->{pv_attr}; # TODO: Parse this out
$anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{size} = ($hash_ref->{pv_size} =~ /^(\d+)B/)[0];
$anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{free_space} = ($hash_ref->{pv_free} =~ /^(\d+)B/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"lvm::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::name" => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{name},
"lvm::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::used_by_vg" => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{used_by_vg},
"lvm::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::attributes" => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{attributes},
"lvm::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::size" => $anvil->Convert->add_commas({number => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{size}}).")",
"lvm::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::free_space" => $anvil->Convert->add_commas({number => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{free_space}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{free_space}}).")",
}});
# We need to find the sector size of this PV.
my $partition = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{name};
$partition =~ s/^.*\///;
my $directory = "/sys/class/block/".$partition."/subsystem";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
partition => $partition,
directory => $directory,
}});
# Look for the parent device. For partitions like 'sda1', this is 'sda'. For 'nvmen0p1', this is 'nvmen0', etc.
my $sector_size = 0;
until ($sector_size)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { partition => $partition }});
if (not $partition)
{
# Weird... Default to 512.
$sector_size = $default_sector_size;
my $original_partition = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{name};
my $sector_path = $directory."/".$original_partition."/queue/hw_sector_size";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_warning_0001", variables => {
device => $original_partition,
sector_path => $sector_path,
sector_size => $sector_size,
}});
}
my $sector_size_file = $directory."/".$partition."/queue/hw_sector_size";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sector_size_file => $sector_size_file }});
if (-e $sector_size_file)
{
$sector_size = $anvil->Storage->read_file({file => $sector_size_file });
chomp $sector_size;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sector_size => $sector_size }});
if ((not $sector_size) or ($sector_size =~ /\D/))
{
# Something went wrong, default to 512.
$sector_size = $default_sector_size;
my $original_partition = $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{name};
my $sector_path = $directory."/".$original_partition."/queue/hw_sector_size";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_lvm_warning_0001", variables => {
device => $original_partition,
sector_path => $sector_path,
sector_size => $sector_size,
}});
}
}
# Take a number off and try again.
chop $partition;
}
$anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{sector_size} = $sector_size;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"lvm::scan_lvm_pv_internal_uuid::${scan_lvm_pv_internal_uuid}::sector_size" => $anvil->Convert->add_commas({number => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{sector_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{scan_lvm_pv_internal_uuid}{$scan_lvm_pv_internal_uuid}{sector_size}}).")",
}});
}
return(0);
}
sub collect_vgs_data
{
my ($anvil) = @_;
my $shell_call = $anvil->data->{path}{exe}{vgscan};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({timeout => 15, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{vgs}." --noheadings --units b --reportformat json -o vg_uuid,vg_name,vg_attr,vg_extent_size,vg_size,vg_free";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({timeout => 15, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
my $json = JSON->new->allow_nonref;
my $vgs_data = $json->decode($output);
foreach my $hash_ref (@{$vgs_data->{report}->[0]->{vg}})
{
my $scan_lvm_vg_internal_uuid = $hash_ref->{vg_uuid};
$anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{name} = $hash_ref->{vg_name};
$anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{attributes} = $hash_ref->{vg_attr};
$anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{extent_size} = ($hash_ref->{vg_extent_size} =~ /^(\d+)B/)[0];
$anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{size} = ($hash_ref->{vg_size} =~ /^(\d+)B/)[0];
$anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{free_space} = ($hash_ref->{vg_free} =~ /^(\d+)B/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"lvm::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::name" => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{name},
"lvm::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::attributes" => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{attributes},
"lvm::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::extent_size" => $anvil->Convert->add_commas({number => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{extent_size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{extent_size}}),
"lvm::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::size" => $anvil->Convert->add_commas({number => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{size}}),
"lvm::scan_lvm_vg_internal_uuid::${scan_lvm_vg_internal_uuid}::free_space" => $anvil->Convert->add_commas({number => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{free_space}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{scan_lvm_vg_internal_uuid}{$scan_lvm_vg_internal_uuid}{free_space}}),
}});
}
return(0);
}
sub collect_lvs_data
{
my ($anvil) = @_;
my $shell_call = $anvil->data->{path}{exe}{lvscan};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({timeout => 15, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{lvs}." --noheadings --units b --reportformat json -o lv_name,vg_name,lv_attr,lv_size,lv_uuid,lv_path,devices";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({timeout => 15, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
my $json = JSON->new->allow_nonref;
my $lvs_data = $json->decode($output);
foreach my $hash_ref (@{$lvs_data->{report}->[0]->{lv}})
{
my $scan_lvm_lv_internal_uuid = $hash_ref->{lv_uuid};
my $on_pvs = $hash_ref->{devices};
$on_pvs =~ s/\(\d+\)//g;
# In JSON format, there are 2+ hash references when there are 2+ PVs under an LV. So we
# record all data on the first pass and append the additional PVs.
if (not exists $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid})
{
$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{name} = $hash_ref->{lv_name};
$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{attributes} = $hash_ref->{lv_attr};
$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_vg} = $hash_ref->{vg_name};
$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{device_path} = $hash_ref->{lv_path};
$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{size} = ($hash_ref->{lv_size} =~ /^(\d+)B/)[0];
$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_pvs} = $on_pvs;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"lvm::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::name" => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{name},
"lvm::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::attributes" => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{attributes},
"lvm::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::on_vg" => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_vg},
"lvm::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::device_path" => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{device_path},
"lvm::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::size" => $anvil->Convert->add_commas({number => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{size}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{size}}),
"lvm::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::on_pvs" => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_pvs},
}});
}
else
{
$anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_pvs} .= ",".$on_pvs;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"lvm::scan_lvm_lv_internal_uuid::${scan_lvm_lv_internal_uuid}::on_pvs" => $anvil->data->{lvm}{scan_lvm_lv_internal_uuid}{$scan_lvm_lv_internal_uuid}{on_pvs},
}});
}
}
return(0);
}