#! /bin/bash

###############################################################################
# collect some configuration, trace, and debug
# information about the S390 Linux system
#
# Copyright (C) 2002, 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
###############################################################################

#
# variables
#

SCRIPTNAME="dbginfo.sh"
WORKDIR=DBGINFO-`date +%Y-%m-%d-%H-%M-%S`
# write output to following directory
WORKPFX=/tmp
WORKPATH=$WORKPFX/$WORKDIR
# write output to following files
CMDOUTPUT=runtime.out

LOGFILE=dbginfo.log

# procfs entries to be collected (except s390dbf and scsi)
PROCFILES=" \
    /proc/version \
    /proc/cpuinfo \
    /proc/meminfo \
    /proc/slabinfo \
    /proc/modules \
    /proc/subchannels \
    /proc/chpids \
    /proc/chandev \
    /proc/qeth \
    /proc/qeth_ipa_takeover \
    /proc/dasd/devices \
    /proc/partitions \
    /proc/ksyms \
    "
# log files to be collected
LOGFILES=" \
    /var/log/kern.all \
    /var/log/messages \
    "
# config files to be collected;
# additional all files "modules.dep" are collected
CONFIGFILES=" \
    /etc/chandev.conf \
    /etc/modules.conf \
    /etc/zfcp.conf \
    "

# collect output of following commands;
# commands are separated by ':'
CMDS="ps aux\
    :ps axX\
    :dmesg -s 1048576\
    :ifconfig -a\
    "
#
# function definitions
#

# print usage and help
printhelp()
{
    echo "Usage: $SCRIPTNAME [OPTIONS]"
    echo "This script collects some runtime, configuration and"
    echo "trace information about your Linux for zSeries system"
    echo "for debugging purposes."
    echo "Options:"
    echo
    echo "        -h, --help       print this help"
    echo
    echo "Currently no real options available."

}

# copy file $1 to $WORKPATH
collect_file_contents()
{
    echo "  $1"  | tee -a $LOGFILE
    if [ ! -e $1 ]
    then
	echo "  WARNING: No such file: \"$1\"" | tee -a $LOGFILE
	return 1
    elif [ ! -r $1 ]
    then
	echo "  WARNING: Permission denied: \"$1\"" | tee -a $LOGFILE
	return 1
    else
	if [ ! -e $WORKPATH`dirname $1` ]
	then
	    mkdir --parents $WORKPATH`dirname $1`
	fi
	cp -d --parents $1 $WORKPATH
# 	head -c 10m $1 >> $2
	if [ $? -ne 0 ]
	then
	    echo "  WARNING: cp failed for file: \"$1\"" | tee -a $LOGFILE
	    return 1
	else
	    return 0
	fi
    fi
}

# append output of command $1 to file $2
collect_cmd_output()
{
    echo "  $1"
    echo "$USER@$HOST> $1" >> $2
    $1 1>>$2 2>&1
    if [ $? -ne 0 ]
    then
	echo "  WARNING: Command not successfully completed: \"$1\"" | tee -a $2
	return 1
    else
	return 0
    fi
}

# check cmd line arguments
check_cmdline()
{
    # currently no options available
    if [[ $# -eq 1 ]] &&  ( [[ $1 = '-h' ]] ||  [[ $1 = '--help' ]] )
    then
	printhelp
	exit 0
    elif [[ $# -ge 1 ]]
    then
	echo "ERROR: Invalid arguments"
	echo 
	printhelp
	exit 1
    fi    
}

# change into temporary directory; if necessary create the directory
prepare_workdir()
{
    if [ -e $WORKPATH ]
    then
	# remove old stuff
	echo "Clean up target directory $WORKPATH"
	rm -rf $WORKPATH/*
    else
	echo "Create target directory $WORKPATH"
	mkdir $WORKPATH
    fi
    echo "Change to target directory $WORKPATH"
    cd $WORKPATH
}

# collect single proc fs entries
# (PRCFILES should not contain /proc/scsi and /proc/s390dbf)
collect_procfs()
{
    echo "Get procfs entries" | tee -a $LOGFILE
    for i in $PROCFILES
    do
	collect_file_contents $i
    done
}

# collect procfs entries of /proc/s390dbf
collect_s390dbf()
{
    echo "Get entries of /proc/s390dbf" | tee -a $LOGFILE
    if [ -e /proc/s390dbf ]
    then
	for i in `find /proc/s390dbf -type f \
                  -not -path "*/raw" -not -path "*/flush"`
	do
	    collect_file_contents $i
 	done
    else
	echo "  WARNING: /proc/s390dbf not found" | tee -a $LOGFILE
    fi
}

# collect procfs entries of /proc/scsi
collect_procfs_scsi()
{
    echo "Get entries of /proc/scsi" | tee -a $LOGFILE
    if [ -e /proc/scsi ]
    then
	for i in `find /proc/scsi -type f \
                  -perm +0444`
	do
	    collect_file_contents $i
	done
    else
	echo "  WARNING: /proc/scsi not found" | tee -a $LOGFILE
    fi
}

# collect output of commands
collect_cmdsout()
{
    echo "Saving runtime information into $CMDOUTPUT" | tee -a $LOGFILE
    _IFS_ORIG=$IFS
    IFS=:
    for i in $CMDS
    do
	IFS=$_IFS_ORIG
	collect_cmd_output "$i" $CMDOUTPUT
	IFS=:
    done
    IFS=$_IFS_ORIG
}

# config files and module dependencies
collect_config()
{
    echo "Copy config files" | tee -a $LOGFILE
    for i in $CONFIGFILES
    do
	collect_file_contents $i
    done
    for i in `find /lib/modules -name modules.dep`
    do
	collect_file_contents $i
    done
}

# log files
collect_log()
{
    echo "Copy log files" | tee -a $LOGFILE
    for i in $LOGFILES
    do
	collect_file_contents $i
    done
}

# create gzip-ped tar file
create_package()
{
    cd $WORKPATH/..
    tar -czf $WORKDIR.tgz $WORKDIR 2>/dev/null && rm -rf $WORKPATH
    echo
    echo "Collected data was saved to:"
    echo "  $WORKPFX/$WORKDIR.tgz"
}

#
# start of script
#

check_cmdline
prepare_workdir
collect_s390dbf
collect_procfs
collect_procfs_scsi
collect_cmdsout
collect_config
collect_log
create_package

#
# end of script
#

#EOF