mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 11:22:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			435 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			435 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/perl
 | |
| # IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| #(C)IBM Corp
 | |
| #
 | |
| ###################################################################
 | |
| #
 | |
| # Description:
 | |
| #     The xcatsnap command gathers configuration, log and trace information
 | |
| #     about the xCAT components that are installed. This command only collects
 | |
| #     the data on the local node on which this command is run.
 | |
| #
 | |
| #     This command is typically executed when a problem is encountered with
 | |
| #     any of these components in order to provide service information to the
 | |
| #     IBM Support Center.
 | |
| #
 | |
| #     This command should only be executed at the instruction of the IBM
 | |
| #     Support Center.
 | |
| # Syntax:
 | |
| #       perl xcatsnap [-h] [-v] [-B] [-d output_directory]
 | |
| #
 | |
| # Flags:
 | |
| #       -h displays the usage of this command to standard output.
 | |
| #       -v displays the version of this tool.
 | |
| #       -B Bypass mode.
 | |
| #       -d is used to specify the output directory,
 | |
| #          otherwise the default directory is /tmp/xcatsnap
 | |
| #
 | |
| # Ouput:
 | |
| #     tar file : xcatsnap.host_name.nnnnnnnn.tar.gz
 | |
| #     log file : xcatsnap.host_name.nnnnnnnn.log
 | |
| #     (where host_name is the base name of the host name of the
 | |
| #     node on which the command is running; nnnnnnnn is a timestamp).
 | |
| #
 | |
| # Exit Status:
 | |
| #     0 - Command ran successfully
 | |
| #     1 - error occured
 | |
| #
 | |
| # Security:
 | |
| #     This command can only be run by a root user.
 | |
| #
 | |
| ####################################################################
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT =
 | |
|         $ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
 | |
|       : -d '/opt/xcat'   ? '/opt/xcat'
 | |
|       : '/usr';
 | |
| }
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| use File::Spec;
 | |
| use Getopt::Long;
 | |
| use strict;
 | |
| require xCAT::MsgUtils;
 | |
| my $OSname;
 | |
| my @Commands_array;
 | |
| my $Command_name;
 | |
| my $Command;
 | |
| my $currentDirectory;
 | |
| my $logDirectory="/tmp/xcatsnap";
 | |
| my $output_dir;
 | |
| my @files_array;
 | |
| my @file_list;
 | |
| my $TarFile;
 | |
| my $LogFile;
 | |
| my $INSTALLDIR;
 | |
| my $circular = 0;
 | |
| 
 | |
| ##############################FUNCTIONS##################################
 | |
| 
 | |
| ################### usage:Display usage message ##########################
 | |
| 
 | |
| sub usage {
 | |
|     print "Usage: xcatsnap [-h][-v][-B][-d output_directory]";
 | |
|     print "\n       -h Display this usage statement.";
 | |
|     print "\n       -v Display the version.";
 | |
|     print "\n       -B Run in bypass mode. Use if xcatd hung";
 | |
|     print "\n       -d Output directory (default:/tmp/xcatsnap)\n";
 | |
| }
 | |
| 
 | |
| ######### valid dir: Converts relative path to an absolute path #############
 | |
| 
 | |
| sub valid_dir {
 | |
|     $logDirectory = File::Spec->rel2abs($logDirectory);
 | |
|     my $Dir_last_char = substr $logDirectory, -1, 1;
 | |
|     if ( $Dir_last_char eq "/" ) {
 | |
|         chop($logDirectory);
 | |
| 
 | |
|     }
 | |
| }
 | |
| 
 | |
| ######################### run_cmd: Runs Commands ###############################
 | |
| 
 | |
