Newer
Older
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
# vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
#
# this handler will save various reports of vital system information.
# by default, all the reports are saved in /var/backups.
# (1) a capture of the debconf package selection states. This file
# can be used to restore the answers to debconf questions for
# packages that you will be installing through (2) below. To
# do this, run: "debconf-set-selections < debconfsel.txt"
#
# (2) a list of all the packages installed and removed.
# this file can be used to restore the state of installed packages
# by running "dpkg --set-selections < dpkg-selections.txt and
# then run "apt-get -u dselect-upgrade". If you have the
# debconf-set-selections file from (1), you should restore those first.
#
# (3) the partition table of all disks.
# this partition table can be used to format another disk of
# the same size. this can be handy if using software raid and
# you have a disk go bad. just replace the disk and partition it
# by running "sfdisk /dev/sdb < partitions.sdb.txt"
# (MAKE SURE YOU PARTITION THE CORRECT DISK!!!)
#
# write to a text file the important things which hwinfo can gleen.
# (5) the Luks header of every Luks block device, if option luksheaders
# is enabled.
# in case you (have to) scramble such a Luks header (for some time),
# and restore it later by running "dd if=luksheader.sda2.bin of=/dev/sda2"
# (MAKE SURE YOU PASS THE CORRECT DEVICE AS of= !!!)
#
# (6) LVM metadata for every detected volume group, if "lvm = yes"
#
if [ -f /etc/debian_version ]
then
os=debian
debug "Debian detected"
osversion="/etc/debian_version"
elif [ -f /etc/redhat-release ]
then
os=redhat
debug "Redhat detected"
osversion="/etc/redhat-release"
else
warning "Unknown OS detected!"
fi
if [ ! -d $parentdir ]; then
mkdir -p $parentdir
fi
if [ $os = "debian" ]
then
getconf packagesfile $parentdir/dpkg-selections.txt
getconf packagemgr `which dpkg`
getconf packagemgroptions ' --get-selections *'
getconf debconfgetselections `which debconf-get-selections`
elif [ $os = "redhat" ]
then
getconf packagesfile $parentdir/rpmpackages.txt
getconf packagemgr `which rpm`
getconf packagemgroptions ' -qa '
getconf SYSREPORT `which sysreport`
getconf sysreport_options ' -norpm '
getconf packagesfile $parentdir/unknownOS.txt
packagemgroptions="${packagemgroptions//__star__/*}"
getconf partitionsfile $parentdir/partitions.__star__.txt
getconf hardwarefile $parentdir/hardware.txt
getconf sysreport yes
getconf sysreportfile $parentdir/sysreport.txt
getconf SFDISK `which sfdisk`
getconf HWINFO `which hwinfo`
getconf sfdisk_options ""
getconf hwinfo_options ""
getconf CRYPTSETUP `which cryptsetup`
getconf DD `which dd`
getconf luksheaders no
getconf luksheadersfile $parentdir/luksheader.__star__.bin
getconf VGS `which vgs`
getconf VGCFGBACKUP `which vgcfgbackup`
getconf lvm no
getconf vsnames all
# If vservers are configured, check that the ones listed in $vsnames are running.
usevserver=no
if [ $vservers_are_available = yes ]; then
if [ "$vsnames" = all ]; then
vsnames="$found_vservers"
fi
if ! vservers_running "$vsnames" ; then
fatal "At least one of the vservers listed in vsnames ($vsnames) is not running."
fi
info "Using vservers '$vsnames'"
## SANITY CHECKS #########################
if [ "$luksheaders" == "yes" ]; then
if [ ! -x "$DD" ]; then
warning "can't find dd, skipping backup of Luks headers."
luksheaders="no"
fi
if [ ! -x "$CRYPTSETUP" ]; then
warning "can't find cryptsetup, skipping backup of Luks headers."
luksheaders="no"
fi
fi
if [ "$lvm" == "yes" ]; then
if [ ! -x "$VGS" ]; then
warning "can't find vgs, skipping backup of LVM metadata"
lvm="no"
fi
if [ ! -x "$VGCFGBACKUP" ]; then
warning "can't find vgcfgbackup, skipping backup of LVM metadata"
lvm="no"
fi
fi
## PACKAGES ##############################
#
# here we grab a list of the packages installed and removed.
#
if [ $usevserver = yes ]; then
info "vserver root directory set to: $VROOTDIR"
for vserver in $vsnames; do
info "examining vserver: $vserver"
# is it running ?
vservers_running $vserver
if [ $? -ne 0 ]; then
warning "The vserver $vserver is not running."
continue
fi
# is $packagemgr available inside $vserver ?
if [ ! -x "${VROOTDIR}/${vserver}${packagemgr}" ]; then
warning "can't find $packagemgr in vserver $vserver, skipping installed packages report."
else
# don't expand * since it can be used in $packagemgroptions
set -o noglob
debug "$VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile"
$VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile || fatal "can not save $packagemgr info to $packagesfile"
set +o noglob
fi
# is $debconfgetselections available inside $vserver ?
found=no
# case #1: it is available on the host, is it available inside $vserver ?
if [ -n "$debconfgetselections" ]; then
[ -x "${VROOTDIR}/${vserver}${debconfgetselections}" ] && found=yes
# case #2: it is not available on the host, is it available inside $vserver ?
else
[ -n "`$VSERVER $vserver exec which debconf-get-selections`" ] && found=yes
fi
if [ "$found" != yes ]; then
warning "can't find debconf-get-selections in vserver $vserver, skipping package selection states. You may want to install the debconf-utils package."
else
debug "$VSERVER $vserver exec $debconfgetselections > $VROOTDIR/$vserver$selectionsfile"

