* Working on timing for DB connections.

* Created a new tool (that may go away) for monitoring for network changes as quickly and with as few resources as possible.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent f72d8e0f70
commit fe4a1d5a1c
  1. 14
      Anvil/Tools/Database.pm
  2. 8
      Anvil/Tools/Get.pm
  3. 41
      Anvil/Tools/System.pm
  4. 7
      notes
  5. 111
      tools/anvil-scan-network
  6. 8
      tools/anvil-update-states

@ -8,6 +8,7 @@ use warnings;
use DBI;
use Scalar::Util qw(weaken isweak);
use Data::Dumper;
use Time::HiRes qw(gettimeofday tv_interval);
our $VERSION = "3.0.0";
my $THIS_FILE = "Database.pm";
@ -637,6 +638,9 @@ sub connect
test_table => $test_table,
}});
my $start_time = [gettimeofday];
print "Start time: [".$start_time->[0].".".$start_time->[1]."]\n";
$anvil->data->{sys}{db_timestamp} = "" if not defined $anvil->data->{sys}{db_timestamp};
# We need the host_uuid before we connect.
@ -715,10 +719,15 @@ sub connect
db_connect_string => $db_connect_string,
"database::${id}::ping_before_connect" => $anvil->data->{database}{$id}{ping_before_connect},
}});
if ($anvil->data->{database}{$id}{ping_before_connect})
#if ($anvil->data->{database}{$id}{ping_before_connect})
if (0)
{
# Can I ping?
my ($pinged) = $anvil->System->ping({ping => $host, count => 1});
my $ping_time = tv_interval ($start_time, [gettimeofday]);
print "[".$ping_time."] - Pinged: [$host:$port:$name:$user]\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { pinged => $pinged }});
if (not $pinged)
{
@ -945,6 +954,9 @@ sub connect
}
}
my $total = tv_interval ($start_time, [gettimeofday]);
print "Total runtime: [".$total."]\n";
# Do I have any connections? Don't die, if not, just return.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { connections => $connections }});
if (not $connections)

