* Updated the pacemaker server config to drop the stop timeout to 5 minutes and the migration timeout to 10 minutes. This will avoid blocking the entire cluster when a stop or migrate operation times out. Will update scan-server to clean these up when they happen.

* Updated Database->archive_table() and ->_find_behind_databases() to loop through connected databases, instead of configured databases.
* Updated Network->get_ips() to only record the real MAC addresses on network interfaces (not bonds or bridges) in the "network::${host}::interface::${in_iface}::mac_address" hash. This should help avoid reboot loops caused by anvil-configure-host thinking the network needs to be reconfigured when it doesn't actually need to be.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent 63fc8aa23f
commit 80bdac8e34
  1. 2
      Anvil/Tools/Cluster.pm
  2. 6
      Anvil/Tools/Database.pm
  3. 75
      Anvil/Tools/Network.pm
  4. 2
      cgi-bin/striker
  5. 6
      tools/anvil-configure-host

@ -206,7 +206,7 @@ sub add_server
### an OS update in 24 hours, there's probably deeper issues.
### TODO: If the target_role is 'started' because the server was running, we may need to later do an
### update to set it to 'stopped' after we've verified it's in the cluster below.
my $resource_command = $anvil->data->{path}{exe}{pcs}." resource create ".$server_name." ocf:alteeve:server name=\"".$server_name."\" meta allow-migrate=\"true\" target-role=\"".$target_role."\" op monitor interval=\"60\" start timeout=\"300\" on-fail=\"block\" stop timeout=\"86400\" on-fail=\"block\" migrate_to timeout=\"86400\"";
my $resource_command = $anvil->data->{path}{exe}{pcs}." resource create ".$server_name." ocf:alteeve:server name=\"".$server_name."\" meta allow-migrate=\"true\" target-role=\"".$target_role."\" op monitor interval=\"60\" start timeout=\"60\" on-fail=\"block\" stop timeout=\"300\" on-fail=\"block\" migrate_to timeout=\"600\" on-fail=\"block\"";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { resource_command => $resource_command }});
my ($output, $return_code) = $anvil->System->call({shell_call => $resource_command});

@ -15995,7 +15995,7 @@ sub _archive_table
}});
# Loop through each database so that we archive from everywhere before resync'ing.
foreach my $uuid (keys %{$anvil->data->{database}})
foreach my $uuid (keys %{$anvil->data->{cache}{database_handle}})
{
# First, if this table doesn't have a history schema, exit.
my $vacuum = 0;
@ -16351,7 +16351,7 @@ sub _find_behind_databases
# Look at all the databases and find the most recent time stamp (and the ID of the DB).
my $source_updated_time = 0;
foreach my $uuid (keys %{$anvil->data->{database}})
foreach my $uuid (keys %{$anvil->data->{cache}{database_handle}})
{
my $database_name = defined $anvil->data->{database}{$uuid}{name} ? $anvil->data->{database}{$uuid}{name} : "#!string!log_0185!#";
my $database_user = defined $anvil->data->{database}{$uuid}{user} ? $anvil->data->{database}{$uuid}{user} : "#!string!log_0185!#";
@ -16498,7 +16498,7 @@ ORDER BY
}
# Are being asked to trigger a resync?
foreach my $uuid (keys %{$anvil->data->{database}})
foreach my $uuid (keys %{$anvil->data->{cache}{database_handle}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"switches::resync-db" => $anvil->data->{switches}{'resync-db'},

@ -1680,16 +1680,77 @@ sub get_ips
{
my $mac_address = $1;
$anvil->data->{network}{$host}{interface}{$in_iface}{mac_address} = $mac_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${host}::interface::${in_iface}::mtu" => $anvil->data->{network}{$host}{interface}{$in_iface}{mtu},
"network::${host}::interface::${in_iface}::mac_address" => $anvil->data->{network}{$host}{interface}{$in_iface}{mac_address},
}});
# Make it easy to look up an interface name based on a given MAC address.
$anvil->data->{network}{$host}{mac_address}{$mac_address}{interface} = $in_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${host}::mac_address::${mac_address}::interface" => $anvil->data->{network}{$host}{mac_address}{$mac_address}{interface},
}});
# If this is a bond or bridge, don't record the MAC address. It confuses things as
# they show the MAC of the active interface. If this is an interface, see if the file
# '/sys/class/net/<nic>/bonding_slave/perm_hwaddr' exists and, if so, read the MAC
# address from there. If not, read the MAC address from
# '/sys/class/net/<nic>/address'.
my $shell_call = 'IFACE='.$in_iface.'
if [ -e "$IFACE" ];
then
echo bridge;
elif [ -e "/proc/net/bonding/$IFACE" ];
then
echo bond;
elif [ -e "/sys/class/net/${IFACE}/bonding_slave/perm_hwaddr" ];
then
echo -n mac:
cat /sys/class/net/${IFACE}/bonding_slave/perm_hwaddr;
else
echo -n mac:
cat /sys/class/net/${IFACE}/address;
fi';
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
if ($is_local)
{
# Local call.
($output, my $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:return_code' => $return_code,
}});
}
else
{
# Remote call
($output, my $error, my $return_code) = $anvil->Remote->call({
debug => $debug,
shell_call => $shell_call,
target => $target,
user => $remote_user,
password => $password,
remote_user => $remote_user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:output' => $output,
's2:error' => $error,
's3:return_code' => $return_code,
}});
}
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /^mac:(.*)$/)
{
my $real_mac = $1;
$anvil->data->{network}{$host}{interface}{$in_iface}{mac_address} = $real_mac;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${host}::interface::${in_iface}::mac_address" => $anvil->data->{network}{$host}{interface}{$in_iface}{mac_address},
}});
# Make it easy to look up an interface name based on a given MAC
# address.
$anvil->data->{network}{$host}{mac_address}{$real_mac}{interface} = $in_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${host}::mac_address::${real_mac}::interface" => $anvil->data->{network}{$host}{mac_address}{$real_mac}{interface},
}});
}
}
}
if ($line =~ /mtu (\d+) /i)
{

@ -6662,7 +6662,7 @@ sub process_sync_page
}});
}
# This needs to be loaded into a hash by target, the sorted. We'll build the table on sort.
# This needs to be loaded into a hash by target, then sorted. We'll build the table on sort.
my $peer_table = "";
foreach my $uuid (keys %{$anvil->data->{database}})
{

@ -355,11 +355,11 @@ sub reconfigure_network
my $ip_key = $this_network."_ip";
my $bridge_key = $this_network."_create_bridge";
my $link1_mac = $anvil->data->{variables}{form}{config_step2}{$link1_key}{value};
my $is_gateway = $this_network eq $gateway_interface ? 1 : 0;
my $link2_mac = defined $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} : "";
my $is_gateway = $this_network eq $gateway_interface ? 1 : 0;
my $link2_mac = defined $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} : "";
my $old_link1_iface = $anvil->data->{network}{$local_host}{mac_address}{$link1_mac}{interface} ? $anvil->data->{network}{$local_host}{mac_address}{$link1_mac}{interface} : "";
my $old_link2_iface = defined $anvil->data->{network}{$local_host}{mac_address}{$link2_mac}{interface} ? $anvil->data->{network}{$local_host}{mac_address}{$link2_mac}{interface} : "";
my $bridge = defined $anvil->data->{variables}{form}{config_step2}{$bridge_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$bridge_key}{value} : 0;
my $bridge = defined $anvil->data->{variables}{form}{config_step2}{$bridge_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$bridge_key}{value} : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ip_key => $ip_key,
is_gateway => $is_gateway,

Loading…
Cancel
Save