| sub run_cmd {
 | |
|     my @output;
 | |
|     $Command_name = $Command;#Constructing the output file name from the command
 | |
|     $Command_name =~ s/ /_/g;
 | |
|     $Command_name =~ s/-//g;
 | |
|     $Command_name =~ s/tabdump_//g;
 | |
|     $Command_name =~ s/\//_/g;
 | |
|     
 | |
|     print "$Command -> $Command_name.out";
 | |
|     print "\n\tExecuting: $Command \n";
 | |
|     eval {
 | |
|         local $SIG{ALRM} = sub { die "Timeout\n" };
 | |
|         alarm 600;
 | |
|         @output = `$Command`;
 | |
|         alarm 0;
 | |
|     };
 | |
|     if ($@) {
 | |
|         print "\t$Command  timed out.\n";
 | |
|         @output = "$Command timed out.\n";
 | |
|     }
 | |
|     
 | |
|         print "\tExecution Complete :$Command.\n";    #Writing command output into a file
 | |
|         my $outfile = $output_dir . $Command_name . ".out";
 | |
|         open( MYFILE, ">", $outfile );
 | |
|         print MYFILE @output;
 | |
|         close(MYFILE);
 | |
|     
 | |
| }
 | |
| 
 | |
| ######################## Tar it: Tars files and folders #############################
 | |
| 
 | |
| sub Tar_it {
 | |
|     my $file= shift;
 | |
|     print "\n Processing $file ..\n";
 | |
|     my $last = substr $file, -1, 1;
 | |
|     if ( $last eq "*" ) {
 | |
|         @file_list = `ls $file 2>/dev/null`;
 | |
|         foreach my $i (@file_list) {
 | |
|             print "\tProcessing $i";
 | |
|         }
 | |
|     }
 | |
|     if ( -l $file ) {
 | |
| 
 | |
|         check_symbolic_link($file);    # Checking Symbolic links
 | |
|     }
 | |
|     if ( $circular != 1 ) {
 | |
|         if ( -e $TarFile ) {
 | |
|             `cd /; tar -uf $TarFile .$file 2>/dev/null`;
 | |
|         }
 | |
|         else {
 | |
|             `cd /; tar -cf $TarFile .$file 2>/dev/null`;
 | |
|         }
 | |
|     }
 | |
|     $circular = 0;
 | |
|     print "\n$file processed...\n";
 | |
| }
 | |
| 
 | |
| ################ check_symbolic_link: Checks symoblic links #####################
 | |
| 
 | |
| sub check_symbolic_link {
 | |
| 
 | |
|     my $file= shift;
 | |
|     my $max_link_count = 32;
 | |
|     my $i              = 0;
 | |
|     while ( defined( my $link = readlink $file ) && $i <= $max_link_count ) {
 | |
|         $file = $link;
 | |
|         $i++;
 | |
|     }
 | |
|     if ( $i >= $max_link_count ) {
 | |
|         $circular = 1;
 | |
|         print
 | |
| "Either the link is circular or the symbolic link count exceeds max_link_count";
 | |
|     }
 | |
| }
 | |
| 
 | |
| ############## make_output_dir: Creates output directory #######################
 | |
| 
 | |
| sub make_output_dir {
 | |
|     if ( -d $output_dir ) {
 | |
|         `rm -rf $output_dir`;
 | |
|     }
 | |
|     `mkdir  $output_dir`;
 | |
| }
 | |
| 
 | |
| ##################### snap_it:Does the main job ###########################
 | |
| 
 | |
