diff --git a/Anvil/Tools/Network.pm b/Anvil/Tools/Network.pm index 5b49a639..00906da5 100644 --- a/Anvil/Tools/Network.pm +++ b/Anvil/Tools/Network.pm @@ -15,7 +15,6 @@ my $THIS_FILE = "Network.pm"; ### Methods; # bridge_info # check_firewall -# check_network # check_internet # collect_data # download @@ -385,409 +384,6 @@ sub check_firewall } -### TODO: Phase this out when EL8 / ifcfg-X file support is ended. -=head2 check_network - -B<< NOTE >>: This method is not yet implemented. - -This method checks to see if bridges and the links in bonds are up. It can simply report the bridge, bond and link states, or it can try to bring up interfaces that are down. - -This method returns C<< 0 >> if nothing was done. It returns C<< 1 >> if any repairs were done. - -Data is stored in the hash; - -* bridge_health::::up = [0,1] -* bond_health::::up = [0,1] -* bond_health::::active_links = -* bond_health::::up_links = -* bond_health::::configured_links = -* bond_health::::interface::::in_bond = [0,1] -* bond_health::::interface::::up = [0,1] -* bond_health::::interface::::carrier = [0,1] -* bond_health::::interface::::name = - -Parameters; - -=head3 heal (optional, default 'down_only') - -When set to C<< down_only >>, a bond where both links are down will attempt to up the links. However, bonds with at least one link up will be left alone. This is the default behaviour as it's not uncommon for admins to remotely down a single interface that is failing to stop alerts until a physical repair can be made. - -When set to C<< all >>, any interfaces that are found to be down will attempt to brought up. - -Wen set to C<< none >>, no attempts will be made to bring up any interfaces. The states will simply be recorded. - -B<< Note >>: Interfaces that show no carrier will not be started in any case. - -=cut -sub check_network -{ - my $self = shift; - my $parameter = shift; - my $anvil = $self->parent; - my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Network->check_internet()" }}); - - # This is causing more problems than it solves. Disabled for the time being. - return(0); - - my $heal = defined $parameter->{heal} ? $parameter->{heal} : "down_only"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - heal => $heal, - }}); - - # Find out the bonds that are up. - my $host = $anvil->Get->short_host_name(); - $anvil->Network->bridge_info({debug => $debug}); - - if (exists $anvil->data->{bond_health}) - { - delete $anvil->data->{bond_health}; - } - - # Read in the network configuration files to track which interfaces are bound to which bonds. - my $repaired = 0; - my $interface = ""; - my $directory = $anvil->data->{path}{directories}{ifcfg}; - local(*DIRECTORY); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0018", variables => { directory => $directory }}); - opendir(DIRECTORY, $directory); - while(my $file = readdir(DIRECTORY)) - { - if ($file =~ /^ifcfg-(.*)$/) - { - $interface = $1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { interface => $interface }}); - - # We'll check these, so this just makes sure we don't get an undefined variable error. - $anvil->data->{raw_network}{interface}{$interface}{variable}{TYPE} = ""; - $anvil->data->{raw_network}{interface}{$interface}{variable}{DEVICE} = ""; - $anvil->data->{raw_network}{interface}{$interface}{variable}{MASTER} = ""; - } - else - { - next; - } - my $full_path = $directory."/".$file; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { full_path => $full_path }}); - - my $device = ""; - my $is_link = ""; - my $in_bond = ""; - my $is_bond = ""; - - # Read in the file. - my $file_body = $anvil->Storage->read_file({debug => $debug, file => $full_path}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { file_body => $file_body }}); - - foreach my $line (split/\n/, $file_body) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }}); - $line =~ s/#.*$//; - if ($line =~ /^(.*?)=(.*)$/) - { - my $variable = $1; - my $value = $2; - $value =~ s/^"(.*)"$/$1/; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - variable => $variable, - value => $value, - }}); - - $anvil->data->{raw_network}{interface}{$interface}{variable}{$variable} = $value; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "raw_network::interface::${interface}::variable::${variable}" => $anvil->data->{raw_network}{interface}{$interface}{variable}{$variable}, - }}); - } - } - $interface = ""; - } - closedir(DIRECTORY); - - # Process - foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{raw_network}{interface}}) - { - my $type = $anvil->data->{raw_network}{interface}{$interface}{variable}{TYPE}; - my $device = $anvil->data->{raw_network}{interface}{$interface}{variable}{DEVICE}; - my $name = defined $anvil->data->{raw_network}{interface}{$interface}{variable}{NAME} ? $anvil->data->{raw_network}{interface}{$interface}{variable}{NAME} : $device; - $name =~ s/ /_/g; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - interface => $interface, - type => $type, - device => $device, - name => $name, - }}); - - # Is this a bridge? - if (lc($type) eq "bridge") - { - # Yup! - $anvil->data->{bridge_health}{$device}{up} = 0; - $anvil->data->{bridge_health}{$device}{name} = $name; - if ((exists $anvil->data->{bridge}{$host}{$device}) && ($anvil->data->{bridge}{$host}{$device}{found})) - { - $anvil->data->{bridge_health}{$device}{up} = 1; - } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "bridge_health::${device}::up" => $anvil->data->{bridge_health}{$device}{up}, - "bridge_health::${device}::name" => $anvil->data->{bridge_health}{$device}{name}, - }}); - } - - # Is this a bond? - if (lc($type) eq "bond") - { - # Yes! - $anvil->data->{bond_health}{$device}{configured_links} = 0; - $anvil->data->{bond_health}{$device}{active_links} = 0; - $anvil->data->{bond_health}{$device}{up_links} = 0; - $anvil->data->{bond_health}{$device}{name} = $name; - - # Find the links configured to be under this bond. - foreach my $this_interface (sort {$a cmp $b} keys %{$anvil->data->{raw_network}{interface}}) - { - # Is this a bond? - my $this_type = $anvil->data->{raw_network}{interface}{$this_interface}{variable}{TYPE}; - my $this_device = $anvil->data->{raw_network}{interface}{$this_interface}{variable}{DEVICE}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - this_interface => $this_interface, - this_type => $this_type, - this_device => $this_device, - }}); - next if lc($this_type) ne "ethernet"; - - my $master = $anvil->data->{raw_network}{interface}{$this_interface}{variable}{MASTER}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { master => $master }}); - if (($master) && ($master eq $device)) - { - # This interface belongs to this bond. - $anvil->data->{bond_health}{$device}{interface}{$this_device}{in_bond} = 0; - $anvil->data->{bond_health}{$device}{interface}{$this_device}{up} = "unknown"; - $anvil->data->{bond_health}{$device}{interface}{$this_device}{carrier} = "unknown"; - $anvil->data->{bond_health}{$device}{interface}{$this_device}{name} = $this_interface; - $anvil->data->{bond_health}{$device}{configured_links}++; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "bond_health::${device}::interface::${this_device}::name" => $anvil->data->{bond_health}{$device}{interface}{$this_device}{name}, - "bond_health::${device}::configured_links" => $anvil->data->{bond_health}{$device}{configured_links}, - }}); - - # Read the interface's carrier - my $carrier_file = "/sys/class/net/".$this_device."/carrier"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { carrier_file => $carrier_file }}); - - if (-e $carrier_file) - { - my $carrier = $anvil->Storage->read_file({debug => $debug, file => $carrier_file}); - chomp $carrier; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { carrier => $carrier }}); - - $anvil->data->{bond_health}{$device}{interface}{$this_device}{carrier} = $carrier; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "bond_health::${device}::interface::${this_device}::carrier" => $anvil->data->{bond_health}{$device}{interface}{$this_device}{carrier}, - }}); - } - - my $operstate_file = "/sys/class/net/".$this_device."/operstate"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { operstate_file => $operstate_file }}); - - if (-e $operstate_file) - { - my $operstate = $anvil->Storage->read_file({debug => $debug, file => $operstate_file}); - chomp $operstate; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { operstate => $operstate }}); - - $anvil->data->{bond_health}{$device}{interface}{$this_device}{up} = $operstate eq "up" ? 1 : 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "bond_health::${device}::interface::${this_device}::operstate" => $anvil->data->{bond_health}{$device}{interface}{$this_device}{operstate}, - }}); - } - } - } - - # Read in the /proc file. - my $proc_file = "/proc/net/bonding/".$device; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { proc_file => $proc_file }}); - - my $in_link = ""; - my $file_body = $anvil->Storage->read_file({debug => $debug, file => $proc_file}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { file_body => $file_body }}); - foreach my $line (split/\n/, $file_body) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }}); - - if ($line =~ /Slave Interface: (.*)$/) - { - $in_link = $1; - $anvil->data->{bond_health}{$device}{active_links}++; - $anvil->data->{bond_health}{$device}{interface}{$in_link}{in_bond} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "bond_health::${device}::active_links" => $anvil->data->{bond_health}{$device}{active_links}, - "bond_health::${device}::interface::${in_link}::in_bond" => $anvil->data->{bond_health}{$device}{interface}{$in_link}{in_bond}, - }}); - next; - } - if (not $line) - { - $in_link = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_link => $in_link }}); - next; - } - if ($in_link) - { - if ($line =~ /MII Status: (.*)$/) - { - my $status = $1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { status => $status }}); - if ($status eq "up") - { - $anvil->data->{bond_health}{$device}{up_links}++; - $anvil->data->{bond_health}{$device}{interface}{$in_link}{up} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "bond_health::${device}::up_links" => $anvil->data->{bond_health}{$device}{up_links}, - "bond_health::${device}::interface::${in_link}::up" => $anvil->data->{bond_health}{$device}{interface}{$in_link}{up}, - }}); - } - else - { - $anvil->data->{bond_health}{$device}{interface}{$in_link}{up} = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "bond_health::${device}::interface::${in_link}::up" => $anvil->data->{bond_health}{$device}{interface}{$in_link}{up}, - }}); - } - next; - } - } - else - { - if ($line =~ /MII Status: (.*)$/) - { - my $status = $1; - $anvil->data->{bond_health}{$device}{up} = $status eq "up" ? 1 : 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - status => $status, - "bond_health::${device}::up" => $anvil->data->{bond_health}{$device}{up}, - }}); - next; - } - } - } - } - } - - # Before we check the bonds, check the bridges. Bonds won't come up if they're in a bridge that is - # down. - my $bridge_count = keys %{$anvil->data->{bridge_health}}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { bridge_count => $bridge_count }}); - if (($bridge_count) && (not $heal eq "none")) - { - foreach my $bridge (sort {$a cmp $b} keys %{$anvil->data->{bridge_health}}) - { - my $up = $anvil->data->{bridge_health}{$bridge}{up}; - my $name = $anvil->data->{bridge_health}{$bridge}{name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - bridge => $bridge, - name => $name, - up => $up, - }}); - - if (not $up) - { - # Try to recover the interface - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0632", variables => { bridge => $bridge }}); - - my $shell_call = $anvil->data->{path}{exe}{ifup}." ".$name; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }}); - - my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - 'output' => $output, - 'return_code' => $return_code, - }}); - } - } - } - - foreach my $bond (sort {$a cmp $b} keys %{$anvil->data->{bond_health}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "s1:bond_health::${bond}::name" => $anvil->data->{bond_health}{$bond}{name}, - "s2:bond_health::${bond}::up" => $anvil->data->{bond_health}{$bond}{up}, - "s3:bond_health::${bond}::configured_links" => $anvil->data->{bond_health}{$bond}{configured_links}, - "s4:bond_health::${bond}::active_links" => $anvil->data->{bond_health}{$bond}{active_links}, - "s5:bond_health::${bond}::up_links" => $anvil->data->{bond_health}{$bond}{up_links}, - }}); - foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{bond_health}{$bond}{interface}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "s1:bond_health::${bond}::interface::${interface}::name" => $anvil->data->{bond_health}{$bond}{interface}{$interface}{name}, - "s2:bond_health::${bond}::interface::${interface}::in_bond" => $anvil->data->{bond_health}{$bond}{interface}{$interface}{in_bond}, - "s3:bond_health::${bond}::interface::${interface}::up" => $anvil->data->{bond_health}{$bond}{interface}{$interface}{up}, - "s4:bond_health::${bond}::interface::${interface}::carrier" => $anvil->data->{bond_health}{$bond}{interface}{$interface}{carrier}, - }}); - } - - if ($anvil->data->{bond_health}{$bond}{configured_links} != $anvil->data->{bond_health}{$bond}{up_links}) - { - next if $heal eq "none"; - next if (($anvil->data->{bond_health}{$bond}{up}) && ($heal eq "down_only")); - - # Log that we're going to try to heal this bond. - if ($heal eq "down_only") - { - # Log that we're healing fully down bonds. - $repaired = 1; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0627", variables => { bond => $bond }}); - } - else - { - # Log that we're healing all bond links - $repaired = 1; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0628", variables => { bond => $bond }}); - } - - # For good measure, try to up the bond as well. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0630", variables => { bond => $bond }}); - - my $shell_call = $anvil->data->{path}{exe}{ifup}." ".$anvil->data->{bond_health}{$bond}{name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }}); - - my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - 'output' => $output, - 'return_code' => $return_code, - }}); - - # If we're here, try to bring up down'ed interfaces. - foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{bond_health}{$bond}{interface}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "s2:bond_health::${bond}::interface::${interface}::in_bond" => $anvil->data->{bond_health}{$bond}{interface}{$interface}{in_bond}, - "s4:bond_health::${bond}::interface::${interface}::carrier" => $anvil->data->{bond_health}{$bond}{interface}{$interface}{carrier}, - }}); - if ((not $anvil->data->{bond_health}{$bond}{interface}{$interface}{in_bond}) && ($anvil->data->{bond_health}{$bond}{interface}{$interface}{carrier})) - { - # Link shown, try to start the interface. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0629", variables => { - bond => $bond, - interface => $interface." (".$anvil->data->{bond_health}{$bond}{interface}{$interface}{name}.")", - }}); - - my $shell_call = $anvil->data->{path}{exe}{ifup}." ".$anvil->data->{bond_health}{$bond}{interface}{$interface}{name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { shell_call => $shell_call }}); - - my ($output, $return_code) = $anvil->System->call({debug => 1, shell_call => $shell_call}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - 'output' => $output, - 'return_code' => $return_code, - }}); - } - } - } - } - - return($repaired); -} - - =head2 check_internet This method tries to connect to the internet. If successful, C<< 1 >> is returned. Otherwise, C<< 0 >> is returned. diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 71fb69d9..ec43f305 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -334,15 +334,13 @@ sub set_delay return($delay); } -### NOTE: This used to call 'Network->check_network', which is now 'scan_network' and no longer tries to -### bring up downed connections. Likely this entire method can be removed, now that we're not using -### ifcfg-X files. # This checks to see if it's time to see if the network is ok and, if the system has been up long enough, # checks and tries to repair network issues. sub check_network { my ($anvil) = @_; + ### TODO: Remove this when EL8 support is dropped. This was an issue with the old ifcfg configured bonds # The network sometimes doesn't come up, but we don't want to try recovering it too soon. As such, # we'll start watching the network after the uptime is 2 minutes. my $uptime = $anvil->Get->uptime;