cad524db9d
* Created new anvil-monitor-network daemon to trigger scan-server via anvil-monitor-network on network events. * Moved functionality into scan-network Signed-off-by: digimer <mkelly@alteeve.ca>
506 lines
23 KiB
Perl
Executable File
506 lines
23 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# This daemon watches for network interface link change (unplugged or plugged in network cables).
|
|
#
|
|
# At this point, the only thing this does is call 'scan-network' when a change is detected.
|
|
#
|
|
# NOTE: This is designed to be minimal overhead, so there is no attempt to connect to the database. As such,
|
|
# be mindful of what this daemon is used for.
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Data::Dumper;
|
|
use Text::Diff;
|
|
use Anvil::Tools;
|
|
|
|
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
|
|
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
|
|
if (($running_directory =~ /^\./) && ($ENV{PWD}))
|
|
{
|
|
$running_directory =~ s/^\./$ENV{PWD}/;
|
|
}
|
|
|
|
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
|
|
$| = 1;
|
|
|
|
my $anvil = Anvil::Tools->new();
|
|
|
|
# Read switches
|
|
$anvil->Get->switches({list => [], man => $THIS_FILE});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
|
|
|
|
# Calculate my sum so that we can exit if it changes later.
|
|
$anvil->Storage->record_md5sums;
|
|
my $next_md5sum_check = time + 30;
|
|
|
|
my $directory = "/sys/class/net";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }});
|
|
|
|
# Now go into the main loop
|
|
while(1)
|
|
{
|
|
### NOTE: A lot of this logic comes from scan-network
|
|
my $scan_time = time;
|
|
my $trigger = 0;
|
|
|
|
# Look for interfaces.
|
|
local(*DIRECTORY);
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }});
|
|
opendir(DIRECTORY, $directory);
|
|
while(my $file = readdir(DIRECTORY))
|
|
{
|
|
next if $file eq ".";
|
|
next if $file eq "..";
|
|
next if $file eq "lo";
|
|
my $full_path = $directory."/".$file;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { full_path => $full_path }});
|
|
if (-d $full_path)
|
|
{
|
|
# Pull out the data I want. Note that some of these don't exist with virtio-net interfaces.
|
|
my $interface = $file;
|
|
my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
|
|
$link_state =~ s/\n$//;
|
|
my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
|
|
$mtu =~ s/\n$//;
|
|
my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
|
|
$duplex =~ s/\n$//;
|
|
my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
|
|
$operational =~ s/\n$//;
|
|
my $modalias = -e $full_path."/device/modalias" ? $anvil->Storage->read_file({file => $full_path."/device/modalias"}) : "unknown";
|
|
$modalias =~ s/\n$//;
|
|
my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed"}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link
|
|
$speed =~ s/\n$//;
|
|
my $media = "unknown";
|
|
my $type = "interface";
|
|
my $driver = "";
|
|
my $tx_bytes = 0; # How many bytes transmitted
|
|
my $rx_bytes = 0; # How many bytes received
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
interface => $interface,
|
|
link_state => $link_state,
|
|
mtu => $mtu,
|
|
duplex => $duplex,
|
|
operational => $operational,
|
|
speed => $speed,
|
|
modalias => $modalias,
|
|
}});
|
|
|
|
# Get the MAC address
|
|
my $mac_address = "";
|
|
my $shell_call = $anvil->data->{path}{exe}{ethtool}." -P ".$interface;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($output =~ /(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)$/)
|
|
{
|
|
$mac_address = lc($1);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
else
|
|
{
|
|
# Get it by reading the address file.
|
|
if (-e $full_path."/bonding_slave/perm_hwaddr")
|
|
{
|
|
$mac_address = $anvil->Storage->read_file({file => $full_path."/bonding_slave/perm_hwaddr"});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
elsif (-e $full_path."/address")
|
|
{
|
|
$mac_address = $anvil->Storage->read_file({file => $full_path."/address"});
|
|
$mac_address =~ s/\n//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
}
|
|
|
|
# These are variables that will be needed if this is a bond interface.
|
|
my $ip_address = "";
|
|
my $subnet_mask = "";
|
|
my $bond_mode = "";
|
|
my $primary_interface = "";
|
|
my $primary_reselect = "";
|
|
my $active_interface = "";
|
|
my $mii_polling_interval = "";
|
|
my $up_delay = "";
|
|
my $down_delay = "";
|
|
my $bond_parent = "";
|
|
|
|
# These are variables that will be needed if this is a bridge interface
|
|
my $bridge_id = "";
|
|
my $bridge_stp_enabled = "";
|
|
|
|
# If this interface is already a bond slave, the real mac address will be in a
|
|
# sub-directory.
|
|
my $mac_bond_file = $directory."/".$file."/bonding_slave/perm_hwaddr";
|
|
if (-e $mac_bond_file)
|
|
{
|
|
# It's a slave.
|
|
$mac_address = $anvil->Storage->read_file({file => $mac_bond_file});
|
|
$mac_address =~ s/\n$//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
|
|
# Pick out our driver.
|
|
if ($modalias =~ /^virtio:/)
|
|
{
|
|
$driver = "virtio";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { driver => $driver }});
|
|
}
|
|
|
|
# If this is a virtual interface, set some fake values that don't actually exist on
|
|
# the system for the sake of a cleaner display.
|
|
if (($mac_address =~ /^52:54:00/) or ($driver eq "virtio"))
|
|
{
|
|
### Set some fake values.
|
|
# Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary.
|
|
if ((not $speed) or ($speed eq "-1"))
|
|
{
|
|
$speed = 10000;
|
|
}
|
|
if ((not $duplex) or ($duplex eq "unknown"))
|
|
{
|
|
$duplex = "full";
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
speed => $speed,
|
|
duplex => $duplex,
|
|
}});
|
|
}
|
|
# If the state is 'down', set the speed to '0'.
|
|
if (not $link_state)
|
|
{
|
|
$speed = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { speed => $speed }});
|
|
}
|
|
|
|
# Is this a bond interface?
|
|
if (-e "/proc/net/bonding/".$interface)
|
|
{
|
|
# Yup, we'll neet to dig into the bond proc files to get the proper slaved
|
|
# interface MAC addresses.
|
|
$type = "bond";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }});
|
|
|
|
# Read the bond mode.
|
|
$bond_mode = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/mode"});
|
|
$bond_mode =~ s/\s.*//;
|
|
$bond_mode =~ s/\n$//;
|
|
$primary_interface = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/primary"});
|
|
$primary_interface =~ s/\n$//;
|
|
$primary_reselect = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/primary_reselect"});
|
|
$primary_reselect =~ s/\s.*//;
|
|
$primary_reselect =~ s/\n$//;
|
|
$active_interface = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/active_slave"});
|
|
$active_interface =~ s/\n$//;
|
|
$mii_polling_interval = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/miimon"});
|
|
$mii_polling_interval =~ s/\n$//;
|
|
$up_delay = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/updelay"});
|
|
$up_delay =~ s/\n$//;
|
|
$down_delay = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/downdelay"});
|
|
$down_delay =~ s/\n$//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
active_interface => $active_interface,
|
|
bond_mode => $bond_mode,
|
|
mii_polling_interval => $mii_polling_interval,
|
|
primary_reselect => $primary_reselect,
|
|
primary_interface => $primary_interface,
|
|
type => $type,
|
|
}});
|
|
}
|
|
elsif ((-e $full_path."/master") && ($interface !~ /^vnet/))
|
|
{
|
|
# We're in a bond.
|
|
my $target = readlink($full_path."/master");
|
|
$bond_parent = ($target =~ /^.*\/(.*)$/)[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
target => $target,
|
|
bond_parent => $bond_parent,
|
|
}});
|
|
}
|
|
elsif (-d $full_path."/bridge")
|
|
{
|
|
# It's a bridge
|
|
$type = "bridge";
|
|
$bridge_id = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/bridge_id"});
|
|
$bridge_id =~ s/\n$//;
|
|
$bridge_stp_enabled = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/stp_state"});
|
|
$bridge_stp_enabled =~ s/\n$//;
|
|
$speed = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
type => $type,
|
|
bridge_id => $bridge_id,
|
|
bridge_stp_enabled => $bridge_stp_enabled,
|
|
}});
|
|
if ($bridge_stp_enabled eq "0")
|
|
{
|
|
$bridge_stp_enabled = "disabled";
|
|
}
|
|
elsif ($bridge_stp_enabled eq "1")
|
|
{
|
|
$bridge_stp_enabled = "enabled_kernel";
|
|
}
|
|
elsif ($bridge_stp_enabled eq "2")
|
|
{
|
|
$bridge_stp_enabled = "enabled_userland";
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_stp_enabled => $bridge_stp_enabled }});
|
|
}
|
|
|
|
# If this is a 'vnet' device, set 'operational' to up
|
|
if ($interface =~ /^vnet/)
|
|
{
|
|
### TODO: We can't assume this, we need to detect virsh net up/down
|
|
$operational = "up";
|
|
$media = "virtual";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
operational => $operational,
|
|
media => $media,
|
|
}});
|
|
}
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
active_interface => $active_interface,
|
|
bond_parent => $bond_parent,
|
|
bond_mode => $bond_mode,
|
|
bridge_id => $bridge_id,
|
|
bridge_stp_enabled => $bridge_stp_enabled,
|
|
down_delay => $down_delay,
|
|
duplex => $duplex,
|
|
interface => $interface,
|
|
mac_address => $mac_address,
|
|
mii_polling_interval => $mii_polling_interval,
|
|
mtu => $mtu,
|
|
operational => $operational,
|
|
primary_reselect => $primary_reselect,
|
|
primary_interface => $primary_interface,
|
|
speed => $speed,
|
|
subnet_mask => $subnet_mask,
|
|
type => $type,
|
|
up_delay => $up_delay,
|
|
}});
|
|
|
|
# Find the media, if possible.
|
|
(my $ethtool, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ethtool}." ".$interface});
|
|
foreach my $line (split/\n/, $ethtool)
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
|
|
if ($line =~ /Supported ports: \[ (.*?) \]/i)
|
|
{
|
|
$media = lc($1);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { media => $media }});
|
|
|
|
# This can be 'tp mii', which breaks json.
|
|
if ($media =~ /\t/)
|
|
{
|
|
$media =~ s/\t/,/g;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { media => $media }});
|
|
}
|
|
last;
|
|
}
|
|
}
|
|
|
|
# Trigger?
|
|
if (not exists $anvil->data->{last_scan}{$interface})
|
|
{
|
|
print "The interface: [".$interface."] has been found. We will now monitor it for changes.\n";
|
|
$trigger = 1;
|
|
}
|
|
else
|
|
{
|
|
# Now look for differences.
|
|
if ($anvil->data->{last_scan}{$interface}{active_interface} ne $active_interface)
|
|
{
|
|
print "The ".$type.": [".$interface."] has a different active interface: [".$anvil->data->{last_scan}{$interface}{active_interface}."] -> [".$active_interface."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{bond_mode} ne $bond_mode)
|
|
{
|
|
print "The ".$type.": [".$interface."] mode has changed from: [".$anvil->data->{last_scan}{$interface}{bond_mode}."] -> [".$bond_mode."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{bond_parent} ne $bond_parent)
|
|
{
|
|
print "The ".$type.": [".$interface."] bond parent has changed from: [".$anvil->data->{last_scan}{$interface}{bond_parent}."] -> [".$bond_parent."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{bridge_id} ne $bridge_id)
|
|
{
|
|
print "The ".$type.": [".$interface."] bridge ID has changed from: [".$anvil->data->{last_scan}{$interface}{bridge_id}."] -> [".$bridge_id."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{bridge_stp_enabled} ne $bridge_stp_enabled)
|
|
{
|
|
print "The ".$type.": [".$interface."] spanning tree protocol (STP) setting has changed from: [".$anvil->data->{last_scan}{$interface}{bridge_stp_enabled}."] -> [".$bridge_stp_enabled."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{down_delay} ne $down_delay)
|
|
{
|
|
print "The ".$type.": [".$interface."] down delay has changed from: [".$anvil->data->{last_scan}{$interface}{bridge_stp_enabled}."ms] -> [".$bridge_stp_enabled."ms].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{up_delay} ne $up_delay)
|
|
{
|
|
print "The ".$type.": [".$interface."] up delay has changed from: [".$anvil->data->{last_scan}{$interface}{up_delay}."ms] -> [".$up_delay."ms].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{duplex} ne $duplex)
|
|
{
|
|
print "The ".$type.": [".$interface."] duplex has changed from: [".$anvil->data->{last_scan}{$interface}{duplex}."] -> [".$duplex."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{ip_address} ne $ip_address)
|
|
{
|
|
print "The ".$type.": [".$interface."] ip address has changed from: [".$anvil->data->{last_scan}{$interface}{ip_address}."] -> [".$ip_address."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{subnet_mask} ne $subnet_mask)
|
|
{
|
|
print "The ".$type.": [".$interface."] subnet_mask has changed from: [".$anvil->data->{last_scan}{$interface}{subnet_mask}."] -> [".$subnet_mask."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{link_state} ne $link_state)
|
|
{
|
|
print "The ".$type.": [".$interface."] link status has changed from: [".$anvil->data->{last_scan}{$interface}{link_state}."] -> [".$link_state."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{mac_address} ne $mac_address)
|
|
{
|
|
print "The ".$type.": [".$interface."] MAC address has changed from: [".$anvil->data->{last_scan}{$interface}{mac_address}."] -> [".$mac_address."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{media} ne $media)
|
|
{
|
|
print "The ".$type.": [".$interface."] media has changed from: [".$anvil->data->{last_scan}{$interface}{media}."] -> [".$media."]. (Excuse me, how?!)\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{mii_polling_interval} ne $mii_polling_interval)
|
|
{
|
|
print "The ".$type.": [".$interface."] media independent interface (mii) polling interval has changed from: [".$anvil->data->{last_scan}{$interface}{mii_polling_interval}."ms] -> [".$mii_polling_interval."ms].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{mtu} ne $mtu)
|
|
{
|
|
print "The ".$type.": [".$interface."] maximum transmission unit (mtu) has changed from: [".$anvil->data->{last_scan}{$interface}{mtu}." bytes] -> [".$mtu." bytes].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{operational} ne $operational)
|
|
{
|
|
print "The ".$type.": [".$interface."] operational status has changed from: [".$anvil->data->{last_scan}{$interface}{operational}."] -> [".$operational."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{primary_reselect} ne $primary_reselect)
|
|
{
|
|
print "The ".$type.": [".$interface."] primary reselect policy has changed from: [".$anvil->data->{last_scan}{$interface}{primary_reselect}."] -> [".$primary_reselect."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{primary_interface} ne $primary_interface)
|
|
{
|
|
print "The ".$type.": [".$interface."] primary interface has changed from: [".$anvil->data->{last_scan}{$interface}{primary_interface}."] -> [".$primary_interface."].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{speed} ne $speed)
|
|
{
|
|
print "The ".$type.": [".$interface."] speed has changed from: [".$anvil->data->{last_scan}{$interface}{speed}." Mbps] -> [".$speed." Mbps].\n";
|
|
$trigger = 1;
|
|
}
|
|
if ($anvil->data->{last_scan}{$interface}{type} ne $type)
|
|
{
|
|
print "The device: [".$interface."] type has changed from: [".$anvil->data->{last_scan}{$interface}{type}."] -> [".$type."].\n";
|
|
$trigger = 1;
|
|
}
|
|
}
|
|
|
|
# We'll use this to determine when an interface has disappeared.
|
|
$anvil->data->{last_scan}{$interface}{seen} = $scan_time;
|
|
|
|
# Store new information we found.
|
|
$anvil->data->{last_scan}{$interface}{active_interface} = $active_interface;
|
|
$anvil->data->{last_scan}{$interface}{bond_mode} = $bond_mode;
|
|
$anvil->data->{last_scan}{$interface}{bond_parent} = $bond_parent;
|
|
$anvil->data->{last_scan}{$interface}{bridge_id} = $bridge_id;
|
|
$anvil->data->{last_scan}{$interface}{bridge_stp_enabled} = $bridge_stp_enabled;
|
|
$anvil->data->{last_scan}{$interface}{down_delay} = $down_delay;
|
|
$anvil->data->{last_scan}{$interface}{duplex} = $duplex;
|
|
$anvil->data->{last_scan}{$interface}{ip_address} = $ip_address;
|
|
$anvil->data->{last_scan}{$interface}{link_state} = $link_state;
|
|
$anvil->data->{last_scan}{$interface}{mac_address} = $mac_address;
|
|
$anvil->data->{last_scan}{$interface}{media} = $media;
|
|
$anvil->data->{last_scan}{$interface}{mii_polling_interval} = $mii_polling_interval;
|
|
$anvil->data->{last_scan}{$interface}{mtu} = $mtu;
|
|
$anvil->data->{last_scan}{$interface}{operational} = $operational;
|
|
$anvil->data->{last_scan}{$interface}{primary_reselect} = $primary_reselect;
|
|
$anvil->data->{last_scan}{$interface}{primary_interface} = $primary_interface;
|
|
$anvil->data->{last_scan}{$interface}{speed} = $speed;
|
|
$anvil->data->{last_scan}{$interface}{subnet_mask} = $subnet_mask;
|
|
$anvil->data->{last_scan}{$interface}{type} = $type;
|
|
$anvil->data->{last_scan}{$interface}{up_delay} = $up_delay;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"last_scan::${interface}::seen" => $anvil->data->{last_scan}{$interface}{seen},
|
|
"last_scan::${interface}::active_interface" => $anvil->data->{last_scan}{$interface}{active_interface},
|
|
"last_scan::${interface}::bond_mode" => $anvil->data->{last_scan}{$interface}{bond_mode},
|
|
"last_scan::${interface}::bond_parent" => $anvil->data->{last_scan}{$interface}{bond_parent},
|
|
"last_scan::${interface}::bridge_id" => $anvil->data->{last_scan}{$interface}{bridge_id},
|
|
"last_scan::${interface}::bridge_stp_enabled" => $anvil->data->{last_scan}{$interface}{bridge_stp_enabled},
|
|
"last_scan::${interface}::down_delay" => $anvil->data->{last_scan}{$interface}{down_delay},
|
|
"last_scan::${interface}::duplex" => $anvil->data->{last_scan}{$interface}{duplex},
|
|
"last_scan::${interface}::ip_address" => $anvil->data->{last_scan}{$interface}{ip_address},
|
|
"last_scan::${interface}::link_state" => $anvil->data->{last_scan}{$interface}{link_state},
|
|
"last_scan::${interface}::mac_address" => $anvil->data->{last_scan}{$interface}{mac_address},
|
|
"last_scan::${interface}::media" => $anvil->data->{last_scan}{$interface}{media},
|
|
"last_scan::${interface}::mii_polling_interval" => $anvil->data->{last_scan}{$interface}{mii_polling_interval},
|
|
"last_scan::${interface}::mtu" => $anvil->data->{last_scan}{$interface}{mtu},
|
|
"last_scan::${interface}::operational" => $anvil->data->{last_scan}{$interface}{operational},
|
|
"last_scan::${interface}::primary_reselect" => $anvil->data->{last_scan}{$interface}{primary_reselect},
|
|
"last_scan::${interface}::primary_interface" => $anvil->data->{last_scan}{$interface}{primary_interface},
|
|
"last_scan::${interface}::speed" => $anvil->data->{last_scan}{$interface}{speed},
|
|
"last_scan::${interface}::subnet_mask" => $anvil->data->{last_scan}{$interface}{subnet_mask},
|
|
"last_scan::${interface}::type" => $anvil->data->{last_scan}{$interface}{type},
|
|
"last_scan::${interface}::up_delay" => $anvil->data->{last_scan}{$interface}{up_delay},
|
|
}});
|
|
}
|
|
}
|
|
closedir(DIRECTORY);
|
|
|
|
# Now look for interfaces that disappeared.
|
|
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{last_scan}})
|
|
{
|
|
next if $anvil->data->{last_scan}{$interface}{seen} == $scan_time;
|
|
print "The device: [".$interface."] appears to have disappeared!\n";
|
|
delete $anvil->data->{last_scan}{$interface};
|
|
|
|
$trigger = 1;
|
|
}
|
|
|
|
# Trigger?
|
|
if ($trigger)
|
|
{
|
|
my $shell_call = $anvil->data->{path}{directories}{scan_agents}."/scan-network/scan-network".$anvil->Log->switches;
|
|
print "Triggering the call to run: [".$shell_call."]\n";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
}
|
|
|
|
if (time > $next_md5sum_check)
|
|
{
|
|
$next_md5sum_check = time + 30;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { next_md5sum_check => $next_md5sum_check }});
|
|
if ($anvil->Storage->check_md5sums)
|
|
{
|
|
# NOTE: We exit with '0' to prevent systemctl from showing a scary red message.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "message_0014"});
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
}
|
|
|
|
sleep 2;
|
|
}
|