mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			442 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			442 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;
 |