| sub snap_it {
 | |
|     print "Collecting files ...\n";
 | |
|     chop( $INSTALLDIR =
 | |
|           `tabdump site | grep installdir | cut -f2 -d ,` );
 | |
|     $INSTALLDIR =~ s/"//g;
 | |
|     # make a list of all files in /tftpboot
 | |
|     # need to limit what we get due to size
 | |
|     `ls -lR /tftpboot > /tftpboot/tftpboot.list`;
 | |
|     if ( $OSname eq "AIX" ) {
 | |
|         
 | |
|         @files_array = (
 | |
|             "/etc/xcat/*","$::ROOTHOME/.xcat/*", "$INSTALLDIR/autoinst/*",
 | |
|             "$INSTALLDIR/postscripts/*", "$INSTALLDIR/prescripts/*",
 | |
|             "/tftpboot/*",               "/var/log/consoles/*",
 | |
|             "/tmp/spot.out.*",           "/var/lib/dhcpd/dhcpd.leases",
 | |
|             "/etc/hosts",                "/etc/conserver.cf",
 | |
|             "/var/log/conserver",        "/etc/db_file.cr",
 | |
|             "/etc/dhcpsd.cnf",           "/var/adm/ras/nimlog",
 | |
|             "/etc/resolv.conf", "/etc/named.conf",  "/var/log/messages", "/var/log/xcat/*");
 | |
|     }
 | |
| 
 | |
|     elsif ( $OSname eq "Linux" ) {
 | |
|         
 | |
|         @files_array = (
 | |
|             "/etc/xcat/*","$::ROOTHOME/.xcat/*", "$INSTALLDIR/autoinst/*",
 | |
|             "$INSTALLDIR/postscripts/*",   "$INSTALLDIR/prescripts/*", "$INSTALLDIR/custom/*", 
 | |
|             "/tftpboot/*",                 "/var/log/consoles/*",
 | |
|             "/etc/*-release",              "/etc/dhcpd.conf",
 | |
|             "/var/lib/dhcpd/dhcpd.leases", "/etc/hosts", "/etc/resolv.conf",
 | |
|             "/etc/named.conf", "/etc/conserver.cf",           "/var/log/conserver",
 | |
|             "/etc/nsswitch.conf",          "/var/log/messages", "/var/log/xcat/*");
 | |
|         print("@files_array \n");
 | |
|     }
 | |
|             foreach my $item (@files_array) {
 | |
|             my $file = $item;
 | |
|             Tar_it($file);
 | |
|         }
 | |
|     print "Done collecting files ...\n\n";
 | |
|     print "Gathering system configuration...\n\n";
 | |
|     $output_dir = "$logDirectory/commands_output/";
 | |
|     my $xcatroot=$ENV{'XCATROOT'};
 | |
|     my $installdir;
 | |
|     chop( $installdir =
 | |
|           `tabdump site | grep installdir | cut -f2 -d ,` );
 | |
|     make_output_dir();
 | |
|     if ( $OSname eq "AIX" ) {
 | |
|         @Commands_array = (
 | |
|             "uname -a","ifconfig -a","netstat -in","netstat -rn","env",
 | |
|             "reventlog -a","lsmod","/sbin/lspci","lssrc -a","rpm -qa",
 | |
|             "ls $installdir","/bin/crontab -l",
 | |
|             "find /tftpboot -size -32k","ls -lR $xcatroot",
 | |
|             "arp -a","ps -edlf","ps -aux","ulimit -a","df -k","oslevel",
 | |
|             "netstat -A","errpt -a","/usr/sbin/instfix -i",
 | |
|             "/usr/sbin/lsnim -l","lssrc -l -s dhcpsd","lslpp -hac","lsxcatd -a");
 | |
|     }
 | |
|     elsif ( $OSname eq "Linux" ) {
 | |
|         @Commands_array = (
 | |
|             "uname -a","ifconfig -a","netstat -in","netstat -rn","env",
 | |
|             "reventlog -a","lsmod","/sbin/lspci","lssrc -a","rpm -qa",
 | |
|             "ls $installdir","/usr/bin/crontab -l",
 | |
|             "find /tftpboot -size -32k","ls -lR $xcatroot",
 | |
|             "arp -a","ps -edlf","ps -aux","ulimit -a","df -k",
 | |
|             "cat /etc/issue","lsxcatd -a","cat /proc/meminfo", "cat /proc/cpuinfo");
 | |
|     }
 | |
|     foreach my $item (@Commands_array) {
 | |
|         $Command = $item;
 | |
|         run_cmd;
 | |
|     }
 | |
|     print "Done gathering system configuration...\n\n";
 | |
| 
 | |
|     if ( -d "/opt/xcat/" ) {
 | |
|         print "Capturing xCAT specific information...\n\n";
 | |
|         print "Gathering management node configurations...\n";
 | |
|         @Commands_array = (
 | |
|             "lsdef -t site -l","lsdef -t group -l","lsdef -t osimage -l",
 | |
|             "nodels","lsdef -t node -l","rpower all stat","nodestat all",
 | |
|             "nodels all groups","monls -a","lsvm all","rinv all all",
 | |
|             "rvitals all all");
 | |
|         foreach my $item (@Commands_array) {
 | |
|             $Command = $item;
 | |
|             run_cmd;
 | |
|         }
 | |
|         print "Done gathering managment node configuration...\n\n";
 | |
|         print "Retrieving xCAT database...\n";
 | |
|         $output_dir = "$logDirectory/xcat-database/";
 | |
|         make_output_dir();
 | |
|         # do not snap the ISNM tables, too big
 | |
|         my $cmd;
 | |
|         $cmd="XCAT_SKIPTABLES=isnm_perf,isnm_perf_dlink,isnm_perf_dlink_sum,isnm_perf_hfi,isnm_perf_hfi_sum,isnm_perf_isr,isnm_perf_isr_sum,isnm_perf_lllink,isnm_perf_lllink_sum,isnm_perf_lrlink,isnm_perf_lrlink_sum,isnm_perf_sum";
 | |
|          $cmd .= " dumpxCATdb -p $output_dir";
 | |
|         `$cmd`;
 | |
|         # now get auditlog and eventlog, last two days
 | |
|          # get number of seconds in the day count
 | |
|          my $numberdays=2;
 | |
|          my $numbersecs=($numberdays * 86400);
 | |
|         # get time now
 | |
|         my $timenow=time;
 | |
|         my $secsdaysago=$timenow - $numbersecs;
 | |
|          # Format like the database table timestamp record
 | |
|         my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
 | |
|               localtime($secsdaysago);
 | |
|          my $daysago = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
 | |
|                                         $year + 1900, $mon + 1, $mday,
 | |
|                                         $hour, $min, $sec);
 | |
|         # now tabdump days gt 2 days ago
 | |
|         $cmd = "tabdump -w \"audittime>$daysago\" auditlog > $output_dir/auditlog.csv";
 | |
| 
 | |
|         `$cmd`;
 | |
|         $cmd = "tabdump -w \"eventtime>$daysago\" eventlog > $output_dir/eventlog.csv";
 | |
| 
 | |
|         `$cmd`;
 | |
|  
 | |
|         print "xCAT database retrieved.\n";
 | |
|     }
 | |
