#!/usr/bin/perl require 5.006; BEGIN { use File::Basename; $binDir = dirname($0); unshift(@INC, "$binDir" ); } while (@ARGV) { $arg = shift @ARGV; $nostrict = 1 if $arg =~ /^--no-strict/i; usage() if $arg =~ /^-h/i; } use setup; use reputils; setup::setupEnv(); $sysname = (POSIX::uname())[0]; $IS_WIN = ($sysname =~ /^win/i); print << "EOM"; ===================== INFO ======================== The talkback agent will capture relevant configuration and log files to help WANdisco diagnoss the problem you may be encountering. EOM @LOSF = qw( /etc/services /etc/xinetd.d/cvspserver /etc/xinetd.d/svnserve /etc/inetd.conf /etc/xinetd.conf /etc/sysctl.conf /proc/sys/fs/file-max /etc/prefs.conf /var/log/messages /var/log/syslog /proc/sys/fs/file-nr /etc/security/limits.conf ); $PROD_TYPE = $setup::PROD_TYPE; $dav = $setup::prefs{"Preferences/SVNProxy/useHttp"}; $dav = ($dav =~ /^true/i ? 1 : undef); $ans = reputils::userChoiceSelect("Is $PROD_TYPE Repository on localhost ?Y|N", "Y"); $isLocal = 1 if ($ans =~ /^y/i); while ($isLocal && !$cvs) { $cvs = "/home/${PROD_TYPE}root"; $cvs = reputils::userPrompt("\nSpecify path to the $PROD_TYPE repository's root", $cvs); $config = ( $PROD_TYPE eq "svn" ? "$cvs/conf/svnserve.conf" : "$cvs/CVSROOT/config"); if (!-r $config) { print "**E: Invalid path $config\n"; undef $cvs; } } while ($isLocal && $dav && !$apache) { $apache = "/usr/local/apache2/conf"; $apache = reputils::userPrompt("\nSpecify path to Apache config directory", $apache); if (!-r $apache) { print "**E: Invalid path $apache\n"; undef $apache; } } push @LOSF, <$apache/*conf>; if ($isLocal && -d "$apache/extra") { push @LOSF, <$apache/extra/*conf>; } $cvspass = ( $PROD_TYPE eq "svn" ? "$cvs/conf/passwd" : "$cvs/CVSROOT/passwd"); push @LOSF, $config if ($isLocal); push @LOSF, $cvspass if ($isLocal && !$dav && -r $cvspass); $BUILD_ROOTDIR = $setup::BUILD_ROOTDIR; $PREFS_ROOT = $setup::PREFS_ROOT; $LOG_DIR = $setup::LOG_DIR; $LIB_DIR = "$BUILD_ROOTDIR/lib"; $DB_DIR = "$BUILD_ROOTDIR/systemdb"; $WIN_BIN = "$BUILD_ROOTDIR/bin/win"; push @LOSF, "$PREFS_ROOT/prefs.xml"; push @LOSF, "$LOG_DIR/console.txt"; push @LOSF, "$PREFS_ROOT/log.properties"; push @LOSF, "$PREFS_ROOT/license.key"; if ($PROD_TYPE eq "svn"){ $LOGFILE = "$LOG_DIR/SVNProxyServer-prefs.log"; push @LOSF, "$PREFS_ROOT/svnokerr.catalog"; } else { $LOGFILE = "$LOG_DIR/ProxyServer-prefs.log"; push @LOSF, "$PREFS_ROOT/cvserr-nonsys.catalog"; push @LOSF, "$PREFS_ROOT/cvserr-sys.catalog"; } if (-e "$LOGFILE") { push @LOSF, "$LOGFILE"; } elsif (-e "$LOGFILE.0") { push @LOSF, "$LOGFILE.0"; push @LOSF, "$LOGFILE.1" if (-e "$LOGFILE.1"); push @LOSF, "$LOGFILE.2" if (-e "$LOGFILE.2"); } $jpid = mkThreadDump(); $rootdir = "$ENV{HOME}/.tmp"; mkdir $rootdir; $status = "$rootdir/rep-status"; open(OF, ">$status") or die "**F: failed to open $status for writing,\ncheck permissions or disk space\n"; $LAX = 1; if ($IS_WIN) { capture("dir"); capture("dir \"$BUILD_ROOTDIR\""); capture("dir \"$LIB_DIR/${PROD_TYPE}-replicator.jar\""); capture("dir \"$DB_DIR\"",1); capture("ver"); capture("$ENV{JAVA_HOME}/bin/java -version",1); capture("echo \%PATH%", 1); capture("\"$WIN_BIN/pslist\" ${PROD_TYPE}"); capture("\"$WIN_BIN/pslist\" java"); capture("\"$WIN_BIN/pslist\" perl"); } else { capture("uptime", 1); capture("pwd"); capture("find $BUILD_ROOTDIR -type d", 1); capture("ls -al $LIB_DIR/${PROD_TYPE}-replicator.jar"); capture("md5sum $LIB_DIR/${PROD_TYPE}-replicator.jar", 1); capture("ls -al $DB_DIR") if (-e "$DB_DIR"); capture("md5sum $DB_DIR/${PROD_TYPE}-proposal*") if (-e "$DB_DIR"); capture("uname -a"); capture("which ${PROD_TYPE}"); capture("$ENV{JAVA_HOME}/bin/java -version",1); capture("$ENV{JAVA_HOME}/bin/java -version",1); capture("ps -leaf | grep ${PROD_TYPE}"); capture("ps -leaf | grep java"); capture("ps -leaf | grep wdog"); capture("top -b -n 1"); captureFDs($jpid); capture("/bin/sh -c \"ulimit -a\""); capture("df -k $LOG_DIR", 1); capture("df -k /tmp", 1); capture("echo $ENV{CVSROOT}", 1); capture("echo $${PROD_TYPE}", 1) if ($cvs); capture("whereis ${PROD_TYPE}", 1); capture("echo $ENV{PATH}", 1); # captureWebConsole(); } capture("java -server -version",1); capture("netstat -an"); if ($PROD_TYPE eq "svn"){ capture("svn --version", 1); capture("which svn", 1); capture("svnserve --version", 1); capture("which svnserve", 1); if ($dav) { $apacheHome = "$apache/../bin"; $apctl = ( -e "$apacheHome/apache2ctl" ? "$apacheHome/apache2ctl" : "$apacheHome/apachectl" ); capture("$apctl -v", 1); capture("$apctl -t", 1); capture("$apctl -l", 1); } } else { capture("cvs -version", 1); } close(OF); push @LOSF, $status; $tmpdir = "$rootdir/talkback"; use File::Path; rmtree($tmpdir); mkdir "$tmpdir" or die "**F : failed to create $tmpdir, please check permissions\n"; foreach $file (@LOSF) { $cpcmd = "cp $file $tmpdir"; #print "$cpcmd\n"; use File::Copy; if (-r $file) { use File::Basename; $unqf = basename($file); copy("$file", "$tmpdir/$unqf") or die "$cpcmd failed: $!\n"; } } $host = (POSIX::uname())[1]; $tarball = ($IS_WIN ? "$ENV{HOME}/talkback-$host.zip" : "$ENV{HOME}/talkback-$host.tar"); if ($sysname =~ /^Linux/) { $tarargs = "z"; $tarball .= ".gz"; } if (! $IS_WIN ) { $tarcmd = "tar ${tarargs}cf $tarball talkback"; system("cd $rootdir; $tarcmd") && die "\n**F: Failed to execute $tarcmd\n"; } else { mkZip("$tmpdir", "$tarball"); } print << "EOM"; --------------------------------------------------------------- Please open a ticket by visting http://support.wandisco.com and upload the $tarball, with a description of the issue. Note: do not email the talkback files, only attach them via the web ticket user interface. -------------------------------------------------------------- EOM use File::Path; #rmtree($tmpdir); #system("rm -rf $tmpdir") && die "**F: please delete $tmpdir\n"; print "\nDone.\n"; #-- subs --- sub mkZip { my ($srcd, $zipfile) = @_; require Archive::Zip;# qw( :ERROR_CODES :CONSTANTS ); my $zip = Archive::Zip->new(); my $member = $zip->addTree("$srcd", "talkback" ); #$member->desiredCompressionMethod( COMPRESSION_DEFLATED ); die '**E: failed to zip $srcd\n' unless $zip->writeToFileNamed("$zipfile" ) == AZ_OK; } sub captureFDs { my $PID = $_[0]; return if (!$PID); if ($sysname =~ /Linux/i) { $fdz = "ls -l /proc/$PID/fd/"; } elsif ($sysname =~ /SunOS/i) { $fdz = "pfiles $PID"; } capture("$fdz"); } sub capture { my $cmd = $_[0]; my $lax = $nostrict; $lax = $_[1] if $_[1]; $rv = open(CMD, "$cmd 2>&1 |"); if ( !$rv && $lax) { return; } elsif (! $rv ) { die "**F: failed to run the command \"$cmd\", please ensure PATH is setup correctly\n"; } print OF "--- $cmd start --\n"; while() { print OF $_; } my $out = ; close(CMD); print OF "--- $cmd end --\n\n"; } sub captureWebConsole { #TODO # Locate wget or lynx on the path } sub mkThreadDump { if ($IS_WIN) { mkWin32ThreadDump(); return; } my $jpid; my $pfile = "$LOG_DIR/java.pid"; chomp($jpid = `cat $pfile`) if (-r $pfile); if (!$jpid) { $rv = open(PP, "ps -leaf | grep ${PROD_TYPE}-replicator |"); while() { if (/perl\b/) { @pidfields = split /\s+/; $wpid = $pidfields[3]; last; } } close(PP); $rv = open(JP, "ps -leaf | grep $wpid | grep java |"); return if (!$rv); while() { if (/java\b/) { @pidfields = split /\s+/; $jpid = $pidfields[3]; last; } } close(JP); } if (!$jpid) { print "\n**W: No java replicator process found user with uid = $< .\nIf possible run talkback with replicator running.\n"; return; } kill 'QUIT', $jpid; return $jpid; } sub mkWin32ThreadDump { $pscmd = "$WIN_BIN/pslist java"; # print "$pscmd\n"; open(PH, "$pscmd 2>&1 |") or die "failed to run $pscmd\n"; while() { # print "$_\n"; next if !(/^java\s+(\d+)\s+/); $jpid = $1; next if !$jpid; $sgcmd = "$WIN_BIN/SendSignal $jpid"; system($sgcmd); } } sub usage { print << "EOM"; talkback [--no-strict] \ttalkback captures information for WANdisco to diagnoss problems easily. \tIt creates a \$HOME/talkback-.tar.gz file which you need to upload \tto http://support.wandisco.com when filing issue ticket. --no-strict: \tThis option enables talkback to keep going even when failures \tare encountered like /bin not being on the path. EOM exit(0); }