diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 9bda9807..4fa02d39 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -15680,6 +15680,15 @@ sub resync_databases return(0); } + # If we're hosting servers, don't resync. Too high of a risk of oom-killer being triggered. + my $server_count = $anvil->Server->count_servers({debug => $debug}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { server_count => $server_count }}); + if ($server_count) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0680", variables => { count => $server_count }}); + return(0); + } + ### NOTE: Don't sort this array, we need to resync in the order that the user passed the tables to us ### to avoid trouble with primary/foreign keys. # We're going to use the array of tables assembles by _find_behind_databases() stored in diff --git a/Anvil/Tools/Server.pm b/Anvil/Tools/Server.pm index 97d9a189..7ca03ec1 100644 --- a/Anvil/Tools/Server.pm +++ b/Anvil/Tools/Server.pm @@ -14,6 +14,7 @@ my $THIS_FILE = "Server.pm"; ### Methods; # active_migrations # boot_virsh +# count_servers # find # get_definition # get_runtime @@ -263,6 +264,74 @@ WHERE return($success); } + +=head2 count_servers + +This method counts the number of hosted servers and returns that number. If C<< virsh >> is not available, C<< 0 >> is returned. Note that it's B< possible >>, though unlikely on an Anvil!, that a qemu server is running outside C<< libvirtd >>. + +This method takes no parameters. + +=cut +sub count_servers +{ + 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 => "Server->count_servers()" }}); + + my $count = 0; + if (-e $anvil->data->{path}{exe}{virsh}) + { + my $shell_call = $anvil->data->{path}{exe}{virsh}." list"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }}); + my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, debug => $debug}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + output => $output, + return_code => $return_code, + }}); + + foreach my $line (split/\n/, $output) + { + $line = $anvil->Words->clean_spaces({string => $line}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }}); + + if ($line =~ /^\d+ (.*) (.*?)$/) + { +=cut +* Server states; +running - The domain is currently running on a CPU +idle - The domain is idle, and not running or runnable. This can be caused because the domain is waiting on IO (a traditional wait state) or has gone to sleep because there was nothing else for it to do. +paused - The domain has been paused, usually occurring through the administrator running virsh suspend. When in a paused state the domain will still consume allocated resources like memory, but will not be eligible for scheduling by the hypervisor. +in shutdown - The domain is in the process of shutting down, i.e. the guest operating system has been notified and should be in the process of stopping its operations gracefully. +shut off - The domain is not running. Usually this indicates the domain has been shut down completely, or has not been started. +crashed - The domain has crashed, which is always a violent ending. Usually this state can only occur if the domain has been configured not to restart on crash. +pmsuspended - The domain has been suspended by guest power management, e.g. entered into s3 state. +=cut + my $name = $1; + my $status = $2; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + status => $status, + name => $name, + }}); + + if ((lc($status) eq "running") or + (lc($status) eq "paused") or + (lc($status) eq "in shutdown") or + (lc($status) eq "pmsuspended")) + { + $count++; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }}); + } + } + } + + } + + return($count); +} + + =head2 find This will look on the local or a remote machine for the list of servers that are running. diff --git a/share/words.xml b/share/words.xml index 54e38203..ad92ad88 100644 --- a/share/words.xml +++ b/share/words.xml @@ -16,7 +16,7 @@ Author: Madison Kelly Anvil! Striker ScanCore - Alteeve's Niche! Inc., Toronto, Ontario, Canada]]> + Alteeve's Niche! Inc., Toronto, Ontario, Canada]]> Anvil!]]> Node DR Host @@ -2071,6 +2071,7 @@ The file: [#!variable!file!#] needs to be updated. The difference is: Found an installable DRBD kernel module RPM that matches the current kernel. Installing it now. [ Note ] - We need to build the DRBD kernel module. This can take a few minutes, please be patient! Use 'journalctl -f' to monitor the build process. Successfully built and installed the new DRBD kernel module! + We were asked to resync the database, but this host is hosting: [#!variable!count!#] server(s). Resync is not allowed when servers are running to reduce the risk the kernel's out of memory handler shooting a VM if the resync consumes too much RAM. You can see which servers are running with 'virsh list' and look for servers whose states are "running", "paused", "in shutdown" or "pmsuspended". The host name: [#!variable!target!#] does not resolve to an IP address. @@ -3096,7 +3097,7 @@ We will sleep a bit and try again. [ Warning ] - The storage group: [#!variable!storage_group_name!#] had the host: [#!variable!host_name!#] as a member. This host is not a member (anymore?) of the Anvil!: [#!variable!anvil_name!#]. Removing it from the storage group now. [ Warning ] - The postgresql server is not installed yet. Sleeping for a bit, then will check again. - [ Warning ] - Failed to build or install the DRBD kernel module! It is very likely that this machine will be able to run any servers until this is fixed. + [ Warning ] - Failed to build or install the DRBD kernel module! It is very unlikely that this machine will be able to run any servers until this is fixed. @@ -3826,7 +3827,7 @@ We will sleep a bit and try again. Anvil! ストライカ スカンコア - Alteeve's Niche! Inc., トロント、オンタリオ、カナダ]]> + Alteeve's Niche! Inc., トロント、オンタリオ、カナダ]]> diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 8b1aa0b0..f4d4e6d3 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -276,7 +276,7 @@ sub check_if_mapping # shouldn't fire in practice). my $expire_age = 86400; my $map_network_age = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 's1:map_network_value' => $map_network_value, 's2:map_network_mtime' => $map_network_mtime, 's3:map_network_modified_date' => $map_network_modified_date, diff --git a/tools/anvil-update-states b/tools/anvil-update-states index 5fa381d2..759a891d 100755 --- a/tools/anvil-update-states +++ b/tools/anvil-update-states @@ -42,6 +42,10 @@ process_interface_cache($anvil); update_network($anvil); # Write out the interface cache +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + "cache::new_file" => $anvil->data->{cache}{new_file}, + "path::data::network_cache" => $anvil->data->{path}{data}{network_cache}, +}}); $anvil->Storage->write_file({ debug => 3, body => $anvil->data->{cache}{new_file}, @@ -446,7 +450,14 @@ sub update_network if ($line =~ /Supported ports: \[ (.*?) \]/i) { $media = lc($1); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { media => $media }}); + $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; } } @@ -948,7 +959,7 @@ ORDER BY network_interface_bond_uuid => defined $row->[9] ? $row->[9] : 'NULL', network_interface_bridge_uuid => defined $row->[10] ? $row->[10] : 'NULL', }; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "network_interfaces::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_mac_address}, "network_interfaces::${network_interface_uuid}::network_interface_name" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_name}, "network_interfaces::${network_interface_uuid}::network_interface_speed" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_speed},