@ -115,7 +115,7 @@ sub anvil_version
my $debug = $parameter->{debug} ? $parameter->{debug} : 2;
my $password = $parameter->{password} ? $parameter->{password} : "";
my $port = $parameter->{port} ? $parameter->{port} : "";
my $target = $parameter->{target} ? $parameter->{target} : "";
my $target = $parameter->{target} ? $parameter->{target} : "local";
my $version = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
password => $anvil->Log->secure ? $password : "--",
@ -128,9 +128,9 @@ sub anvil_version
{
# Remote call.
my $shell_call = "
if [ -e ".$anvil->data->{path}{exe}{'anvil.version'}." ];
if [ -e ".$anvil->data->{path}{configs}{'anvil.version'}." ];
then
cat ".$anvil->data->{path}{exe}{'anvil.version'}.";
cat ".$anvil->data->{path}{configs}{'anvil.version'}.";
else
echo 0;
fi;
@ -147,7 +147,7 @@ fi;
else
{
# Local.
$version = $anvil->Storage->read_file({file => $anvil->data->{path}{exe}{'anvil.version'}});
$version = $anvil->Storage->read_file({file => $anvil->data->{path}{configs}{'anvil.version'}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { version => $version }});
# Did we actually read a version?

@ -8,6 +8,7 @@ use warnings;
use Data::Dumper;
use Net::SSH2;
use Scalar::Util qw(weaken isweak);
use Time::HiRes qw(gettimeofday tv_interval);
our $VERSION = "3.0.0";
my $THIS_FILE = "System.pm";
@ -846,6 +847,12 @@ sub ping
my $parameter = shift;
my $anvil = $self->parent;
# my $start_time = [gettimeofday];
# print "Start time: [".$start_time->[0].".".$start_time->[1]."]\n";
#
# my $ping_time = tv_interval ($start_time, [gettimeofday]);
# print "[".$ping_time."] - Pinged: [$host]\n";
# If we were passed a target, try pinging from it instead of locally
my $count = $parameter->{count} ? $parameter->{count} : 1; # How many times to try to ping it? Will exit as soon as one succeeds
my $debug = $parameter->{debug} ? $parameter->{deug} : 3;
@ -874,7 +881,7 @@ sub ping
# Build the call. Note that we use 'timeout' because if there is no connection and the hostname is
# used to ping and DNS is not available, it could take upwards of 30 seconds time timeout otherwise.
my $shell_call = $anvil->data->{path}{exe}{timeout}." 2 ".$anvil->data->{path}{exe}{'ping'}." -W 1 -n $ping -c 1";
my $shell_call = $anvil->data->{path}{exe}{timeout}." 1 ".$anvil->data->{path}{exe}{'ping'}." -W 1 -n $ping -c 1";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
if (not $fragment)
{
@ -1176,7 +1183,17 @@ sub remote_call
}
# Make sure the port is valid.
if (($port !~ /^\d+$/) or ($port < 0) or ($port > 65536))
if ($port eq "")
{
$port = 22;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { port => $port }});
}
elsif ($port !~ /^\d+$/)
{
$port = getservbyname($port, 'tcp');
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { port => $port }});
}
if ((not defined $port) or (($port !~ /^\d+$/) or ($port < 0) or ($port > 65536)))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0058", variables => { port => $port }});
return("!!error!!");
@ -1212,11 +1229,20 @@ sub remote_call
# If I don't already have an active SSH file handle, connect now.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { ssh_fh => $ssh_fh }});
if ($ssh_fh !~ /^Net::SSH2/)
{
$ssh_fh = Net::SSH2->new();
if (not $ssh_fh->connect($target, $port, Timeout => 10))
### NOTE: Nevermind, timeout isn't supported... >_< Find a newer version if IO::Socket::IP?
### TODO: Make the timeout user-configurable to handle slow connections. Make it
### 'sys::timeout::{all|host} = x'
my $start_time = [gettimeofday];
$ssh_fh = Net::SSH2->new(timeout => 1000);
if (not $ssh_fh->connect($target, $port))
{
my $connect_time = tv_interval ($start_time, [gettimeofday]);
print "[".$connect_time."] - Connection failed time to: [$target:$port]\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", list => {
user => $user,
target => $target,
@ -1249,10 +1275,13 @@ sub remote_call
{
$message_key = "message_0004";
}
$error = $anvil->Words->string({key => $message_key, variables => { $variables }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => $message_key, variables => { $variables }});
$error = $anvil->Words->string({key => $message_key, variables => $variables});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => $message_key, variables => $variables});
}
my $connect_time = tv_interval ($start_time, [gettimeofday]);
print "[".$connect_time."] - Connect time to: [$target:$port]\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $log_level, list => { error => $error, ssh_fh => $ssh_fh }});
if (not $error)
{

@ -1,5 +1,12 @@
All systems have a UUID, even VMs. Use that for system UUID in the future.
virt-manager stores information in dconf-editor -> /org/virt-manager/virt-manager/connections ($HOME/.config/dconf/user)
==== dconf read /org/virt-manager/virt-manager/connections/uris
['qemu+ssh://root@localhost/system', 'qemu+ssh://root@wp-a01n02.remote/system', 'qemu+ssh://root@an-nas02.kw01.alteeve.ca/system', 'qemu+ssh://root@hb-a01n01.remote/system', 'qemu+ssh://root@hb-a01n02.remote/system', 'qemu:///system']
==== dconf read /org/virt-manager/virt-manager/connections/autoconnect
['qemu+ssh://root@localhost/system']
====

@ -0,0 +1,111 @@
#!/usr/bin/perl
#
# This daemon watches for network changes and updates a cache file when changes are found.
#
# NOTE: This daemon does NOT connect to the databases. This is meant to be as quick as possible and to use as
# few resources as possible. It will exit with 'ok' or 'change' depending on if something in the
# network changed.
#
# Exit codes;
# 0 = Normal exit
#
# TODO:
#
use strict;
use warnings;
use Time::HiRes qw(gettimeofday tv_interval);
my $start_time = [gettimeofday];
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();
$anvil->Log->level({set => 2});
scan($anvil);
my $total = tv_interval ($start_time, [gettimeofday]);
print "Total runtime: [".$total."]\n";
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Functions #
#############################################################################################################
sub scan
{
my ($anvil) = @_;
my $directory = $anvil->data->{path}{sysfs}{network_interfaces};
print $THIS_FILE." ".__LINE__."; directory: [".$directory."]\n";
local(*DIRECTORY);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, 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";
print $THIS_FILE." ".__LINE__."; full_path: [".$full_path."]\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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 $mac_address = -e $full_path."/address" ? $anvil->Storage->read_file({file => $full_path."/address"}) : "";
my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
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
if ($speed > 100000)
{
# NOTE: This is probably 0 now... Though someday >100 Gbps will be reasonable
# and we'll need to change this.
$speed = 0;
}
# Find the media, if possible.
my $media = "unknown";
my $shell_call = $anvil->data->{path}{exe}{ethtool}." $interface";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
my $ethtool = $anvil->System->call({shell_call => $shell_call});
foreach my $line (split/\n/, $ethtool)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }});
if ($line =~ /Supported ports: \[ (.*?) \]/i)
{
$media = lc($1);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { media => $media }});
last;
}
}
# Log
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
interface => $interface,
mac_address => $mac_address,
link_state => $link_state,
mtu => $mtu,
duplex => $duplex,
operational => $operational,
speed => $speed,
media => $media,
}});
}
}
closedir(DIRECTORY);
return(0);
}

@ -18,7 +18,6 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
}
my $anvil = Anvil::Tools->new();
print $THIS_FILE." ".__LINE__."; anvil: [".$anvil."]\n";
$anvil->Log->level({set => 2});
$anvil->Storage->read_config({file => "/etc/anvil/anvil.conf"});
@ -26,6 +25,7 @@ my $connections = $anvil->Database->connect({
sql_file => $anvil->data->{sys}{database}{schema},
test_table => "network_interfaces",
});
print $THIS_FILE." ".__LINE__."; connections: [".$connections."]\n";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0132", variables => { connections => $connections }});
if (not $connections)
@ -37,7 +37,7 @@ if (not $connections)
report_network($anvil);
exit(0);
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Functions #
@ -50,7 +50,7 @@ sub report_network
# Write out the data in json format.
my $directory = $anvil->data->{path}{sysfs}{network_interfaces};
print $THIS_FILE." ".__LINE__."; directory: [".$directory."]\n";
#print $THIS_FILE." ".__LINE__."; directory: [".$directory."]\n";
local(*DIRECTORY);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0018", variables => { directory => $directory }});
opendir(DIRECTORY, $directory);
@ -60,7 +60,7 @@ sub report_network
next if $file eq "..";
next if $file eq "lo";
my $full_path = "$directory/$file";
print $THIS_FILE." ".__LINE__."; full_path: [".$full_path."]\n";
#print $THIS_FILE." ".__LINE__."; full_path: [".$full_path."]\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { full_path => $full_path }});
if (-d $full_path)
{

Loading…
Cancel
Save