intrigeri
committed
$VSERVER $vserver exec $debconfgetselections > $VROOTDIR/$vserver$selectionsfile || fatal "can not save debconf-get-selections info to $selectionsfile"
unset found
# We want to perform this on the host as well
if [ -z "$packagemgr" -o ! -x "$packagemgr" ]; then
warning "can't find ${packagemgr}, skipping installed packages report."
else
# don't expand * since it can be used in $packagemgroptions
set -o noglob
debug "$packagemgr $packagemgroptions > $packagesfile"
$packagemgr $packagemgroptions > $packagesfile || fatal "can not save $packagemgr info to $packagesfile"
if [ -z "$debconfgetselections" ]; then
warning "can't find debconf-get-selections, skipping package selection states. You might want to install the debconf-utils package."
else
debug "$debconfgetselections > $selectionsfile"
$debconfgetselections > $selectionsfile || fatal "can not save $debconfgetselections info to $selectionsfile"
fi
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
fi
## System report ##############################
#
# here we grab a bunch of system stuff for a report
#
export STATUS
HASHES="#################################################################"
DASHES="-----------------------------------------------------------------"
cat /dev/null > $sysreportfile || fatal "can not write to $sysreportfile"
catiffile () {
echo $HASHES >> $sysreportfile
echo "# $STATUS" >> $sysreportfile
echo $HASHES >> $sysreportfile
if [ -f $1 ]; then
echo "file: $1" >> $sysreportfile
echo $DASHES >> $sysreportfile
cat $1 >> $sysreportfile 2>&1 || info "reading of $1 failed"
fi
if [ -d $1 ]; then
echo "directory: $1" >> $sysreportfile
echo $DASHES >> $sysreportfile
for file in `find $1 -maxdepth 3 -noleaf -type f`
do
catiffile $file
done
fi
echo $DASHES >> $sysreportfile
catifexec () {
if [ -x $1 ]; then
echo $HASHES >> $sysreportfile
echo "# $STATUS" >> $sysreportfile
echo $HASHES >> $sysreportfile
$* >> $sysreportfile 2>&1 || info "executing of $1 failed"
fi
STATUS="Determining $os version:"
catiffile $osversion
STATUS="Determinding your current hostname: "
catifexec "/bin/hostname"
STATUS="Getting the date:"
catifexec "/bin/date"
STATUS="Checking your systems current uptime and load average:"
catifexec "/usr/bin/uptime"
STATUS="Checking available memory:"
catifexec "/usr/bin/free"
STATUS="Checking free disk space:"
catifexec "/bin/df" "-al"
STATUS="Collecting what services run at what run level:"
if [ $os = "redhat" ]; then
catifexec "/sbin/chkconfig" "--list"
STATUS="Collecting information about /etc/rc.d:"
catiffile "/bin/ls /etc/rc.d/rc*.d/"
elif [ $os = "debian" ]; then
for level in 0 1 2 3 4 5 6 S; do
echo "Level: $level" >> $sysreportfile
for f in /etc/rc${level}.d/*; do
# Remove /etc/Knn or Snn from beginning
ff=$(echo $f | @SED@ 's_/etc/rc..d/[KS][0-9][0-9]__')
if [ $f != $ff ]; then
echo $ff >> $sysreportfile
fi
done
echo "" >> $sysreportfile
done
fi
STATUS="Getting bootloader information:"
catifexec "/bin/ls" "-alR /boot"
# This covers sparc, alpha, and intel (respectively)
# updated for grub -mpg
if [ -f /etc/silo.conf ]; then
STATUS="Collecting information about the boot process (silo):"
catiffile "/etc/silo.conf"
fi
if [ -f /etc/milo.conf ]; then
STATUS="Collecting information about the boot process (milo):"
catiffile "/etc/milo.conf"
fi
if [ -f /etc/lilo.conf ]; then
STATUS="Collecting information about the boot process (lilo):"
catiffile "/etc/lilo.conf"
catifexec "/sbin/lilo" "-q"
fi
if [ -d /boot/grub -a -f /boot/grub/grub.conf -a -f /boot/grub/device.map ]; then
STATUS="Collecting information about the boot process (grub.conf):"
catiffile "/boot/grub/grub.conf"
STATUS="Collecting information about the boot process (grub.map):"
catiffile "/boot/grub/device.map"
fi
if [ -f /etc/cluster.conf -o -f /etc/cluster.xml ] ; then
STATUS="Gathering information on cluster setup"
# 2.1 AS
if [ -f /etc/cluster.conf ] ; then
catiffile "/etc/cluster.conf"
fi
# Taroon
if [ -f /etc/cluster.xml ] ; then
catiffile "/etc/cluster.xml"
fi
fi
STATUS="Gathering sysctl information (sysctl -a):"
catiffile "sysctl -a 2>/dev/null"
STATUS="Gathering sysctl information (/etc/sysctl.conf):"
catiffile "/etc/sysctl.conf"
STATUS="Gathering IP information (/sbin/ifconfig):"
catifexec "/sbin/ifconfig" "-a"
STATUS="Gathering additional IP information (/bin/ip addr list):"
catifexec "/bin/ip" "addr list"
STATUS="Checking network routes:"
catifexec "/sbin/route" "-n"
STATUS="Collecting Name Service Switch config information:"
catiffile "/etc/nsswitch.conf"
STATUS="Collecting information about system authentication (pam):"
catiffile "/etc/pam.conf"
catiffile "/etc/pam.d"
echo
echo "Getting information about the kernel."
echo
STATUS="Getting kernel version:"
catifexec "/bin/uname" "-a"
if [ "$hardware" == "yes" ]; then
STATUS="Checking module information:"
catifexec "/sbin/lsmod"
for x in $(/sbin/lsmod | /usr/bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null
) ; do
STATUS="Checking module information $x:"
catifexec "/sbin/modinfo" "$x"
done
fi
STATUS="Gathering information about your filesystems:"
catiffile "/proc/filesystems"
STATUS="Gathering information about your system stat:"
catiffile "/proc/stat"
STATUS="Gathering information about your partitions:"
catiffile "/proc/partitions"

intrigeri
committed
catiffile "/proc/kallsyms"
STATUS="Gathering information about slabinfo:"
catiffile "/proc/slabinfo"
# Added support to cover for the new modules.conf layout in Red Hat 7
STATUS="Collecting information regarding kernel modules"
VER=`uname -r`
catiffile "/lib/modules/$VER/modules.dep"
if [ -f /etc/conf.modules ]; then
STATUS="Collecting information regarding kernel modules (conf.modules)"
catiffile "/etc/conf.modules"
fi
if [ -f /etc/modules.conf ]; then
STATUS="Collecting information regarding kernel modules (modules.conf)"
catiffile "/etc/modules.conf"
fi
if [ -f /etc/modprobe.conf ]; then
STATUS="Collecting information regarding kernel modules (modeprobe.conf)"
catiffile "/etc/modprobe.conf"
fi
# dkms status
if [ -x /usr/sbin/dkms ] ; then
STATUS="Gathering current status of modules, versions and kernels (dkms):"
catifexec "/usr/sbin/dkms" "status"
fi
if [ -f /etc/sysconfig/isdncard ] ; then
STATUS="Gathering information about ISDN:"
catiffile "/etc/sysconfig/isdncard"
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
fi
STATUS="Collecting information from the proc directory:"
catiffile "/proc/pci"
STATUS="Getting kernel command line"
catiffile "/proc/cmdline"
STATUS="Gathering information about your CPU:"
catiffile "/proc/cpuinfo"
STATUS="Gathering information about your Ram:"
catiffile "/proc/meminfo"
STATUS="Gathering information about your ioports:"
catiffile "/proc/ioports"
STATUS="Gathering information about your interrupts:"
catiffile "/proc/interrupts"
STATUS="Gathering information about your scsi devices:"
catiffile "/proc/scsi"
STATUS="Gathering information about your dma:"
catiffile "/proc/dma"
STATUS="Gathering information about your devices (/proc/devices):"
catiffile "/proc/devices"
STATUS="Gathering information about your rtc:"
catiffile "/proc/rtc"
STATUS="Gathering information about your ide drivers:"
catiffile "/proc/ide"
if [ "$hardware" == "yes" ]; then
STATUS="Gathering information about your bus:"
catifexec "/usr/bin/lspci"
catiffile "/proc/bus"
fi
echo
echo "Getting disk and filesystem information."
echo
STATUS="Collecting information from /etc/fstab:"
catiffile "/etc/fstab"
STATUS="Collecting disk partition information:"
catifexec "/sbin/fdisk" "-l"
STATUS="Checking mounted file systems (mount) "
catifexec "/bin/mount"
STATUS="Checking mounted file systems (/proc/mounts)"
catiffile "/proc/mounts"
STATUS="Collecting Software RAID information (/proc/mdstat)"
catiffile "/proc/mdstat"
STATUS="Collecting Software RAID information (/etc/raidtab)"
catiffile "/etc/raidtab"
STATUS="Collecting Software RAID information (/etc/mdadm.conf)"
catiffile "/etc/mdadm.conf"
STATUS="Collecting Software RAID information (/sbin/mdadm -Q)"
if ls /dev/md?* >/dev/null 2>&1; then
catifexec "/sbin/mdadm" "-Q" "--detail" '/dev/md?*'
fi
STATUS="Collecting Automount information (auto.master)"
catiffile "/etc/auto.master"
STATUS="Collecting Automount information (auto.misc)"
catiffile "/etc/auto.misc"
STATUS="Collecting Automount information (auto.net)"
catiffile "/etc/auto.net"
STATUS="Collecting LVM information:"
if [ $os = "redhat" ]; then
catifexec "/usr/sbin/vgdisplay" "-vv"
elif [ $os = "debian" ]; then
catifexec "/sbin/vgdisplay" "-vv"
fi
STATUS="Collecting device-mapper (dm) information:"
catifexec '/sbin/dmsetup' 'info'
STATUS="Collecting SCSI Tape information (/etc/stinit.def)"
catiffile "/etc/stinit.def"
if [ -x /sbin/lsusb ] ; then
STATUS="Collecting USB devices list (lsusb):"
catifexec "/sbin/lsusb"
fi
if [ -x /usr/bin/lshal ] ; then
STATUS="Collecting global devices list (lshal):"
catifexec "/usr/bin/lshal"
fi
STATUS="Gathering information on SELinux setup"
catifexec "/usr/bin/selinuxconfig"
catifexec "/usr/sbin/sestatus"
if [ $os = "redhat" ]; then
catifexec "rpm" "-q -V selinux-policy-targeted"
catifexec "rpm" "-q -V selinux-policy-strict"
fi
if [ $usevserver = yes ]; then
STATUS="Gathering vserver information"
catiffile "/proc/virtual"
fi
if [ ! -x "$SFDISK" ]; then
warning "can't find sfdisk, skipping sfdisk report."
partitions="no"
fi
if [ ! -x "$HWINFO" ]; then
warning "can't find hwinfo, skipping partition report."
partitions="no"
fi
if [ ! -x "$HWINFO" ]; then
warning "can't find hwinfo, skipping hardware report."
hardware="no"
fi
## HARDWARE #############################
#
# here we use hwinfo to dump a table listing all the
# information we can find on the hardware of this machine
fi
touch $hardwarefile
echo -e "\n\n====================== summary ======================\n" >> $hardwarefile
debug "$HWINFO --short --cpu --network --disk --pci >> $hardwarefile"
$HWINFO --short --cpu --network --disk --pci >> $hardwarefile
for flag in cpu network bios pci; do
echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile
$HWINFO --$flag >> $hardwarefile
# here we use sfdisk to dump a listing of all the partitions.
# these files can be used to directly partition a disk of the same size.
if [ "$partitions" == "yes" ]; then
devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1`
if [ "$devices" == "" ]; then
warning "No harddisks found"
fi
for dev in $devices; do
debug "$SFDISK will try to backup partition tables for device $dev"
[ -b $dev ] || continue
label=${dev#/dev/}
label=${label//\//-}
outputfile=${partitionsfile//__star__/$label}
debug "$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null"
$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null
if [ $? -ne 0 ]; then
warning "The partition table for $dev could not be saved."
fi
done
fi
if [ "$dohwinfo" == "yes" ]; then
debug "Using $HWINFO to get all available disk information"
echo -e "\n\n====================== $disk ======================\n" >> $hardwarefile
$HWINFO --disk >> $hardwarefile
fi
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
if [ "$luksheaders" == "yes" ]; then
devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1`
[ -n "$devices" ] || warning "No block device found"
targetdevices=""
for dev in $devices; do
[ -b $dev ] || continue
debug "$CRYPTSETUP isLuks $dev"
$CRYPTSETUP isLuks $dev
[ $? -eq 0 ] && targetdevices="$targetdevices $dev"
done
for dev in $targetdevices; do
label=${dev#/dev/}
label=${label//\//-}
outputfile=${luksheadersfile//__star__/$label}
# the following sizes are expressed in terms of 512-byte sectors
debug "Let us find out the Luks header size for $dev"
debug "$CRYPTSETUP luksDump \"$dev\" | grep '^Payload offset:' | @AWK@ '{print $3}'"
headersize=`$CRYPTSETUP luksDump "$dev" | grep '^Payload offset:' | @AWK@ '{print $3}'`
if [ $? -ne 0 ]; then
warning "Could not compute the size of Luks header, skipping device $dev"
continue
elif [ -z "$headersize" -o -n "`echo \"$headersize\" | sed 's/[0-9]*//g'`" ]; then
warning "The computed size of Luks header is not an integer, skipping device $dev"
continue
fi
debug "Let us backup the Luks header of device $dev"
debug "$DD if=\"${dev}\" of=\"${outputfile}\" bs=512 count=\"${headersize}\""
output=`$DD if="${dev}" of="${outputfile}" bs=512 count="${headersize}" 2>&1`
exit_code=$?
if [ $exit_code -eq 0 ]; then
debug $output
info "The Luks header of $dev was saved to $outputfile."
else
debug $output
fatal "The Luks header of $dev could not be saved."
fi
done
fi
## LVM ####################################
# returns 0 on success, 1 on error, 2 if not tried
# outputs error message if error, reason if not tried
function doLvmBackup () {
local lvmdir="$1"
if [ ! -d "$lvmdir" ]; then
if ! mkdir "$lvmdir"; then
echo "could not create $lvmdir"
return 2
else
info "successfully created $lvmdir"
fi
fi
if [ ! -w "$lvmdir" ]; then
echo "can not write to directory $lvmdir"
return 2
fi
debug "Let's try to gather the list of LVM volume groups"
debug "$VGS --options vg_name --noheadings | @SED@ 's/^[ ]*//' | @SED@ 's/[ ]*$//' | tr '\n' ' '"
vgs=`$VGS --options vg_name --noheadings | @SED@ 's/^[ ]*//' | @SED@ 's/[ ]*$//' | tr '\n' ' '`
debug "Let's try to backup LVM metadata for detected volume groups: $vgs"
for vg in $vgs
do
debug "$VGCFGBACKUP --file \"${lvmdir}\"/\'%s\' $vg"
output=`$VGCFGBACKUP --file "${lvmdir}"/'%s' $vg`
done
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
exit_code=$?
debug $output
case $exit_code in
0)
info "LVM metadata was saved to $lvmdir for volume groups: $vgs"
return 0
;;
*)
echo "LVM metadata could not be saved for at least one of these volume groups: $vgs"
return 1
;;
esac
}
if [ "$lvm" == "yes" ]; then
output=`doLvmBackup "${parentdir}/lvm"`
exit_code=$?
case $exit_code in
0) # success. info message has already been displayed
true
;;
1) # error
fatal "$output"
;;
2) # could not even try
fatal "LVM metadata backup was not tried: $output"
;;
*) # should never happen
fatal "Unhandled error ($exit_code) while trying to backup LVM metadata, please report a bug"
;;
esac
fi