From 7a7e3db0c15d1ad6c01e1a35f3d4e1f2809d83e7 Mon Sep 17 00:00:00 2001 From: Digimer Date: Tue, 30 Jul 2019 02:10:04 -0400 Subject: [PATCH] * Created DRBD->get_devices() that finds and maps the /dev/drbdX devices to their resources and backing LVs. * Got Server->get_status() and ->_parse_definition() pulling out all but the device bus data from the XML files. Under devices, started parsing, with 'channel' devices now being parsed. * Fixed a bug in several Storage->X calls where the test to see if a 'target' was the local host or not wasn't smart enough. * Purged 'ocs:alteeve:server' to prepare for the rewrite where a lot of the logic is being moved into the Anvil::Tools modules as their functionality will be needed elsewhere anyway. Signed-off-by: Digimer --- Anvil/Tools/DRBD.pm | 184 +++++- Anvil/Tools/Server.pm | 341 +++++++++- Anvil/Tools/Storage.pm | 16 +- cgi-bin/striker | 2 +- ocf/alteeve/server | 1388 +--------------------------------------- 5 files changed, 534 insertions(+), 1397 deletions(-) diff --git a/Anvil/Tools/DRBD.pm b/Anvil/Tools/DRBD.pm index 4452ebb0..8b0da831 100755 --- a/Anvil/Tools/DRBD.pm +++ b/Anvil/Tools/DRBD.pm @@ -12,7 +12,8 @@ our $VERSION = "3.0.0"; my $THIS_FILE = "DRBD.pm"; ### Methods; -# status +# get_devices +# get_status =pod @@ -73,6 +74,182 @@ sub parent # Public methods # ############################################################################################################# +=head2 get_devices + +This finds all of the configured '/dev/drbdX' devices and maps them to their resource names. + + +Parameters; + +=head3 password (optional) + +This is the password to use when connecting to a remote machine. If not set, but C<< target >> is, an attempt to connect without a password will be made. + +=head3 port (optional) + +This is the TCP port to use when connecting to a remote machine. If not set, but C<< target >> is, C<< 22 >> will be used. + +=head3 remote_user (optional, default 'root') + +If C<< target >> is set, this will be the user we connect to the remote machine as. + +=head3 target (optional) + +This is the IP or host name of the machine to read the version of. If this is not set, the local system's version is checked. + +=cut +sub get_devices +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + + my $password = defined $parameter->{password} ? $parameter->{password} : ""; + my $port = defined $parameter->{port} ? $parameter->{port} : ""; + my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root"; + my $target = defined $parameter->{target} ? $parameter->{target} : "local"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + password => $anvil->Log->secure ? $password : $anvil->Words->string({key => "log_0186"}), + port => $port, + remote_user => $remote_user, + target => $target, + }}); + + # Clear the hash where we'll store the data. + if (exists $anvil->data->{drbd}{'dump-xml'}) + { + delete $anvil->data->{drbd}{'dump-xml'}; + } + + # Is this a local call or a remote call? + my $shell_call = $anvil->data->{path}{exe}{drbdadm}." dump-xml"; + my $output = ""; + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) + { + # Remote call. + ($output, my $error, $anvil->data->{drbd}{'drbdadm-xml'}{return_code}) = $anvil->Remote->call({ + debug => $debug, + shell_call => $shell_call, + target => $target, + port => $port, + password => $password, + remote_user => $remote_user, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + error => $error, + output => $output, + "drbd::drbdadm-xml::return_code" => $anvil->data->{drbd}{'drbdadm-xml'}{return_code}, + }}); + } + else + { + # Local. + ($output, $anvil->data->{drbd}{'drbdadm-xml'}{return_code}) = $anvil->System->call({shell_call => $shell_call}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + output => $output, + "drbd::drbdadm-xml::return_code" => $anvil->data->{drbd}{'drbdadm-xml'}{return_code}, + }}); + } + + my $xml = XML::Simple->new(); + my $dump_xml = ""; + eval { $dump_xml = $xml->XMLin($output, KeyAttr => {}, ForceArray => 1) }; + if ($@) + { + chomp $@; + my $error = "[ Error ] - The was a problem parsing: [$output]. The error was:\n"; + $error .= "===========================================================\n"; + $error .= $@."\n"; + $error .= "===========================================================\n"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { error => $error }}); + $anvil->nice_exit({exit_code => 1}); + } + + $anvil->data->{drbd}{'dump-xml'}{parsed} = $dump_xml; + $anvil->data->{drbd}{config}{'auto-promote'} = 0; + + foreach my $hash_ref (@{$dump_xml->{resource}}) + { + my $this_resource = $hash_ref->{name}; + foreach my $connection_href (@{$hash_ref->{connection}}) + { + foreach my $host_href (@{$connection_href->{host}}) + { + my $host = $host_href->{name}; + my $port = $host_href->{address}->[0]->{port}; + my $ip_address = $host_href->{address}->[0]->{content}; + $anvil->data->{drbd}{config}{$this_resource}{connection}{$host}{ip_family} = $host_href->{address}->[0]->{family}; + $anvil->data->{drbd}{config}{$this_resource}{connection}{$host}{ip_address} = $host_href->{address}->[0]->{content}; + $anvil->data->{drbd}{config}{$this_resource}{connection}{$host}{port} = $port; + $anvil->data->{drbd}{ip_addresses}{$ip_address} = 1; + $anvil->data->{drbd}{tcp_ports}{$port} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "drbd::config::${this_resource}::connection::${host}::ip_family" => $anvil->data->{drbd}{config}{$this_resource}{connection}{$host}{ip_family}, + "drbd::config::${this_resource}::connection::${host}::ip_address" => $anvil->data->{drbd}{config}{$this_resource}{connection}{$host}{ip_address}, + "drbd::config::${this_resource}::connection::${host}::port" => $anvil->data->{drbd}{config}{$this_resource}{connection}{$host}{port}, + "drbd::ip_addresses::${ip_address}" => $anvil->data->{drbd}{ip_addresses}{$ip_address}, + "drbd::tcp_ports::${port}" => $anvil->data->{drbd}{tcp_ports}{$port}, + }}); + } + foreach my $section_href (@{$connection_href->{section}}) + { + my $section = $section_href->{name}; + foreach my $option_href (@{$section_href->{option}}) + { + my $variable = $option_href->{name}; + $anvil->data->{drbd}{config}{$this_resource}{section}{$section}{$variable} = $option_href->{value}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "drbd::config::${this_resource}::section::${section}::${variable}" => $anvil->data->{drbd}{config}{$this_resource}{section}{$section}{$variable}, + }}); + } + } + } + + foreach my $host_href (@{$hash_ref->{host}}) + { + ### TODO: Handle external metadata + my $host = $host_href->{name}; + my $local = 0; + if (($host eq $anvil->_hostname) or ($host eq $anvil->_short_hostname)) + { + $local = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'local' => $local }}); + } + foreach my $volume_href (@{$host_href->{volume}}) + { + my $volume = $volume_href->{vnr}; + my $drbd_path = $volume_href->{device}->[0]->{content}; + my $lv_path = $volume_href->{disk}->[0]; + $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{drbd_path} = $drbd_path; + $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{drbd_minor} = $volume_href->{device}->[0]->{minor}; + $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{'meta-disk'} = $volume_href->{'meta-disk'}->[0]; + $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{backing_lv} = $lv_path; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "drbd::config::${this_resource}::volume::${volume}::drbd_path" => $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{drbd_path}, + "drbd::config::${this_resource}::volume::${volume}::drbd_minor" => $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{drbd_minor}, + "drbd::config::${this_resource}::volume::${volume}::meta-disk" => $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{'meta-disk'}, + "drbd::config::${this_resource}::volume::${volume}::backing_lv" => $anvil->data->{drbd}{config}{$this_resource}{volume}{$volume}{backing_lv}, + }}); + if ($local) + { + $anvil->data->{drbd}{'local'}{drbd_path}{$drbd_path}{on} = $lv_path; + $anvil->data->{drbd}{'local'}{drbd_path}{$drbd_path}{resource} = $this_resource; + $anvil->data->{drbd}{'local'}{lv_path}{$lv_path}{under} = $drbd_path; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "drbd::local::drbd_path::${drbd_path}::on" => $anvil->data->{drbd}{'local'}{drbd_path}{$drbd_path}{on}, + "drbd::local::drbd_path::${drbd_path}::resource" => $anvil->data->{drbd}{'local'}{drbd_path}{$drbd_path}{resource}, + "drbd::local::lv_path::${lv_path}::under" => $anvil->data->{drbd}{'local'}{lv_path}{$lv_path}{under}, + }}); + } + } + } + } + + return(0); +} + + =head2 get_status This parses the DRBD status on the local or remote system. The data collected is stored in the following hashes; @@ -161,7 +338,10 @@ sub get_status # Local. ($output, $anvil->data->{drbd}{status}{return_code}) = $anvil->System->call({shell_call => $shell_call}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + output => $output, + "drbd::status::${host}::return_code" => $anvil->data->{drbd}{status}{return_code}, + }}); } # Parse the output. diff --git a/Anvil/Tools/Server.pm b/Anvil/Tools/Server.pm index b9a5a09c..ef81793f 100755 --- a/Anvil/Tools/Server.pm +++ b/Anvil/Tools/Server.pm @@ -12,7 +12,7 @@ our $VERSION = "3.0.0"; my $THIS_FILE = "Server.pm"; ### Methods; -# status +# get_status =pod @@ -73,6 +73,14 @@ sub parent # Public methods # ############################################################################################################# +=head2 find + +This looks on an Anvil! for what servers are running where. + + + +=cut + =head2 get_status This reads in a server's XML definition file from disk, if available, and from memory, if the server is running. The XML is analyzed and data is stored in the following locations; @@ -132,15 +140,16 @@ sub get_status { delete $anvil->data->{server}{$server}; } + $anvil->data->{server}{$server}{from_memory}{host} = ""; # Is this a local call or a remote call? - my $shell_call = $anvil->data->{path}{exe}{virsh}." dumpxml ".$server; + my $shell_call = $anvil->data->{path}{exe}{virsh}." dumpxml ".$server; + my $host = $anvil->_short_hostname; if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # Remote call. $host = $target; - - ($anvil->data->{server}{$server}{running}{xml}, my $error, $anvil->data->{server}{$server}{running}{return_code}) = $anvil->Remote->call({ + ($anvil->data->{server}{$server}{from_memory}{xml}, my $error, $anvil->data->{server}{$server}{from_memory}{return_code}) = $anvil->Remote->call({ debug => $debug, shell_call => $shell_call, target => $target, @@ -150,28 +159,38 @@ sub get_status }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { error => $error, - "server::${server}::running::xml" => $anvil->data->{server}{$server}{running}{xml}, - "server::${server}::running::return_code" => $anvil->data->{server}{$server}{running}{return_code}, + "server::${server}::from_memory::xml" => $anvil->data->{server}{$server}{from_memory}{xml}, + "server::${server}::from_memory::return_code" => $anvil->data->{server}{$server}{from_memory}{return_code}, }}); } else { # Local. - ($anvil->data->{server}{$server}{running}{xml}, $anvil->data->{server}{$server}{running}{return_code}) = $anvil->System->call({shell_call => $shell_call}); + ($anvil->data->{server}{$server}{from_memory}{xml}, $anvil->data->{server}{$server}{from_memory}{return_code}) = $anvil->System->call({shell_call => $shell_call}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "server::${server}::running::xml" => $anvil->data->{server}{$server}{running}{xml}, - "server::${server}::running::return_code" => $anvil->data->{server}{$server}{running}{return_code}, + "server::${server}::from_memory::xml" => $anvil->data->{server}{$server}{from_memory}{xml}, + "server::${server}::from_memory::return_code" => $anvil->data->{server}{$server}{from_memory}{return_code}, }}); } # If the return code was non-zero, we can't parse the XML. - if ($anvil->data->{server}{$server}{running}{return_code}) + if ($anvil->data->{server}{$server}{from_memory}{return_code}) { - $anvil->data->{server}{$server}{running}{xml} = ""; + $anvil->data->{server}{$server}{from_memory}{xml} = ""; + } + else + { + $anvil->data->{server}{$server}{from_memory}{host} = $host; + $anvil->Server->_parse_definition({ + debug => $debug, + server => $server, + source => "from_memory", + definition => $anvil->data->{server}{$server}{from_memory}{xml}, + }); } # Now get the on-disk XML. - ($anvil->data->{server}{$server}{disk}{xml}) = $anvil->Storage->read_file({ + ($anvil->data->{server}{$server}{from_disk}{xml}) = $anvil->Storage->read_file({ debug => $debug, password => $password, port => $port, @@ -179,10 +198,19 @@ sub get_status target => $target, force_read => 1, file => $anvil->data->{path}{directories}{shared}{definitions}."/".$server.".xml", - }) + }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "server::${server}::disk::xml" => $anvil->data->{server}{$server}{disk}{xml}, }}); + if ($anvil->data->{server}{$server}{disk}{xml}) + { + $anvil->Server->_parse_definition({ + debug => $debug, + server => $server, + source => "from_disk", + definition => $anvil->data->{server}{$server}{from_disk}{xml}, + }); + } return(0); } @@ -196,3 +224,290 @@ sub get_status ############################################################################################################# # Private functions # ############################################################################################################# + +### NOTE: This is a work in progress. As of now, it parses out what ocf:alteeve:server needs. +# This pulls apart specific data out of a definition file. +sub _parse_definition +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + + # Source is required. + my $server = defined $parameter->{server} ? $parameter->{server} : ""; + my $source = defined $parameter->{source} ? $parameter->{source} : ""; + my $definition = defined $parameter->{definition} ? $parameter->{definition} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + source => $source, + definition => $definition, + }}); + + if (not $server) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Server->_parse_definition()", parameter => "server" }}); + return(1); + } + if (not $source) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Server->_parse_definition()", parameter => "source" }}); + return(1); + } + if (not $definition) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Server->_parse_definition()", parameter => "definition" }}); + return(1); + } + + # We're going to map DRBD devices to resources, so we need to collect that data now. + $anvil->DRBD->get_devices({debug => $debug}); + + my $xml = XML::Simple->new(); + my $server_xml = ""; + eval { $server_xml = $xml->XMLin($definition, KeyAttr => {}, ForceArray => 1) }; + if ($@) + { + chomp $@; + my $error = "[ Error ] - The was a problem parsing: [$definition]. The error was:\n"; + $error .= "===========================================================\n"; + $error .= $@."\n"; + $error .= "===========================================================\n"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", list => { error => $error }}); + $anvil->nice_exit({exit_code => 1}); + } + + $anvil->data->{server}{$server}{$source}{parsed} = $server_xml; + #print Dumper $server_xml; + + # Find what drives (disk and "optical") this server uses. + foreach my $device_ref (@{$server_xml->{devices}}) + { + foreach my $disk_ref (@{$device_ref->{disk}}) + { + my $type = $disk_ref->{device}; + my $bus = $disk_ref->{target}->[0]->{bus}; + my $target = $disk_ref->{target}->[0]->{dev}; + my $boot_order = defined $disk_ref->{boot}->[0]->{order} ? $disk_ref->{boot}->[0]->{order} : 99; + my $alias = $disk_ref->{alias}->[0]->{name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + type => $type, + bus => $bus, + target => $target, + alias => $alias, + }}); + + if ($type eq "disk") + { + foreach my $source_ref (@{$disk_ref->{source}}) + { + my $device_path = $source_ref->{dev}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { device_path => $device_path }}); + + $anvil->data->{server}{$server}{$source}{disk}{$device_path}{on_lv} = defined $anvil->data->{drbd}{'local'}{drbd_path}{$device_path}{on} ? $anvil->data->{drbd}{'local'}{drbd_path}{$device_path}{on} : ""; + $anvil->data->{server}{$server}{$source}{disk}{$device_path}{resource} = defined $anvil->data->{drbd}{'local'}{drbd_path}{$device_path}{resource} ? $anvil->data->{drbd}{'local'}{drbd_path}{$device_path}{resource} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::optical::${device_path}::on_lv" => $anvil->data->{server}{$server}{$source}{disk}{$device_path}{on_lv}, + "server::${server}::${source}::optical::${device_path}::resource" => $anvil->data->{server}{$server}{$source}{disk}{$device_path}{resource}, + }}); + } + } + elsif ($type eq "cdrom") + { + foreach my $source_ref (@{$disk_ref->{source}}) + { + my $file = defined $source_ref->{file} ? $source_ref->{file} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { file => $file }}); + + $anvil->data->{server}{$server}{$source}{optical}{$file} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "server::${server}::${source}::optical::${file}" => $anvil->data->{server}{$server}{$source}{optical}{$file} }}); + } + } + } + } + + # Pull out some basic server info. + $anvil->data->{server}{$server}{$source}{info}{uuid} = $server_xml->{uuid}->[0]; + $anvil->data->{server}{$server}{$source}{info}{name} = $server_xml->{name}->[0]; + $anvil->data->{server}{$server}{$source}{info}{on_poweroff} = $server_xml->{on_poweroff}->[0]; + $anvil->data->{server}{$server}{$source}{info}{on_crash} = $server_xml->{on_crash}->[0]; + $anvil->data->{server}{$server}{$source}{info}{on_reboot} = $server_xml->{on_reboot}->[0]; + $anvil->data->{server}{$server}{$source}{info}{boot_menu} = $server_xml->{os}->[0]->{bootmenu}->[0]->{enable}; + $anvil->data->{server}{$server}{$source}{info}{id} = $server_xml->{id}; + $anvil->data->{server}{$server}{$source}{info}{emulator} = $server_xml->{devices}->[0]->{emulator}->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::info::uuid" => $anvil->data->{server}{$server}{$source}{info}{uuid}, + "server::${server}::${source}::info::name" => $anvil->data->{server}{$server}{$source}{info}{name}, + "server::${server}::${source}::info::on_poweroff" => $anvil->data->{server}{$server}{$source}{info}{on_poweroff}, + "server::${server}::${source}::info::on_crash" => $anvil->data->{server}{$server}{$source}{info}{on_crash}, + "server::${server}::${source}::info::on_reboot" => $anvil->data->{server}{$server}{$source}{info}{on_reboot}, + "server::${server}::${source}::info::boot_menu" => $anvil->data->{server}{$server}{$source}{info}{boot_menu}, + "server::${server}::${source}::info::id" => $anvil->data->{server}{$server}{$source}{info}{id}, + "server::${server}::${source}::info::emulator" => $anvil->data->{server}{$server}{$source}{info}{emulator}, + }}); + + # CPU + $anvil->data->{server}{$server}{$source}{cpu}{total_cores} = $server_xml->{vcpu}->[0]->{content}; + $anvil->data->{server}{$server}{$source}{cpu}{sockets} = $server_xml->{cpu}->[0]->{topology}->[0]->{sockets}; + $anvil->data->{server}{$server}{$source}{cpu}{cores} = $server_xml->{cpu}->[0]->{topology}->[0]->{cores}; + $anvil->data->{server}{$server}{$source}{cpu}{threads} = $server_xml->{cpu}->[0]->{topology}->[0]->{threads}; + $anvil->data->{server}{$server}{$source}{cpu}{model_name} = $server_xml->{cpu}->[0]->{model}->[0]->{content}; + $anvil->data->{server}{$server}{$source}{cpu}{model_fallback} = $server_xml->{cpu}->[0]->{model}->[0]->{fallback}; + $anvil->data->{server}{$server}{$source}{cpu}{match} = $server_xml->{cpu}->[0]->{match}; + $anvil->data->{server}{$server}{$source}{cpu}{vendor} = $server_xml->{cpu}->[0]->{vendor}->[0]; + $anvil->data->{server}{$server}{$source}{cpu}{mode} = $server_xml->{cpu}->[0]->{mode}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::cpu::total_cores" => $anvil->data->{server}{$server}{$source}{cpu}{total_cores}, + "server::${server}::${source}::cpu::sockets" => $anvil->data->{server}{$server}{$source}{cpu}{sockets}, + "server::${server}::${source}::cpu::cores" => $anvil->data->{server}{$server}{$source}{cpu}{cores}, + "server::${server}::${source}::cpu::threads" => $anvil->data->{server}{$server}{$source}{cpu}{threads}, + "server::${server}::${source}::cpu::model_name" => $anvil->data->{server}{$server}{$source}{cpu}{model_name}, + "server::${server}::${source}::cpu::model_fallback" => $anvil->data->{server}{$server}{$source}{cpu}{model_fallback}, + "server::${server}::${source}::cpu::match" => $anvil->data->{server}{$server}{$source}{cpu}{match}, + "server::${server}::${source}::cpu::vendor" => $anvil->data->{server}{$server}{$source}{cpu}{vendor}, + "server::${server}::${source}::cpu::mode" => $anvil->data->{server}{$server}{$source}{cpu}{mode}, + }}); + foreach my $hash_ref (@{$server_xml->{cpu}->[0]->{feature}}) + { + my $name = $hash_ref->{name}; + $anvil->data->{server}{$server}{$source}{cpu}{feature}{$name} = $hash_ref->{policy}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::cpu::feature::${name}" => $anvil->data->{server}{$server}{$source}{cpu}{feature}{$name}, + }}); + + } + + # Power Management + $anvil->data->{server}{$server}{$source}{pm}{'suspend-to-disk'} = $server_xml->{pm}->[0]->{'suspend-to-disk'}->[0]->{enabled}; + $anvil->data->{server}{$server}{$source}{pm}{'suspend-to-mem'} = $server_xml->{pm}->[0]->{'suspend-to-mem'}->[0]->{enabled}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::pm::suspend-to-disk" => $anvil->data->{server}{$server}{$source}{pm}{'suspend-to-disk'}, + "server::${server}::${source}::pm::suspend-to-mem" => $anvil->data->{server}{$server}{$source}{pm}{'suspend-to-mem'}, + }}); + + # RAM - 'memory' is as set at boot, 'currentMemory' is the RAM used at polling (so only useful when + # running). In the Anvil!, we don't support memory ballooning, so we're use whichever is + # higher. + my $current_ram_value = $server_xml->{currentMemory}->[0]->{content}; + my $current_ram_unit = $server_xml->{currentMemory}->[0]->{unit}; + my $current_ram_bytes = $anvil->Convert->human_readable_to_bytes({size => $current_ram_value, type => $current_ram_unit}); + my $ram_value = $server_xml->{memory}->[0]->{content}; + my $ram_unit = $server_xml->{memory}->[0]->{unit}; + my $ram_bytes = $anvil->Convert->human_readable_to_bytes({size => $ram_value, type => $ram_unit}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + current_ram_value => $current_ram_value, + current_ram_unit => $current_ram_unit, + current_ram_bytes => $anvil->Convert->add_commas({number => $current_ram_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $current_ram_bytes}).")", + ram_value => $ram_value, + ram_unit => $ram_unit, + ram_bytes => $anvil->Convert->add_commas({number => $ram_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $ram_bytes}).")", + }}); + + $anvil->data->{server}{$server}{$source}{memory} = $current_ram_bytes > $ram_bytes ? $current_ram_bytes : $ram_bytes; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::memory" => $anvil->Convert->add_commas({number => $anvil->data->{server}{$server}{$source}{memory}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{server}{$server}{$source}{memory}}).")", + }}); + + # Pull out my channels + foreach my $hash_ref (@{$server_xml->{devices}->[0]->{channel}}) + { + my $type = $hash_ref->{type}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { type => $type }}); + if ($type eq "unix") + { + # Bus stuff + my $address_type = $hash_ref->{address}->[0]->{type}; + my $address_controller = $hash_ref->{address}->[0]->{controller}; + my $address_bus = $hash_ref->{address}->[0]->{bus}; + my $address_port = $hash_ref->{address}->[0]->{port}; + + # Store + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{source}{mode} = $hash_ref->{source}->[0]->{mode}; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{source}{path} = $hash_ref->{source}->[0]->{path}; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{alias} = $hash_ref->{alias}->[0]->{name}; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{type} = $address_type; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{bus} = $address_bus; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{controller} = $address_controller; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{port} = $address_port; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{target}{type} = $hash_ref->{target}->[0]->{type}; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{target}{'state'} = $hash_ref->{target}->[0]->{'state'}; + $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{target}{name} = $hash_ref->{target}->[0]->{name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::device::channel::unix::source::mode" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{source}{mode}, + "server::${server}::${source}::device::channel::unix::source::path" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{source}{path}, + "server::${server}::${source}::device::channel::unix::alias" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{alias}, + "server::${server}::${source}::device::channel::unix::address::type" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{type}, + "server::${server}::${source}::device::channel::unix::address::bus" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{bus}, + "server::${server}::${source}::device::channel::unix::address::controller" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{controller}, + "server::${server}::${source}::device::channel::unix::address::port" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{address}{port}, + "server::${server}::${source}::device::channel::unix::target::type" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{target}{type}, + "server::${server}::${source}::device::channel::unix::target::state" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{target}{'state'}, + "server::${server}::${source}::device::channel::unix::target::name" => $anvil->data->{server}{$server}{$source}{device}{channel}{unix}{target}{name}, + }}); + + # Add to system bus list + $anvil->data->{server}{$server}{$source}{address}{$address_type}{controller}{$address_controller}{bus}{$address_bus}{port}{$address_port} = "channel - ".$type; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::address::${address_type}::controller::${address_controller}::bus::${address_bus}::port::${address_port}" => $anvil->data->{server}{$server}{$source}{address}{$address_type}{controller}{$address_controller}{bus}{$address_bus}{port}{$address_port}, + }}); + } + elsif ($type eq "spicevmc") + { + # Bus stuff + my $address_type = $hash_ref->{address}->[0]->{type}; + my $address_controller = $hash_ref->{address}->[0]->{controller}; + my $address_bus = $hash_ref->{address}->[0]->{bus}; + my $address_port = $hash_ref->{address}->[0]->{port}; + + # Store + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{alias} = $hash_ref->{alias}->[0]->{name}; + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{type} = $address_type; + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{bus} = $address_bus; + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{controller} = $address_controller; + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{port} = $address_port; + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{target}{type} = $hash_ref->{target}->[0]->{type}; + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{target}{'state'} = $hash_ref->{target}->[0]->{'state'}; + $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{target}{name} = $hash_ref->{target}->[0]->{name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::device::channel::spicevmc::alias" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{alias}, + "server::${server}::${source}::device::channel::spicevmc::address::type" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{type}, + "server::${server}::${source}::device::channel::spicevmc::address::bus" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{bus}, + "server::${server}::${source}::device::channel::spicevmc::address::controller" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{controller}, + "server::${server}::${source}::device::channel::spicevmc::address::port" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{address}{port}, + "server::${server}::${source}::device::channel::spicevmc::target::type" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{target}{type}, + "server::${server}::${source}::device::channel::spicevmc::target::state" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{target}{'state'}, + "server::${server}::${source}::device::channel::spicevmc::target::name" => $anvil->data->{server}{$server}{$source}{device}{channel}{spicevmc}{target}{name}, + }}); + + # Add to system bus list + $anvil->data->{server}{$server}{$source}{address}{$address_type}{controller}{$address_controller}{bus}{$address_bus}{port}{$address_port} = "channel - ".$type; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "server::${server}::${source}::address::${address_type}::controller::${address_controller}::bus::${address_bus}::port::${address_port}" => $anvil->data->{server}{$server}{$source}{address}{$address_type}{controller}{$address_controller}{bus}{$address_bus}{port}{$address_port}, + }}); + } + } + die; + + # Pull out other devices + foreach my $device (sort {$a cmp $b} keys %{$server_xml->{devices}->[0]}) + { + next if $device eq "emulator"; + next if $device eq "channel"; + print "Device: [$device] -> [".$server_xml->{devices}->[0]->{$device}."] (".@{$server_xml->{devices}->[0]->{$device}}."))\n"; + + foreach my $hash_ref (@{$server_xml->{devices}->[0]->{$device}}) + { + # video, memballoon, rng and sound don't have type. + my $type = defined $hash_ref->{type} ? $hash_ref->{type} : ""; + print "- Type: [$type]\n"; + #print Dumper $hash_ref; + if ($type) + { + + } + } + } + + die; + + return(0); +} diff --git a/Anvil/Tools/Storage.pm b/Anvil/Tools/Storage.pm index 4ac9a97d..8fb1adc3 100644 --- a/Anvil/Tools/Storage.pm +++ b/Anvil/Tools/Storage.pm @@ -171,7 +171,7 @@ sub backup if ($fatal) { $anvil->nice_exit({code => 1}); } } - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # Make sure the source file exists, is a file and can be read. my $shell_call = " @@ -668,7 +668,7 @@ sub copy_file file => $file, }}); - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # Copying on a remote system. my $proceed = 1; @@ -984,7 +984,7 @@ sub make_directory $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { working_directory => $working_directory }}); # Are we working locally or remotely? - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # Assemble the command my $shell_call = " @@ -1193,7 +1193,7 @@ sub move_file }}); } - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # Copying on a remote system. my $proceed = 1; @@ -1561,7 +1561,7 @@ sub read_file } # Reading locally or remote? - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # Remote. Make sure the passed file is a full path and file name. if ($file !~ /^\/\w/) @@ -1913,7 +1913,7 @@ sub rsync # If local, call rsync directly. If remote, setup the rsync wrapper my $wrapper_script = ""; my $shell_call = $anvil->data->{path}{exe}{rsync}." ".$switches." ".$source." ".$destination; - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # If we didn't get a port, but the target is pre-configured for a port, use it. if ((not $parameter->{port}) && ($anvil->data->{hosts}{$target}{port})) @@ -2344,7 +2344,7 @@ sub update_config # Did we see the variable? if (not $seen) { - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0175", variables => { variable => $variable, @@ -2674,7 +2674,7 @@ sub write_file }}); # Now, are we writing locally or on a remote system? - if ($target) + if (($target) && ($target ne "local") && ($target ne $anvil->_hostname) && ($target ne $anvil->_short_hostname)) { # If we didn't get a port, but the target is pre-configured for a port, use it. if ((not $parameter->{port}) && ($anvil->data->{hosts}{$target}{port})) diff --git a/cgi-bin/striker b/cgi-bin/striker index 2a2def27..aa54310e 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -1041,11 +1041,11 @@ sub add_sync_peer password => $password, target => $ssh_tcp != 22 ? $host.":".$ssh_tcp : $host, shell_call => $shell_call, - return_code => $return_code, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output, error => $error, + return_code => $return_code, }}); if ($error) { diff --git a/ocf/alteeve/server b/ocf/alteeve/server index 97b5c5c0..3c77b48c 100755 --- a/ocf/alteeve/server +++ b/ocf/alteeve/server @@ -132,7 +132,6 @@ if ($anvil->data->{environment}{PCMK_debug}) # Get any command line switches. $anvil->Get->switches; - # Something for the logs if ((not $anvil->data->{switches}{metadaata}) and (not $anvil->data->{switches}{'meta-data'})) { @@ -313,6 +312,10 @@ sub start_server my $server = $anvil->data->{environment}{OCF_RESKEY_name}; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0303", variables => { server => $server }}); + # Make sure things are sane. + validate_all($anvil); + + die; # If we're still alive, then we didn't see the server in the list of running servers, which is really weird. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0311", variables => { server => $server }}); @@ -327,227 +330,6 @@ sub stop_server # Stopping the server is simply a question of "is the server running?" and, if so, stop it. Once # stopped, we stop the DRBD resource on both nodes. my $server = $anvil->data->{environment}{OCF_RESKEY_name}; - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list"}); - if ($return_code) - { - # Looks like virsh isn't running. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0312", variables => { return_code => $return_code, output => $output }}); - $anvil->nice_exit({exit_code => 1}); - } - - my $shutdown = 1; - my $found = 0; - foreach my $line (split/\n/, $output) - { - $line =~ s/^\s+//; - $line =~ s/\s+$//; - $line =~ s/\s+/ /g; - - if ($line =~ /^(\d+) $server (.*)$/) - { - my $state = $2; - $found = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - server => $server, - 'state' => $state, - }}); - - if ($state eq "running") - { - # The server is running, shut it down. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0313", variables => { server => $server }}); - } - elsif ($state eq "paused") - { - # The server is paused. Resume it, wait a few, then proceed with the shutdown. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0314", variables => { server => $server }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." resume $server"}); - if ($return_code) - { - # Looks like virsh isn't running. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0315", variables => { - server => $server, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0316"}); - sleep 3; - } - elsif ($state eq "pmsuspended") - { - # The server is paused. Resume it, wait a few, then proceed with the shutdown. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0317", variables => { server => $server }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." dompmwakeup $server"}); - if ($return_code) - { - # Looks like virsh isn't running. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0318", variables => { - server => $server, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0319"}); - sleep 30; - } - elsif ($state eq "in shutdown") - { - # The server is already shutting down - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0320", variables => { server => $server }}); - $shutdown = 0; - } - elsif ($state eq "shut off") - { - # The server is already shutting down - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0321", variables => { server => $server }}); - $anvil->nice_exit({exit_code => 0}); - } - elsif (($state eq "idle") or ($state eq "crashed")) - { - # The server needs to be destroyed. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0322", variables => { - server => $server, - 'state' => $state, - }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." destroy $server"}); - if ($return_code) - { - # Looks like virsh isn't running. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0323", variables => { - server => $server, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0324", variables => { server => $server }}); - $anvil->nice_exit({exit_code => 0}); - } - else - { - # WTF? - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0325", variables => { - server => $server, - 'state' => $state, - }}); - $anvil->nice_exit({exit_code => 6}); - } - - last; - } - } - - # If we didn't see it, it's off and undefined. - if (not $found) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0326", variables => { server => $server }}); - $anvil->nice_exit({exit_code => 0}); - } - - # If we're alive, it is time to stop the server - if ($shutdown) - { - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." shutdown $server"}); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0327", variables => { server => $server }}); - if ($return_code) - { - # Looks like virsh isn't running. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0328", variables => { - server => $server, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - } - - # Now loop until we see the server either vanish from virsh or enter "shut off" state. We wait - # forever and let pacemaker kill us if we time out. - while (1) - { - my $found = 0; - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list"}); - if ($return_code) - { - # Looks like virsh isn't running. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0312", variables => { - server => $server, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - foreach my $line (split/\n/, $output) - { - $line =~ s/^\s+//; - $line =~ s/\s+$//; - $line =~ s/\s+/ /g; - - if ($line =~ /^(\d+) $server (.*)$/) - { - my $state = $2; - $found = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - server => $server, - 'state' => $state, - }}); - - if ($state eq "shut off") - { - # We're down. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0324", variables => { server => $server }}); - $anvil->nice_exit({exit_code => 0}); - } - - last; - } - } - - # If we didn't find the server, it's off and undefined now. - if (not $found) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0329", variables => { server => $server }}); - - # Stop DRBD resources now. We don't worry if it actually stops or not (let ScanCore - # handle that). We only care that the server has stopped. - read_server_definition($anvil); - validate_storage($anvil); - foreach my $device_path (sort {$a cmp $b} keys %{$anvil->data->{server}{disks}}) - { - - my $resource = $anvil->data->{device_path}{$device_path}{resource}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - device_path => $device_path, - resource => $resource, - }}); - - if ((not exists $anvil->data->{drbd}{stopped}{$resource}) or (not $anvil->data->{drbd}{stopped}{$resource})) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0408", variables => { - resource => $resource, - device_path => $device_path, - }}); - manage_drbd_resource($anvil, "down", $resource); - $anvil->data->{drbd}{stopped}{$resource} = 1; - } - else - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0409", variables => { - resource => $resource, - device_path => $device_path, - }}); - } - } - $anvil->nice_exit({exit_code => 0}); - } - - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0330", variables => { server => $server }}); - sleep 5; - } $anvil->nice_exit({exit_code => 0}); } @@ -570,116 +352,6 @@ sub server_status $anvil->data->{environment}{OCF_RESKEY_CRM_meta_timeout} = 20000; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "warn", key => "log_0331", variables => { logout => $anvil->data->{environment}{OCF_RESKEY_CRM_meta_timeout} }}); } - my $return_code = undef; - my $output = ""; - my $current_time = time; - my $timeout = $current_time + int(($anvil->data->{environment}{OCF_RESKEY_CRM_meta_timeout} /= 1000) / 2); - my $waiting = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - current_time => $current_time, - timeout => $timeout, - }}); - - while($waiting) - { - # Make the call - ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list"}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { return_code => $return_code }}); - if (not $return_code) - { - $waiting = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { waiting => $waiting }}); - } - elsif (time > $timeout) - { - # We've waited long enough. - $waiting = 0; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "warn", key => "log_0332", variables => { return_code => $return_code }}); - } - else - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0333", variables => { return_code => $return_code }}); - sleep 2; - } - } - - # If I got a non-zero return code, something went wrong with the virsh call. - if ($return_code) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0334", variables => { return_code => $return_code }}); - if ($output) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0335", variables => { - command => $anvil->data->{path}{exe}{virsh}, - output => $output, - }}); - } - $anvil->nice_exit({exit_code => 1}); - } - - # If we're still alive, process the output - foreach my $line (split/\n/, $output) - { - $line =~ s/^\s+//; - $line =~ s/\s+$//; - $line =~ s/\s+/ /g; - - if ($line =~ /^(\d+) $server (.*)$/) - { - $state = $2; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - server => $server, - 'state' => $state, - }}); - last; - } - } - - # If there is a state, see what the state is. - if ($state) - { - # What is the state? - # (See the comment below the 'FUNCTIONS' divider above the first function for a full list of states.) - if (($state eq "running") or ($state eq "paused") or ($state eq "pmsuspended") or ($state eq "in shutdown")) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0336", variables => { - server => $server, - 'state' => $state, - }}); - $anvil->nice_exit({exit_code => 0}); - } - elsif ($state eq "shut off") - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0337", variables => { - server => $server, - 'state' => $state, - }}); - $anvil->nice_exit({exit_code => $7}); - } - elsif (($state eq "idle") or ($state eq "crashed")) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0338", variables => { - server => $server, - 'state' => $state, - }}); - $anvil->nice_exit({exit_code => 1}); - } - else - { - # WTF? - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0339", variables => { - server => $server, - 'state' => $state, - }}); - $anvil->nice_exit({exit_code => 1}); - } - } - else - { - # Not running. Exit with OCF_NOT_RUNNING - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0340", variables => { server => $server }}); - $anvil->nice_exit({exit_code => 7}); - } $anvil->nice_exit({exit_code => 0}); } @@ -703,312 +375,6 @@ sub migrate_server target => $target, }}); - # The actual migration command will involve enabling dual primary, then beginning the migration. The - # virsh call will depend on if we're pushing or pulling. Once the migration completes, regardless of - # success or failure, dual primary will be disabled again. - my $migration_command = ""; - my $verify_command = ""; - - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'switches::migrate_to' => $anvil->data->{switches}{migrate_to}, - 'switches::migrate_from' => $anvil->data->{switches}{migrate_from}, - }}); - if ($anvil->data->{switches}{migrate_to}) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0341", variables => { - server => $server, - target => $target, - }}); - - # Is the server even here? - my $found = 0; - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list"}); - if ($return_code) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0342", variables => { - server => $server, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - foreach my $line (split/\n/, $output) - { - $line =~ s/^\s+//; - $line =~ s/\s+$//; - $line =~ s/\s+/ /g; - - if ($line =~ /^(\d+) $server (.*)$/) - { - my $state = $2; - $found = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - server => $server, - 'state' => $state, - found => $found, - }}); - - # We can only migrate if it is running. - if (lc($state) ne "running") - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0343", variables => { - server => $server, - 'state' => $state, - }}); - $anvil->nice_exit({exit_code => 1}); - } - } - } - if (not $found) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0344", variables => { server => $server }}); - $anvil->nice_exit({exit_code => 1}); - } - - read_server_definition($anvil); - validate_storage($anvil); - - # If we're alive, craft the migration command. - $migration_command = $anvil->data->{path}{exe}{virsh}." migrate --undefinesource --tunnelled --p2p --live ".$server." qemu+ssh://".$target."/system"; - $verify_command = $anvil->data->{path}{exe}{virsh}." list"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - migration_command => $migration_command, - verify_command => $verify_command, - }}); - } - elsif ($anvil->data->{switches}{migrate_from}) - { - # This is called after a migration. In case this is the case here, the target will be us. - # Just make sure it is running and, if so, return '0'. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "environment::OCF_RESKEY_CRM_meta_on_node" => $anvil->data->{environment}{OCF_RESKEY_CRM_meta_on_node}, - target => $target, - }}); - if ($anvil->data->{environment}{OCF_RESKEY_CRM_meta_on_node} eq $target) - { - # Yup. All we want to do if make sure it is running here. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0345", variables => { server => $server }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list"}); - if ($return_code) - { - # This really shouldn't happen... The migration to here should have failed. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0346", variables => { - server => $server, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - foreach my $line (split/\n/, $output) - { - $line =~ s/^\s+//; - $line =~ s/\s+$//; - $line =~ s/\s+/ /g; - - if ($line =~ /^(\d+) $server (.*)$/) - { - my $state = $2; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - server => $server, - 'state' => $state, - }}); - if ($state eq "running") - { - # Success! - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0347", variables => { server => $server }}); - $anvil->nice_exit({exit_code => 0}); - } - } - } - - # If we're still alive, we'll proceed as if we're pulling the server to us, and maybe - # that will work. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0348", variables => { server => $server }}); - } - else - { - # If we're being re-invoked after a previous successful migration, then the server - # might already be here. Check before we proceed. - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list"}); - if ($return_code) - { - # If this fails, we want to exit with OCF_ERR_CONFIGURED (6) so that pacemaker doesn't try to - # also start the server on another node, because we don't know the state of it here. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "log_0304", variables => { return_code => $return_code, output => $output }}); - } - foreach my $line (split/\n/, $output) - { - $line =~ s/^\s+//; - $line =~ s/\s+$//; - $line =~ s/\s+/ /g; - - if ($line =~ /^(\d+) $server (.*)$/) - { - my $state = $2; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - server => $server, - 'state' => $state, - }}); - - # Make sure the server is shut down, if it is listed at all. Any other state is - # unexpected and needs to be sorted by a human. - if ($state ne "shut down") - { - # Abort - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0412", variables => { server => $server, 'state' => $state }}); - $anvil->nice_exit({exit_code => 0}); - } - last; - } - } - } - - # Validate everything, as if we were about to boot - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0349", variables => { - server => $server, - target => $target, - }}); - validate_all($anvil); - - # If we're alive, craft the migration command. - $migration_command = $anvil->data->{path}{exe}{virsh}." -c qemu+ssh://root\@".$source."/system migrate --undefinesource --tunnelled --p2p --live ".$server." qemu+ssh://".$target."/system"; - $verify_command = $anvil->data->{path}{exe}{virsh}." -c qemu+ssh://root\@".$source."/system list"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - migration_command => $migration_command, - verify_command => $verify_command, - }}); - } - - # Enable dual-primary. If this fails, we will disable (or try to) and then abort. - my $migrate = 1; - foreach my $resource (sort {$a cmp $b} keys %{$anvil->data->{resource}}) - { - next if not defined $anvil->data->{resource}{$resource}{target_node_id}; - next if not $migrate; - my $shell_call = $anvil->data->{path}{exe}{drbdsetup}." net-options ".$resource." ".$anvil->data->{resource}{$resource}{target_node_id}." --allow-two-primaries=yes"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0350", variables => { - resource => $resource, - target_name => $anvil->data->{resource}{$resource}{target_name}, - target_node_id => $anvil->data->{resource}{$resource}{target_node_id}, - }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call}); - if ($return_code) - { - # Something went wrong. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0346", variables => { - resource => $resource, - target_name => $anvil->data->{resource}{$resource}{target_name}, - target_node_id => $anvil->data->{resource}{$resource}{target_node_id}, - return_code => $return_code, - output => $output, - }}); - - # Disable migration (and any further attempts to enable dual-primary). - $migrate = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { migrate => $migrate }}); - } - } - - my $migrated = 0; - if ($migrate) - { - # Call the migration. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0352", variables => { - server => $server, - target => $target, - }}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { migration_command => $migration_command }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $migration_command}); - if ($return_code) - { - # Something went wrong. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0353", variables => { - server => $server, - target => $target, - return_code => $return_code, - output => $output, - }}); - } - else - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0354"}); - - $migrated = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { migrated => $migrated }}); - } - } - - # Switch off dual-primary. - my $shell_call = $anvil->data->{path}{exe}{drbdadm}." adjust all"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0355"}); - my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call}); - if ($return_code) - { - # Something went wrong. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0356", variables => { - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - - # Did something go wrong during the dual-primary enable or the actual migration call? - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - migrate => $migrate, - migrated => $migrated, - }}); - if ((not $migrate) or (not $migrated)) - { - # Exit - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0357"}); - $anvil->nice_exit({exit_code => 1}); - } - - # Last, verify that the server is now on the target. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { verify_command => $verify_command }}); - - $return_code = undef; - $output = undef; - ($output, $return_code) = $anvil->System->call({shell_call => $verify_command}); - if ($return_code) - { - # If this fails, we want to exit with OCF_ERR_CONFIGURED (6) so that pacemaker doesn't try to - # also start the server on another node, because we don't know the state of it here. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0358", variables => { - target => $target, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - foreach my $line (split/\n/, $output) - { - $line =~ s/^\s+//; - $line =~ s/\s+$//; - $line =~ s/\s+/ /g; - - if ($line =~ /^(\d+) $server (.*)$/) - { - my $state = $2; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - server => $server, - 'state' => $state, - }}); - if ($state eq "running") - { - # Success! - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0359", variables => { - server => $server, - target => $target, - }}); - $anvil->nice_exit({exit_code => 0}); - } - } - } # If we made it here, we succeeded. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0360"}); @@ -1021,33 +387,12 @@ sub validate_all my ($anvil) = @_; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0361"}); - # Read in the server's definition file (if found and readable). - read_server_definition($anvil); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0362"}); - - # Does the internal server name match? - validate_name($anvil); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0363"}); - - # Make sure the emulator it wants is the one we have. - validate_emulator($anvil); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0364"}); - - # These tests are only needed if we're about to boot the server - if (($anvil->data->{switches}{start}) or ($anvil->data->{switches}{migrate_from})) - { - # Check that we have enough RAM. - validate_ram($anvil); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0365"}); - } + ### TODO: When we have actual Anvil! systems, connect to the peers (nodes / DR) for this host and see + ### if the server is running elsewhere. - # Validate bridges - validate_bridges($anvil); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0366"}); + # Read in an parse the server's XML. + $anvil->Server->get_status({debug => 2, server => $anvil->data->{environment}{OCF_RESKEY_name}}); - # Validate storage (Disks and optical media) - validate_storage($anvil); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0367"}); return(0); } @@ -1057,48 +402,6 @@ sub validate_bridges { my ($anvil) = @_; - # Find the Optical drives and DRBD devices. - foreach my $device_ref (@{$anvil->data->{server}{definition_xml}->{devices}}) - { - foreach my $interface_ref (@{$device_ref->{interface}}) - { - foreach my $source_ref (@{$interface_ref->{source}}) - { - my $bridge = $source_ref->{bridge}; - $anvil->data->{server}{bridges}{$bridge} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "server::bridges::${bridge}" => $anvil->data->{server}{bridges}{$bridge} }}); - } - } - } - - # Get a list of available bridges. We pick up interfaces and MTU data as well, though there really - # isn't any use for it at this time. - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{bridge}." -j link show"}); - my $json = JSON->new->allow_nonref; - my $bridge_data = $json->decode($output); - foreach my $hash_ref (@{$bridge_data}) - { - my $bridge = $hash_ref->{master}; - my $interface = $hash_ref->{ifname}; - my $mtu = $hash_ref->{mtu}; - $anvil->data->{bridge}{$bridge}{interface}{$interface}{mtu} = $mtu; - $anvil->data->{'local'}{bridge}{$bridge} = 1; - } - - # Verify bridges now - foreach my $bridge (sort {$a cmp $b} keys %{$anvil->data->{server}{bridges}}) - { - if ($anvil->data->{'local'}{bridge}{$bridge}) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "log_0368", variables => { bridge => $bridge }}); - } - else - { - # Missing bridge. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0369", variables => { bridge => $bridge }}); - $anvil->nice_exit({exit_code => 5}); - } - } return(0); } @@ -1107,43 +410,8 @@ sub validate_bridges sub validate_storage { my ($anvil) = @_; - - # Find the storage device(s) this server uses. - foreach my $device_ref (@{$anvil->data->{server}{definition_xml}->{devices}}) - { - foreach my $disk_ref (@{$device_ref->{disk}}) - { - my $type = $disk_ref->{device}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { type => $type }}); - if ($type eq "disk") - { - foreach my $source_ref (@{$disk_ref->{source}}) - { - my $device_path = $source_ref->{dev}; - $anvil->data->{server}{disks}{$device_path} = "check"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "server::disks::${device_path}" => $anvil->data->{server}{disks}{$device_path} }}); - } - } - elsif ($type eq "cdrom") - { - foreach my $source_ref (@{$disk_ref->{source}}) - { - my $file = $source_ref->{file}; - $anvil->data->{server}{optical}{$file} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "server::optical::${file}" => $anvil->data->{server}{optical}{$file} }}); - } - } - } - } - # Verify optical disks now, unless we're migrating a server off of us or stopping. - if ((not $anvil->data->{switches}{migrate_to}) && (not $anvil->data->{switches}{stop})) - { - validate_storage_optical($anvil); - } - # Verify DRBD devices now - validate_storage_drbd($anvil); return(0); } @@ -1154,284 +422,7 @@ sub validate_storage_drbd { my ($anvil) = @_; - # Read in the DRBD configuration XML. - my ($drbd_body, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{drbdadm}." dump-xml"}); - if ($return_code) - { - # Something went wrong. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0370", variables => { - return_code => $return_code, - drbd_body => $drbd_body, - }}); - $anvil->nice_exit({exit_code => 1}); - } - - # Parse the XML - my $drbd_xml = ""; - my $xml = XML::Simple->new(); - eval { $drbd_xml = $xml->XMLin($drbd_body, KeyAttr => ["name", "vnr"], ForceArray => 1) }; - if ($@) - { - chomp $@; - my $error = "[ Error ] - The was a problem parsing: [$drbd_body]. The error was:\n"; - $error .= "===========================================================\n"; - $error .= $@."\n"; - $error .= "===========================================================\n"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", list => { error => $error }}); - $anvil->nice_exit({exit_code => 1}); - } - - foreach my $resource (sort {$a cmp $b} keys %{$drbd_xml->{resource}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { resource => $resource }}); - - # Figure out who I am and who my peer is, ignoring DR host(s). - my $peer = ""; - my $local = ""; - foreach my $connection_ref (@{$drbd_xml->{resource}->{$resource}->{connection}}) - { - my $protocol = $connection_ref->{section}->{net}->{option}->{protocol}->{value}; - my $fencing = $connection_ref->{section}->{net}->{option}->{fencing}->{value}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - protocol => $protocol, - fencing => $fencing, - }}); - - # If this isn't set to 'resource-and-stonith', it's a DR connection and we'll ignore - # it. - next if $fencing ne "resource-and-stonith"; - - # Look at the hosts - foreach my $host (sort {$a cmp $b} keys %{$connection_ref->{host}}) - { - my $address = $connection_ref->{host}->{$host}->{address}->[0]->{content}; - my $port = $connection_ref->{host}->{$host}->{address}->[0]->{port}; - my $short_hostname = $host; - $short_hostname =~ s/\..*$//; - my $local_hostname = $anvil->_hostname; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - host => $host, - short_hostname => $short_hostname, - address => $address, - port => $port, - local_hostname => $local_hostname, - }}); - - # Is this me or the peer? - if (($local_hostname eq $short_hostname) or ($local_hostname =~ /^$short_hostname\./)) - { - # This is us. - $local = $host; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'local' => $local }}); - - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "log_0371", variables => { - resource => $resource, - address => $address, - port => $port, - }}); - $anvil->data->{server}{drbd}{'local'}{hostname} = $host, - $anvil->data->{server}{drbd}{'local'}{short_hostname} = $short_hostname, - $anvil->data->{server}{drbd}{'local'}{address} = $address, - $anvil->data->{server}{drbd}{'local'}{port} = $port, - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "server::drbd::local::hostname" => $anvil->data->{server}{drbd}{'local'}{hostname}, - "server::drbd::local::short_hostname" => $anvil->data->{server}{drbd}{'local'}{short_hostname}, - "server::drbd::local::address" => $anvil->data->{server}{drbd}{'local'}{address}, - "server::drbd::local::port" => $anvil->data->{server}{drbd}{'local'}{port}, - }}); - - # Record my node name for this resource (to be paired with the node - # ID when migrating) - $anvil->data->{resource}{$resource}{local_node_name} = $host; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "resource::${resource}::local_node_name" => $anvil->data->{resource}{$resource}{local_node_name} }}); - } - else - { - # This is our peer - $peer = $host; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer => $peer }}); - - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "log_0372", variables => { - resource => $resource, - address => $address, - port => $port, - }}); - $anvil->data->{server}{drbd}{peer}{hostname} = $host, - $anvil->data->{server}{drbd}{peer}{short_hostname} = $short_hostname, - $anvil->data->{server}{drbd}{peer}{address} = $address, - $anvil->data->{server}{drbd}{peer}{port} = $port, - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "server::drbd::peer::hostname" => $anvil->data->{server}{drbd}{peer}{hostname}, - "server::drbd::peer::short_hostname" => $anvil->data->{server}{drbd}{peer}{short_hostname}, - "server::drbd::peer::address" => $anvil->data->{server}{drbd}{peer}{address}, - "server::drbd::peer::port" => $anvil->data->{server}{drbd}{peer}{port}, - }}); - } - } - } - - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'local' => $local, - peer => $peer, - }}); - foreach my $volume (sort {$a cmp $b} keys %{$drbd_xml->{resource}->{$resource}->{host}->{$local}->{volume}}) - { - # The backing device is the logical volume underpinning this DRBD device on this node. - my $backing_device = $drbd_xml->{resource}->{$resource}->{host}->{$local}->{volume}->{$volume}->{disk}->[0]; - my $device_path = $drbd_xml->{resource}->{$resource}->{host}->{$local}->{volume}->{$volume}->{device}->[0]->{content}; - my $device_minor = $drbd_xml->{resource}->{$resource}->{host}->{$local}->{volume}->{$volume}->{device}->[0]->{minor}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - volume => $volume, - backing_device => $backing_device, - device_path => $device_path, - device_minor => $device_minor, - }}); - - $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{lv} = $backing_device; - $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{minor} = $device_minor; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - "server::drbd::local::device::${device_path}::lv" => $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{lv}, - "server::drbd::local::device::${device_path}::minor" => $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{minor}, - }}); - - # Map the resource name to the local drbd device path. - $anvil->data->{resource}{$resource}{volume}{$volume}{lv} = $backing_device; - $anvil->data->{resource}{$resource}{volume}{$volume}{path} = $device_path; - $anvil->data->{device_path}{$device_path}{resource} = $resource; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "resource::${resource}::volume::${volume}::path" => $anvil->data->{resource}{$resource}{volume}{$volume}{path}, - "resource::${resource}::volume::${volume}::lv" => $anvil->data->{resource}{$resource}{volume}{$volume}{lv}, - "device_path::${device_path}::resource" => $anvil->data->{device_path}{$device_path}{resource}, - }}); - } - } - - # Pair the volumes to their backing LVs. - foreach my $device_path (sort {$a cmp $b} keys %{$anvil->data->{server}{disks}}) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0373", variables => { device_path => $device_path }}); - - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "server::drbd::local::device::${device_path}::lv" => $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{lv} }}); - if (not $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{lv}) - { - # The backing LV doesn't exist. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 0, priority => "err", key => "log_0374", variables => { device_path => $device_path }}); - $anvil->nice_exit({exit_code => 5}); - } - elsif (not -e $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{lv}) - { - # The backing LV doesn't exist. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 0, priority => "err", key => "log_0375", variables => { - device_path => $device_path, - lv => $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{lv}, - }}); - $anvil->nice_exit({exit_code => 5}); - } - else - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "log_0376", variables => { - device_path => $device_path, - lv => $anvil->data->{server}{drbd}{'local'}{device}{$device_path}{lv}, - }}); - } - } - - # If we're in a stop operation, we're done. - if ($anvil->data->{switches}{stop}) - { - return(0); - } - - # Now read in the status of the drbd devices - my $host = $anvil->_short_hostname; - $anvil->DRBD->get_status({debug => 2}); - if ($anvil->data->{drbd}{status}{$host}{return_code}) - { - # Something went wrong. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0377", variables => { - return_code => $anvil->data->{drbd}{status}{$host}{return_code}, - status_json => $status_json, - }}); - $anvil->nice_exit({exit_code => 1}); - } - die; - - # If DRBD is not up, the returned JSON output will not actually exist. - if (($status_json =~ /No currently configured DRBD found/si) or (not check_drbd_status($anvil, $status_json))) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0378"}); - foreach my $device_path (sort {$a cmp $b} keys %{$anvil->data->{server}{disks}}) - { - my $resource = $anvil->data->{device_path}{$device_path}{resource}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - device_path => $device_path, - resource => length($resource), - }}); - - if ((not exists $anvil->data->{drbd}{started}{$resource}) or (not $anvil->data->{drbd}{started}{$resource})) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "log_0379", variables => { - resource => $resource, - device_path => $device_path, - }}); - } - else - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "log_0407", variables => { - resource => $resource, - device_path => $device_path, - }}); - next; - } - - manage_drbd_resource($anvil, "up", $resource); - $anvil->data->{drbd}{started}{$resource} = 1; - } - - # Give them a few seconds to start. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "log_0381"}); - sleep 3; - - # Check DRBD setup again - $return_code = undef; - $status_json = undef; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "log_0385"}); - ($status_json, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{drbdsetup}." status --json"}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - status_json => $status_json, - return_code => $return_code, - }}); - if ($return_code) - { - # Something went wrong. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0382", variables => { - return_code => $return_code, - status_json => $status_json, - }}); - $anvil->nice_exit({exit_code => 1}); - } - - # If DRBD is still not up, we're done. - if (($status_json =~ /No currently configured DRBD found/si) or (length($status_json) < 5)) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0383"}); - $anvil->nice_exit({exit_code => 1}); - } - } - - # Process the JSON data. If any disks are not seen, they won't be set to 'ok', which we'll catch next. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { status_json => $status_json }}); - check_drbd_status($anvil, $status_json); - - ### TODO: Finish this, whatever this was going to be... - # If I am about to push a server off, we need to make sure the peer is UpToDate - if ($anvil->data->{switches}{migrate_to}) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0387"}); - foreach my $device_path (sort {$a cmp $b} keys %{$anvil->data->{server}{disks}}) - { - } - } + return(0); } @@ -1442,170 +433,8 @@ sub check_drbd_status my ($anvil, $status_json) = @_; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { status_json => $status_json }}); - my $json = JSON->new->allow_nonref; - my $drbd_status = $json->decode($status_json); - my $resource_found = 0; - foreach my $resource_ref (@{$drbd_status}) - { - my $resource = $resource_ref->{name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { resource => $resource }}); - - # Record my node ID for this resource - $anvil->data->{resource}{$resource}{local_node_id} = $resource_ref->{'node-id'}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "resource::${resource}::local_node_id" => $anvil->data->{resource}{$resource}{local_node_id} }}); - - foreach my $volume (sort {$a cmp $b} keys %{$anvil->data->{resource}{$resource}{volume}}) - { - my $device_path = $anvil->data->{resource}{$resource}{volume}{$volume}{path}; - my $logical_volume = $anvil->data->{resource}{$resource}{volume}{$volume}{lv}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 's1:volume' => $volume, - 's2:device_path' => $device_path, - 's3:logical_volume' => $logical_volume, - 's4:server::disks::$device_path' => defined $anvil->data->{server}{disks}{$device_path} ? $anvil->data->{server}{disks}{$device_path} : "", - }}); - - if ((defined $anvil->data->{server}{disks}{$device_path}) && ($anvil->data->{server}{disks}{$device_path} eq "check")) - { - ### This disk is in use by this server, check it. - $resource_found = 1; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0388", variables => { device_path => $device_path }}); - - # We can't run the server here until our device(s) are UpToDate or SyncSource. - if (($anvil->data->{switches}{start}) or ($anvil->data->{switches}{migrate_from})) - { - foreach my $device_ref (@{$resource_ref->{devices}}) - { - # Are we UpToDate (or SyncSource)? - if ((lc($device_ref->{'disk-state'}) ne "uptodate") && (lc($device_ref->{'disk-state'}) ne "syncsource")) - { - # We can't run here. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0389", variables => { - resource => $resource, - volume => $device_ref->{volume}, - disk_state => $device_ref->{'disk-state'}, - }}); - $anvil->nice_exit({exit_code => 1}); - } - else - { - # We're good. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0390", variables => { - resource => $resource, - volume => $device_ref->{volume}, - disk_state => $device_ref->{'disk-state'}, - }}); - } - } - } - - # If we're booting a server, we need to be sure that *no* peer is Primary. - foreach my $connection_ref (@{$resource_ref->{connections}}) - { - # If we're not connected, skip. - my $connection_state = $connection_ref->{'connection-state'}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { connection_state => $connection_state }}); - next if lc($connection_state) ne "connected"; - - # Is the peer's role Primary? In all cases, we abort if so. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0391", variables => { name => $connection_ref->{name} }}); - if ((lc($connection_ref->{'peer-role'}) eq "primary") && ($anvil->data->{switches}{start})) - { - # Don't boot here - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0392", variables => { - resource => $resource, - name => $connection_ref->{name} - }}); - $anvil->nice_exit({exit_code => 1}); - } - - # If we're migrating to the peer, make sure the target disk state is UpToDate - # or SyncSource. - if ($anvil->data->{switches}{migrate_to}) - { - # Is this connection to our migration target? - my $peer_short_name = $connection_ref->{name}; - $peer_short_name =~ s/\..*$//; - my $migration_target = $anvil->data->{environment}{OCF_RESKEY_CRM_meta_migrate_target}; - $migration_target =~ s/\..*$//; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - peer_short_name => $peer_short_name, - migration_target => $migration_target, - }}); - if ($peer_short_name ne $migration_target) - { - # Ignore this, it isn't our target - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0394", variables => { peer_short_name => $peer_short_name }}); - next; - } - - # We will need the node ID to enable dual-primary. - $anvil->data->{resource}{$resource}{target_name} = $connection_ref->{name}; - $anvil->data->{resource}{$resource}{target_node_id} = $connection_ref->{'peer-node-id'}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "resource::${resource}::target_name" => $anvil->data->{resource}{$resource}{target_name}, - "resource::${resource}::target_node_id" => $anvil->data->{resource}{$resource}{target_node_id}, - }}); - - # If we're still alive, we want to ensure all volumes are UpToDate. - foreach my $volume_ref (@{$connection_ref->{peer_devices}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - volume => $volume_ref->{volume}, - disk_state => $volume_ref->{'peer-disk-state'}, - }}); - if ((lc($volume_ref->{'peer-disk-state'}) ne "uptodate") && (lc($volume_ref->{'peer-disk-state'}) ne "syncsource")) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0395", variables => { - resource => $resource, - name => $connection_ref->{name} - }}); - $anvil->nice_exit({exit_code => 1}); - } - } - } - } - - # If we're here, it's OK. - $anvil->data->{server}{disks}{$device_path} = "ok"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "server::disks::${device_path}" => $anvil->data->{server}{disks}{$device_path} }}); - } - else - { - # Ignoring, not used. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 3, key => "log_0396", variables => { device_path => $device_path }}); - } - } - - # If we're still alive and we're booting a server, make sure the local resource is Primary - my $role = $resource_ref->{role}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { role => $role }}); - if (($anvil->data->{switches}{start}) && (lc($role) eq "secondary")) - { - # Go primary. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "log_0410", variables => { - resource => $resource, - role => $role, - }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{drbdadm}." primary ".$resource}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - output => $output, - return_code => $return_code, - }}); - if ($return_code) - { - # Something went wrong - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0411", variables => { - resource => $resource, - return_code => $return_code, - output => $output, - }}); - $anvil->nice_exit({exit_code => 1}); - } - } - } - return($resource_found); + return(0); } # This makes sure that any media in the server's optical drive exists here and is readable. @@ -1613,30 +442,7 @@ sub validate_storage_optical { my ($anvil) = @_; - foreach my $file (sort {$a cmp $b} keys %{$anvil->data->{server}{optical}}) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "log_0397", variables => { file => $file }}); - - # If the file doesn't exist, exit with OCF_ERR_INSTALLED (5). If we can't read it, exit with - # OCF_ERR_PERM (4). - if (not -e $file) - { - # It doesn't exist. Exit with OCF_ERR_INSTALLED (5). - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0398", variables => { file => $file }}); - $anvil->nice_exit({exit_code => 5}); - } - elsif (not -r $file) - { - # We can't read it. Exit with OCF_ERR_PERM (4). - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0399", variables => { file => $file }}); - $anvil->nice_exit({exit_code => 4}); - } - else - { - # We're OK. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0400", variables => { file => $file }}); - } - } + return(0); } @@ -1646,24 +452,7 @@ sub validate_emulator { my ($anvil) = @_; - # What emulator is this using? - my $emulator = $anvil->data->{server}{definition_xml}->{devices}->[0]->{emulator}->[0]; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { emulator => $emulator }}); - if (not -e $emulator) - { - # It doesn't exist. Exit with OCF_ERR_INSTALLED (5). - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0401", variables => { - emulator => $emulator, - definition_file => $anvil->data->{server}{definition_file}, - }}); - $anvil->nice_exit({exit_code => 5}); - } - if (not -x $emulator) - { - # We can't execute it. Exit with OCF_ERR_PERM (4). - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0402", variables => { emulator => $emulator }}); - $anvil->nice_exit({exit_code => 4}); - } + return(0); } @@ -1673,15 +462,7 @@ sub validate_name { my ($anvil) = @_; - my $server = $anvil->data->{environment}{OCF_RESKEY_name}; - if ($server ne $anvil->data->{server}{definition_xml}->{name}->[0]) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0403", variables => { - server => $server, - name => $anvil->data->{server}{definition_xml}->{name}, - }}); - $anvil->nice_exit({exit_code => 1}); - } + return(0); } @@ -1691,61 +472,7 @@ sub validate_ram { my ($anvil) = @_; - # How mcuh RAM does the server need? - my $server_ram_value = $anvil->data->{server}{definition_xml}->{memory}->[0]->{content}; - my $server_ram_units = $anvil->data->{server}{definition_xml}->{memory}->[0]->{unit}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - server_ram_value => $server_ram_value, - server_ram_units => $server_ram_units, - }}); - - # Convert to bytes - my $server_ram_bytes = $anvil->Convert->human_readable_to_bytes({size => $server_ram_value, type => $server_ram_units, base2 => 1 }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - server_ram_bytes => $server_ram_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_bytes}).")", - }}); - - # How much RAM do we have available? - my $available = 0; - my ($free_output, $free_rc) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{free}." --bytes"}); - foreach my $line (split/\n/, $free_output) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); - if ($line =~ /Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/) - { - my $total = $1; - my $used = $2; - my $free = $3; - my $shared = $4; - my $cache = $5; - $available = $6; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - total => $total." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $total})."})", - used => $used." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $used})."})", - free => $free." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free})."})", - shared => $shared." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $shared})."})", - cache => $cache." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $cache})."})", - available => $available." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $available})."})", - }}); - } - } - - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - server_ram_bytes => $anvil->Convert->add_commas({number => $server_ram_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_bytes}).")", - available => $anvil->Convert->add_commas({number => $available})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $available}).")", - }}); - if ($server_ram_bytes > $available) - { - # Not enough free memory. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0404", variables => { - name => $anvil->data->{environment}{OCF_RESKEY_name}, - ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_bytes}), - ram_bytes => $anvil->Convert->add_commas({number => $server_ram_bytes}), - available_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_bytes}), - available_ram_bytes => $anvil->Convert->add_commas({number => $available}), - }}); - $anvil->nice_exit({exit_code => 1}); - } + return(0); } @@ -1756,52 +483,8 @@ sub manage_drbd_resource { my ($anvil, $task, $resource) = @_; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'server::drbd::peer::hostname' => $anvil->data->{server}{drbd}{peer}{hostname}, - }}); - # Stop the resource on the peer, then stop it here. - my $peer_hostname = $anvil->data->{server}{drbd}{peer}{hostname}; - my $shell_call = $anvil->data->{path}{exe}{drbdadm}." ".$task." ".$resource; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - peer_hostname => $peer_hostname, - shell_call => $shell_call, - }}); - my ($output, $error, $return_code) = $anvil->Remote->call({ - debug => 2, - shell_call => $shell_call, - target => $peer_hostname, - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - output => $output, - error => $error, - return_code => $return_code, - }}); - - # Now call it locally - $output = undef; - $return_code = undef; - ($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, - }}); - - # Now wait for it to come up. - my $wait = 1; - while($wait) - { - if ($wait) - { - sleep 1; - } - - ($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, - }}); - } + return(0); } @@ -1812,51 +495,10 @@ sub read_server_definition my ($anvil) = @_; my $server = $anvil->data->{environment}{OCF_RESKEY_name}; - my $definition_file = $anvil->data->{path}{directories}{shared}{definitions}."/".$server.".xml"; - my $server_xml = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { server => $server, - definition_file => $definition_file, }}); - # If the file doesn't exist, return OCF_ERR_INSTALLED (5). If the file exists but we can't read it, - # return OCF_ERR_PERM (4). - if (not -e $definition_file) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0405", variables => { - definition_file => $definition_file, - server => $server, - }}); - $anvil->nice_exit({exit_code => 5}); - } - elsif (not -r $definition_file) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0406", variables => { - definition_file => $definition_file, - server => $server, - }}); - $anvil->nice_exit({exit_code => 4}); - } - - # Still alive? Read it in. - my $definition_xml = $anvil->Storage->read_file({file => $definition_file}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { definition_file => $definition_file }}); - - my $xml = XML::Simple->new(); - eval { $server_xml = $xml->XMLin($definition_xml, KeyAttr => {}, ForceArray => 1) }; - if ($@) - { - chomp $@; - my $error = "[ Error ] - The was a problem parsing: [$definition_file]. The error was:\n"; - $error .= "===========================================================\n"; - $error .= $@."\n"; - $error .= "===========================================================\n"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", list => { error => $error }}); - $anvil->nice_exit({exit_code => 1}); - } - - $anvil->data->{server}{definition_xml} = $server_xml; - $anvil->data->{server}{definition_file} = $definition_file; return(0); }