|     `rm /tftpboot/tftpboot.list`;  # remove temp list
 | |
| }    
 | |
| ##################### getHomeDirectory ###########################
 | |
| #  input userid output homedir
 | |
| #####################################################################
 | |
| sub getHomeDir
 | |
| {
 | |
|   my @user;
 | |
|   my $homedir;
 | |
|   @user = getpwuid($>);
 | |
|   my $username=$user[0];
 | |
| 
 | |
|   if ($user[7]) { #  if homedir
 | |
|       $homedir= $user[7];
 | |
|   } else { # no home
 | |
|       $homedir=`su - $username -c  pwd`;
 | |
|       chop $homedir;
 | |
|   }
 | |
|   return $homedir;
 | |
| 
 | |
| }
 | |
| ############################# Main Section ####################################
 | |
| 
 | |
| my $userid = `id -ru`;    #Checking if the user is root
 | |
| if ( $userid != 0 ) {
 | |
|     print "You must be root to run the xcatsnap tool";
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| `export PATH=/opt/xcat/bin:/opt/xcat/sbin:/bin:/sbin:/usr/bin:/usr/sbin:`;
 | |
| 
 | |
| #Checking the program arguments
 | |
| 
 | |
| if (
 | |
|     !GetOptions(
 | |
|                 'd|dir=s'        => \$::DIRECTORY,
 | |
|                 'B|bypass'     => \$::BYPASS,
 | |
|                 'h|help'       => \$::HELP,
 | |
|                 'v|version'    => \$::VERSION,
 | |
|     )
 | |
|   )
 | |
| {
 | |
|     &usage;
 | |
|     exit(1);
 | |
| }
 | |
| if ($::HELP ) {
 | |
|     usage();
 | |
|     exit 0;
 | |
| }
 | |
| if ($::VERSION) {
 | |
|         my $version = xCAT::Utils->Version();
 | |
|         $version .= "\n";
 | |
|         xCAT::MsgUtils->message("N", $version);
 | |
|         exit 0;
 | |
| 
 | |
|     exit 0;
 | |
| 
 | |
| }
 | |
| if ($::BYPASS)
 | |
| {
 | |
|     $ENV{XCATBYPASS} = "yes";  # bypass xcatd
 | |
| }
 | |
| 
 | |
| 
 | |
| if (!($::DIRECTORY)) {
 | |
|     print " Log Directory will be /tmp/xcatsnap/\n";
 | |
| }
 | |
| else  {
 | |
|     $logDirectory = $::DIRECTORY ;
 | |
|     valid_dir();
 | |
| }
 | |
| unless ( -d $logDirectory ) {   #Create the output directory if it doesn't exist
 | |
|     `mkdir -p $logDirectory`;
 | |
|      if ($?!=0) {  
 | |
|        print " Could not create $logDirectory\n";
 | |
|        exit 1;
 | |
|      }  
 | |
|   
 | |
|     valid_dir();
 | |
| }
 | |
| my $hostname;
 | |
| chop( $OSname   = `uname` );
 | |
| chop( $hostname = `hostname -s` );
 | |
| my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
 | |
|   localtime(time);
 | |
| $mon = $mon + 1;
 | |
| my @date_array = ( $mon, $mday, $hour, $min );
 | |
| foreach my $item (@date_array) {
 | |
|     $item =
 | |
|       sprintf( "%2d", $item );    #Formatting the date for dispaly in file name
 | |
|     $item =~ tr/ /0/;
 | |
| }
 | |
| my $logdate = $date_array[0] . $date_array[1] . $date_array[2] . $date_array[3];
 | |
| $LogFile = $logDirectory . "/xcatsnap." . $hostname . "." . $logdate . ".log";
 | |
| $TarFile = $logDirectory . "/xcatsnap." . $hostname . "." . $logdate . ".tar";
 | |
| 
 | |
| open( STDOUT, "| tee  $LogFile" );
 | |
| print "Time Stamp:" . `date`;
 | |
| print "Log Directory: $logDirectory \n";
 | |
| print "Preparation Complete...\n";
 | |
| $::ROOTHOME = &getHomeDir();
 | |
| snap_it(); # Calling the main function that gathers files,command output and MN database
 | |
| print "Compiling Information...\n";
 | |
| `cd $logDirectory;tar -uf $TarFile "./commands_output" 2>/dev/null`;
 | |
| `cd $logDirectory;tar -uf $TarFile "./xcat-database" 2>/dev/null`;
 | |
| `rm -rf $logDirectory/commands_output/`;
 | |
| `rm -rf $logDirectory/xcat-database/`;
 | |
| 
 | |
| print "Information compiled...\n";
 | |
| `chmod 400 $LogFile`;    # Processing the log file
 | |
| print "Send $LogFile to IBM Support.\n";
 | |
| my $donotdelete=0;
 | |
| if ( `which gunzip` == 0 ) {    # Compressing the tar file
 | |
|     `gzip -f $TarFile`;
 | |
| }
 | |
| elsif ( `which compress` == 0 ) {
 | |
|     `compress -f $TarFile`;
 | |
| }
 | |
| else {
 | |
|     print
 | |
| "gzip and compress are not available. The tar file $TarFile will not be compressed";
 | |
| $donotdelete=1;
 | |
| }
 | |
| 
 | |
| if (-e $TarFile  && $donotdelete == 0){   # Don't remove if only file to send 
 | |
|     `rm $TarFile`;
 | |
| }
 | |
| 
 | |
| if ( -e $TarFile . ".gz" ) {
 | |
|     `chmod 400 $TarFile".gz"`;
 | |
|     print "Send $TarFile.gz to IBM Support.\n";
 | |
| }
 | |
| elsif ( -e $TarFile . ".z" ) {
 | |
|     `chmod 400 $TarFile".z"`;
 | |
|     print "Send $TarFile.z to IBM Support.\n";
 | |
| }
 | |
| elsif ( -e $TarFile ) {
 | |
|     `chmod 400 $TarFile`;
 | |
|     print "Send $TarFile to IBM Support.\n";
 | |
| }
 | |
| close(STDOUT);
 | |
| exit 0;
 |