#! /usr/bin/perl # IBM(c) 2016 EPL license http://www.eclipse.org/legal/epl-v10.html BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } use lib "$::XCATROOT/probe/lib/perl"; use probe_utils; use File::Basename; use Net::Ping; use Getopt::Long qw(:config no_ignore_case); use Data::Dumper; use warnings; my $program_name = basename("$0"); my $help; my $noderange = ""; my $test; my $output = "stdout"; my $verbose = 0; my $rst = 0; # Match pattern for discovered nodes: node-1234-ABCDE-123456 # node- d+ -[a-z]- d+ #my $discovered_node_pattern = '^node-\d+-[a-zA-Z]+-\d+'; my $discovered_node_pattern = '^node-'; $::USAGE = "Usage: $program_name -h $program_name [-d|delete_duplicate] [-n noderange] [-V|--verbose] Description: Use this command to check node defintions in xCAT DB. Options: -h : Get usage information of $program_name -n : Range of nodes to check -d : Remove duplicate model type and serial number node definition from xCAT DB -V : To print additional debug information. "; #------------------------------------- # main process #------------------------------------- if ( !GetOptions("--help|h" => \$help, "T" => \$test, "V|verbose" => \$VERBOSE, "n=s" => \$noderange, "d|delete_duplicate" => \$DELETE_DUPLICATE)) { probe_utils->send_msg("$output", "f", "Invalid parameter for $program_name"); probe_utils->send_msg("$output", "d", "$::USAGE"); exit 1; } if ($help) { if ($output ne "stdout") { probe_utils->send_msg("$output", "d", "$::USAGE"); } else { print "$::USAGE"; } exit 0; } if ($test) { probe_utils->send_msg("$output", "o", "Use this command to check node defintions in xCAT DB."); exit 0; } if (scalar(@ARGV) >= 1) { # After processing all the expected flags and arguments, # there is still left over stuff on the command line probe_utils->send_msg("$output", "f", "Invalid flag or parameter: @ARGV"); probe_utils->send_msg("$output", "d", "$::USAGE"); exit 1; } check_for_duplicate_mtms_sn(); check_for_valid_node_attributes(); # Check for node definitions with duplicate MTM+SERIAL sub check_for_duplicate_mtms_sn { my $na = "N/A"; my %node_mtm_serial_hash; my %mtm_serial_node_hash; my %waiting_to_be_discovered; my $all_nodes_mtm_serial = `lsdef -i mtm,serial -c $noderange 2> /dev/null`; chomp($all_nodes_mtm_serial); my @all_nodes_mtm_serial_lines = split("[\n\r]", $all_nodes_mtm_serial); if ($all_nodes_mtm_serial =~ /Usage:|Could not find any object definitions to display/) { # lsdef command displayed a Usage message. Must be some noderange formatting problem, # or no nodes defined at all. Issue a warning and exit. probe_utils->send_msg("$output", "w", "Can not get a list of nodes from specified noderange."); return 1; } if (scalar(@all_nodes_mtm_serial_lines) <= 0) { # There were no nodes matching the noderange. Issue a warning and exit. probe_utils->send_msg("$output", "w", "No nodes matching the noderange were found."); return 1; } # Build a hash of key="nodename" value="mtm+serial" foreach (@all_nodes_mtm_serial_lines) { probe_utils->send_msg("$output", "d", "Processing $_.") if ($VERBOSE); my ($node_name, $value) = split ":", $_; if (exists($node_mtm_serial_hash{$node_name})) { # already have an entry for this node with mtm, concat the serial $value = $node_mtm_serial_hash{$node_name} . $value; if ($node_name =~ /$discovered_node_pattern/) { probe_utils->send_msg("$output", "d", "Pattern match discovered for node: $node_name") if ($VERBOSE); # Check if mtm and serial are set unless ($value eq " mtm= serial=") { # Build a hash of key="mtm+serial" and value="nodename". Later, this entry # will be removed if predefined node found with the same mtm + serial found $waiting_to_be_discovered{$value} = $node_name; } } } $node_mtm_serial_hash{$node_name} = $value; } #print Dumper(\%node_mtm_serial_hash) if ($VERBOSE); # Build a hash of key="mtm+serial" value = "nodename" for all non-empty mtm+serial my $any_dups = 0; while (($node_name, $mtm_serial) = each %node_mtm_serial_hash) { # Check if hash already has the same key indicating another node definition has the same mtm+serial if (exists($mtm_serial_node_hash{$mtm_serial})) { if ($mtm_serial eq " mtm= serial=") { # Exclude entries that do not have mtm+serial set probe_utils->send_msg("$output", "d", "No mtm and no serial for node $node_name") if ($VERBOSE); next; } # Check whioh of the 2 matching node definitions is the discovered node # for proper message display if ($node_name =~ /$discovered_node_pattern/) { probe_utils->send_msg("$output", "f", "$node_name has been discovered as $mtm_serial_node_hash{$mtm_serial} and can be removed using \"rmdef $node_name\""); } elsif ($mtm_serial_node_hash{$mtm_serial} =~ /$discovered_node_pattern/) { probe_utils->send_msg("$output", "f", "$mtm_serial_node_hash{$mtm_serial} has been discovered as $node_name and can be removed using \"rmdef $mtm_serial_node_hash{$mtm_serial}\""); } else { # None of the node names start with discovered_node_pattern, display generic message probe_utils->send_msg("$output", "f", "Duplicate node definition found for the same $mtm_serial : $node_name and $mtm_serial_node_hash{$mtm_serial}"); } if ($DELETE_DUPLICATE) { # Removing node definition of the duplicate node entry probe_utils->send_msg("$output", "d", "Removing node definition: $mtm_serial_node_hash{$mtm_serial}") if ($VERBOSE); my $remove_result = `rmdef $mtm_serial_node_hash{$mtm_serial}`; } # Remove entries from waiting_to_be_discovered hash if duplicate entry is detected delete $waiting_to_be_discovered{$mtm_serial}; $any_dups = 1; } else { $mtm_serial_node_hash{$mtm_serial} = $node_name; } } #print Dumper(\%mtm_serial_node_hash) if ($VERBOSE); #print Dumper(\%waiting_to_be_discovered) if ($VERBOSE); my $rc = 1; unless ($any_dups) { probe_utils->send_msg("$output", "o", "No nodes with duplicate mtm and serial numbers were found."); $rc = 0; } # Display all discovered nodes (starting with "node-" that do not have a corresponding predefined node foreach (values %waiting_to_be_discovered) { probe_utils->send_msg("$output", "o", "$_: Waiting to be discovered"); } return $rc; } # Check attributes in node definitions for valid format sub check_for_valid_node_attributes { my $na = "N/A"; my $rc = 0; return $rc; }