399 lines
9.8 KiB
Bash
Executable File
399 lines
9.8 KiB
Bash
Executable File
#!/bin/sh
|
|
##########################################################
|
|
# Copyright (c) 2006-2022 VMware, Inc. All rights reserved.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU Lesser General Public License as published
|
|
# by the Free Software Foundation version 2.1 and no later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
# or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
|
|
# License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
#
|
|
##########################################################
|
|
|
|
# usage(): prints how to use this script
|
|
usage()
|
|
{
|
|
echo ""
|
|
echo "Usage: $0 [-hux]"
|
|
echo " -h prints this usage statement"
|
|
echo " -u updates the host with the state of support data" \
|
|
"collection process"
|
|
echo " -x transfers support data to the host"
|
|
exit 1
|
|
}
|
|
|
|
|
|
# banner(): prints any number of strings padded with
|
|
# newlines before and after.
|
|
banner()
|
|
{
|
|
echo
|
|
for option in "$@"
|
|
do
|
|
echo $option
|
|
done
|
|
echo
|
|
}
|
|
|
|
|
|
# The status constants are important and have to be kept
|
|
# in sync with VMware Workstation implementation
|
|
|
|
# vm-support script is not running
|
|
VMSUPPORT_NOT_RUNNING=0
|
|
# vm-support script is beginning
|
|
VMSUPPORT_BEGINNING=1
|
|
# vm-support script running in progress
|
|
VMSUPPORT_RUNNING=2
|
|
# vm-support script is ending
|
|
VMSUPPORT_ENDING=3
|
|
# vm-support script failed
|
|
VMSUPPORT_ERROR=10
|
|
# vm-support collection not supported
|
|
VMSUPPORT_UNKNOWN=100
|
|
|
|
#internal state machine state for update
|
|
update=0
|
|
|
|
#internal state machine state for transfering logs to host
|
|
transfer=0
|
|
|
|
# UpdateState($state): Updates the VM with the given state.
|
|
UpdateState()
|
|
{
|
|
if [ $update -eq 1 ]; then
|
|
vmware-xferlogs upd $1
|
|
fi
|
|
}
|
|
|
|
|
|
# checkOutputDir(): checks for a self contained output
|
|
# directory for later tar'ing and creates it if needed
|
|
|
|
checkOutputDir()
|
|
{
|
|
dir="$1"
|
|
|
|
if [ ! -d "${OUTPUT_DIR}$dir" ]; then
|
|
mkdir -p "${OUTPUT_DIR}$dir"
|
|
|
|
if [ $? != 0 ]; then
|
|
banner "Could not create ${OUTPUT_DIR}$dir... " \
|
|
"Have you run out of disk space?" "Continuing"
|
|
return -1
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
# addfile(): copies whatever files and directories you give it to
|
|
# a self contained output directory for later tar'ing
|
|
# Working on copies could slow this down with VERY large files but:
|
|
# 1) We don't expect VERY large files
|
|
# 2) Since /proc files can be copied this preserves the tree without
|
|
# having to cat them all into a file.
|
|
# 3) tar barfs on open files like logs if it changes while it's tar'ing.
|
|
# Copying file first makes sure tar doesn't complain
|
|
addfile()
|
|
{
|
|
file="$1"
|
|
|
|
if [ ! -e "$file" ]; then
|
|
return 2
|
|
fi
|
|
|
|
dir=`dirname "$file"`
|
|
checkOutputDir "$dir"
|
|
if [ $? != 0 ]; then
|
|
return $?
|
|
fi
|
|
|
|
# Ignore stdout and handle errors.
|
|
cp -pRP "$file" "${OUTPUT_DIR}$dir" 2>/dev/null
|
|
if [ $? != 0 ]; then
|
|
banner "Could not copy '$file' to the tar area."
|
|
fi
|
|
}
|
|
|
|
|
|
# addfiles(): adds a list of files to the archive.
|
|
addfiles()
|
|
{
|
|
for i in "$@"; do
|
|
addfile $i
|
|
done
|
|
}
|
|
|
|
|
|
# runcmd($out, $cmd): executes the command redirected to a file
|
|
runcmd()
|
|
{
|
|
outFileRelPath="$1"
|
|
shift # The command arguments are in "$@".
|
|
|
|
dir=`dirname "$outFileRelPath"`
|
|
checkOutputDir "$dir"
|
|
if [ $? != 0 ]; then
|
|
return
|
|
fi
|
|
|
|
"$@" > "$OUTPUT_DIR$outFileRelPath" 2>/dev/null
|
|
if [ $? != 0 ]; then
|
|
echo 3
|
|
banner "Either could not run $@ or could not write to" \
|
|
"${OUTPUT_DIR}$outFileRelPath" \
|
|
"Do you have a full disk? Continuing..."
|
|
fi
|
|
}
|
|
|
|
|
|
# stageLinux(): gather information for troubleshooting Linux guests.
|
|
stageLinux()
|
|
{
|
|
# Try to collect bootloader config.
|
|
addfile /etc/lilo.conf
|
|
|
|
# Old linux kernel use modules.conf while new kernel use modprobe.conf and modprobe.d
|
|
addfile /etc/modules.conf
|
|
addfile /etc/modprobe.conf
|
|
addfile /etc/modprobe.d
|
|
|
|
addfile /etc/cron.daily
|
|
addfile /etc/cron.hourly
|
|
addfile /etc/cron.monthly
|
|
addfile /etc/cron.weekly
|
|
addfile /etc/crontab
|
|
addfile /etc/ntp.conf
|
|
addfile /etc/services
|
|
addfile /proc/interrupts
|
|
addfile /proc/irq
|
|
|
|
# Commands to run ($2) and redirect to logs ($1) for inclusion.
|
|
runcmd "/tmp/ps-auwwx.txt" ps auwwx
|
|
runcmd "/tmp/lspci1.txt" lspci -M -vvv -nn -xxxx
|
|
runcmd "/tmp/lspci2.txt" lspci -t -v -nn -F "${OUTPUT_DIR}/tmp/lspci1.txt"
|
|
runcmd "/tmp/lspci3.txt" lspci -vvv -nn
|
|
runcmd "/tmp/modules.txt" /sbin/lsmod
|
|
runcmd "/tmp/uname.txt" uname -a
|
|
runcmd "/tmp/issue.txt" cat /etc/issue
|
|
if which rpm > /dev/null; then
|
|
runcmd "/tmp/rpm-qa.txt" rpm -qa
|
|
fi
|
|
if which apt > /dev/null; then
|
|
runcmd "/tmp/apt-list.txt" apt list
|
|
fi
|
|
runcmd "/tmp/free.txt" free
|
|
}
|
|
|
|
|
|
# stageFreeBSD(): gather information for troubleshooting FreeBSD guests.
|
|
stageFreeBSD()
|
|
{
|
|
runcmd "/tmp/ps-auwwx.txt" ps auwwx
|
|
}
|
|
|
|
# stageSolaris(): gather information for troubleshooting Solaris guests.
|
|
stageSolaris()
|
|
{
|
|
runcmd "/tmp/ps-eaf.txt" ps -eaf
|
|
}
|
|
|
|
|
|
# error(): prints an error message using the "banner" funtion and quits.
|
|
error()
|
|
{
|
|
banner "$@"
|
|
UpdateState $VMSUPPORT_ERROR
|
|
exit 1
|
|
}
|
|
|
|
|
|
# Cleanup our temp folder and optionally exit.
|
|
cleanup()
|
|
{
|
|
exitCode="$1"
|
|
|
|
rm -rf "$OUTPUT_DIR"
|
|
if [ $? != 0 ]; then
|
|
banner "$OUTPUT_DIR was not successfully removed." \
|
|
"Please remove manually."
|
|
fi
|
|
|
|
if [ "$exitCode" ]; then
|
|
exit "$exitCode"
|
|
fi
|
|
}
|
|
|
|
collectNetworkDetails()
|
|
{
|
|
if which ip >/dev/null; then
|
|
runcmd "/tmp/ip-addr.txt" ip addr
|
|
runcmd "/tmp/ip-route.txt" ip route
|
|
else
|
|
runcmd "/tmp/ifconfig.txt" ifconfig -a
|
|
runcmd "/tmp/route.txt" route
|
|
fi
|
|
|
|
if which ss >/dev/null; then
|
|
runcmd "/tmp/ss-lan.txt" ss -lan
|
|
else
|
|
runcmd "/tmp/netstat-lan.txt" netstat -lan
|
|
fi
|
|
}
|
|
|
|
# This executable may run with root privileges, so hardcode a PATH where
|
|
# unprivileged users cannot write.
|
|
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
|
|
|
TARFILE=vm-`date +%Y-%m-%d`.$$.tar.gz
|
|
VER=0.95
|
|
|
|
# Parse args
|
|
for option in $@
|
|
do
|
|
case $option in
|
|
"-h")
|
|
usage
|
|
;;
|
|
"-u")
|
|
update=1
|
|
;;
|
|
"-x")
|
|
transfer=1
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Start message
|
|
|
|
UpdateState $VMSUPPORT_BEGINNING
|
|
|
|
banner "VMware UNIX Support Script $VER"
|
|
|
|
# Check for root privledge
|
|
|
|
if [ `whoami` != 'root' ]; then
|
|
error "Please re-run this program as root. "
|
|
fi
|
|
|
|
# Source /etc/profile. If we can't find it, it's the users problem to get
|
|
# their paths straight.
|
|
if [ -f /etc/profile ]; then
|
|
. /etc/profile
|
|
fi
|
|
|
|
# Protect against non-default values of $IFS (Not all scripts in /etc/profile.d/
|
|
# are good citizens).
|
|
if [ `uname` != 'SunOS' ]; then
|
|
unset IFS 2>/dev/null
|
|
fi
|
|
|
|
# Create a temporary directory to place the files to archive.
|
|
#
|
|
# o mktemp creates a new directory, with a random name, and gives it
|
|
# permissions 700 so only the current user (and root) can access the
|
|
# contents of the directory. This prevents a rogue user from:
|
|
# 1) Guessing the name of the directory.
|
|
# 2) Performing a symlink attack inside the directory.
|
|
# 3) Reading data inside the directory, that only the current user (and root)
|
|
# are supposed to access.
|
|
# o The directory is created inside /tmp, so only the current user (and root)
|
|
# can delete the directory. This prevents a rogue user from wholesale
|
|
# replacing the directory after we have created it, with a directory that has
|
|
# more lenient permissions.
|
|
OUTPUT_DIR="`mktemp -d /tmp/vm-support.XXXXXX`"
|
|
if [ $? != 0 ]; then
|
|
banner "Could not create a secure temporary directory. Exiting..."
|
|
exit 1
|
|
fi
|
|
|
|
# Cleanup our temp folder if the process is signalled midway.
|
|
trap "cleanup 1" HUP INT QUIT TERM ABRT
|
|
|
|
banner "Collecting support information..."
|
|
|
|
# Common stuff that we gather for all OSes.
|
|
runcmd "/tmp/vm-support-version.txt" echo vm-support version: $VER
|
|
|
|
addfiles /etc/vmware-tools
|
|
addfiles /var/log/boot*
|
|
addfiles /var/log/secure*
|
|
addfiles /var/log/messages*
|
|
addfiles /var/log/syslog*
|
|
addfiles /var/log/vmware-*
|
|
addfiles /var/run/vmware-*
|
|
addfile /var/log/cloud-init.log
|
|
addfile /var/log/cloud-init-output.log
|
|
addfile /etc/cloud/cloud.cfg
|
|
addfile /etc/default/locale
|
|
addfile /etc/locale.conf
|
|
|
|
runcmd "/tmp/df.txt" df
|
|
collectNetworkDetails
|
|
runcmd "/tmp/mount.txt" mount
|
|
runcmd "/tmp/dmesg.txt" dmesg
|
|
runcmd "/tmp/ulimit-a.txt" ulimit -a
|
|
runcmd "/tmp/uptime.txt" uptime
|
|
runcmd "/tmp/date.txt" date
|
|
runcmd "/tmp/umask.txt" umask
|
|
runcmd "/tmp/locale-current.txt" locale
|
|
runcmd "/tmp/locale-list.txt" locale -a
|
|
|
|
case `uname` in
|
|
Linux)
|
|
stageLinux
|
|
# tar options: 'S' for sparse core files.
|
|
TAR_OPTS=-czSf
|
|
;;
|
|
FreeBSD)
|
|
stageFreeBSD
|
|
TAR_OPTS=-czf
|
|
;;
|
|
SunOS)
|
|
stageSolaris
|
|
TAR_OPTS=-czf
|
|
;;
|
|
esac
|
|
|
|
UpdateState $VMSUPPORT_RUNNING
|
|
|
|
banner "Creating tar archive..."
|
|
# Set umask to make diagnostic information unreadable to other users to avoid
|
|
# possible information leakage.
|
|
(umask 0077 && tar $TAR_OPTS $TARFILE $OUTPUT_DIR)
|
|
if [ $? != 0 ]; then
|
|
banner "The tar process did not successfully complete!" \
|
|
"If tar reports that a file changed while reading, please attempt " \
|
|
"to rerun this script."
|
|
fi
|
|
|
|
# Clean up temporary files
|
|
trap - HUP INT QUIT TERM ABRT; cleanup
|
|
|
|
if [ $transfer -eq 1 ]; then
|
|
banner "Transferring support data to the host..."
|
|
vmware-xferlogs enc $TARFILE 2>/dev/null
|
|
|
|
if [ $? != 0 ]; then
|
|
banner "Could not transfer the support data successfully: either " \
|
|
"vmware-xferlogs binary is not in the path, or you are not " \
|
|
"in a virtual machine."
|
|
fi
|
|
else
|
|
banner "Skipping support data transfer to the host."
|
|
fi
|
|
|
|
UpdateState $VMSUPPORT_ENDING
|
|
banner "Done, support data available in '$TARFILE'."
|