1#!/bin/bash 2# We use some bash-isms (getopts?) 3 4# Copyright (C) 2007 Red Hat, Inc. All rights reserved. 5# 6# This file is part of LVM2. 7# 8# This copyrighted material is made available to anyone wishing to use, 9# modify, copy, or redistribute it subject to the terms and conditions 10# of the GNU General Public License v.2. 11# 12# You should have received a copy of the GNU General Public License 13# along with this program; if not, write to the Free Software Foundation, 14# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 16# lvm_dump: This script is used to collect pertinent information for 17# the debugging of lvm issues. 18 19# following external commands are used throughout the script 20# echo and test are internal in bash at least 21MKDIR=mkdir # need -p 22TAR=tar # need czf 23RM=rm # need -rf 24CP=cp 25TAIL=tail # we need -n 26LS=ls # need -la 27PS=ps # need alx 28SED=sed 29DD=dd 30CUT=cut 31DATE=date 32BASENAME=basename 33UNAME=uname 34 35# user may override lvm and dmsetup location by setting LVM_BINARY 36# and DMSETUP_BINARY respectively 37LVM=${LVM_BINARY-lvm} 38DMSETUP=${DMSETUP_BINARY-dmsetup} 39 40die() { 41 code=$1; shift 42 echo "$@" 1>&2 43 exit $code 44} 45 46"$LVM" version >& /dev/null || die 2 "Could not run lvm binary '$LVM'" 47"$DMSETUP" version >& /dev/null || DMSETUP=: 48 49function usage { 50 echo "$0 [options]" 51 echo " -h print this message" 52 echo " -a advanced collection - warning: if lvm is already hung," 53 echo " then this script may hang as well if -a is used" 54 echo " -m gather LVM metadata from the PVs" 55 echo " -d <directory> dump into a directory instead of tarball" 56 echo " -c if running clvmd, gather cluster data as well" 57 echo "" 58 59 exit 1 60} 61 62advanced=0 63clustered=0 64metadata=0 65while getopts :acd:hm opt; do 66 case $opt in 67 s) sysreport=1 ;; 68 a) advanced=1 ;; 69 c) clustered=1 ;; 70 d) userdir=$OPTARG ;; 71 h) usage ;; 72 m) metadata=1 ;; 73 :) echo "$0: $OPTARG requires a value:"; usage ;; 74 \?) echo "$0: unknown option $OPTARG"; usage ;; 75 *) usage ;; 76 esac 77done 78 79NOW=`$DATE -u +%G%m%d%k%M%S | /usr/bin/tr -d ' '` 80if test -n "$userdir"; then 81 dir="$userdir" 82else 83 dirbase="lvmdump-$HOSTNAME-$NOW" 84 dir="$HOME/$dirbase" 85fi 86 87test -e $dir && die 3 "Fatal: $dir already exists" 88$MKDIR -p $dir || die 4 "Fatal: could not create $dir" 89 90log="$dir/lvmdump.log" 91 92myecho() { 93 echo "$@" 94 echo "$@" >> "$log" 95} 96 97log() { 98 echo "$@" >> "$log" 99 eval "$@" 100} 101 102warnings() { 103 if test "$UID" != "0" && test "$EUID" != "0"; then 104 myecho "WARNING! Running as non-privileged user, dump is likely incomplete!" 105 elif test "$DMSETUP" = ":"; then 106 myecho "WARNING! Could not run dmsetup, dump is likely incomplete." 107 fi 108} 109 110warnings 111 112myecho "Creating dump directory: $dir" 113echo " " 114 115if (( $advanced )); then 116 myecho "Gathering LVM volume info..." 117 118 myecho " vgscan..." 119 log "\"$LVM\" vgscan -vvvv > \"$dir/vgscan\" 2>&1" 120 121 myecho " pvscan..." 122 log "\"$LVM\" pvscan -v >> \"$dir/pvscan\" 2>> \"$log\"" 123 124 myecho " lvs..." 125 log "\"$LVM\" lvs -a -o +devices >> \"$dir/lvs\" 2>> \"$log\"" 126 127 myecho " pvs..." 128 log "\"$LVM\" pvs -a -v > \"$dir/pvs\" 2>> \"$log\"" 129 130 myecho " vgs..." 131 log "\"$LVM\" vgs -v > \"$dir/vgs\" 2>> \"$log\"" 132fi 133 134if (( $clustered )); then 135 myecho "Gathering cluster info..." 136 137 { 138 for i in nodes status services; do 139 cap_i=$(echo $i|tr a-z A-Z) 140 printf "$cap_i:\n----------------------------------\n" 141 log "cman_tool $i 2>> \"$log\"" 142 echo 143 done 144 145 echo "LOCKS:" 146 echo "----------------------------------" 147 if [ -f /proc/cluster/dlm_locks ] 148 then 149 echo clvmd > /proc/cluster/dlm_locks 150 cat /proc/cluster/dlm_locks 151 echo 152 echo "RESOURCE DIR:" 153 cat /proc/cluster/dlm_dir 154 echo 155 echo "DEBUG LOG:" 156 cat /proc/cluster/dlm_debug 157 echo 158 fi 159 if [ -f /debug/dlm/clvmd ] 160 then 161 cat /debug/dlm/clvmd 162 echo 163 echo "WAITERS:" 164 cat /debug/dlm/clvmd_waiters 165 echo 166 echo "MASTER:" 167 cat /debug/dlm/clvmd_master 168 fi 169 } > $dir/cluster_info 170fi 171 172myecho "Gathering LVM & device-mapper version info..." 173echo "LVM VERSION:" > "$dir/versions" 174"$LVM" lvs --version >> "$dir/versions" 2>> "$log" 175echo "DEVICE MAPPER VERSION:" >> "$dir/versions" 176"$DMSETUP" --version >> "$dir/versions" 2>> "$log" 177echo "KERNEL VERSION:" >> "$dir/versions" 178"$UNAME" -a >> "$dir/versions" 2>> "$log" 179echo "DM TARGETS VERSIONS:" >> "$dir/versions" 180"$DMSETUP" targets >> "$dir/versions" 2>> "$log" 181 182myecho "Gathering dmsetup info..." 183log "\"$DMSETUP\" info -c > \"$dir/dmsetup_info\" 2>> \"$log\"" 184log "\"$DMSETUP\" table > \"$dir/dmsetup_table\" 2>> \"$log\"" 185log "\"$DMSETUP\" status > \"$dir/dmsetup_status\" 2>> \"$log\"" 186 187myecho "Gathering process info..." 188log "$PS alx > \"$dir/ps_info\" 2>> \"$log\"" 189 190myecho "Gathering console messages..." 191log "$TAIL -n 75 /var/log/messages > \"$dir/messages\" 2>> \"$log\"" 192 193myecho "Gathering /etc/lvm info..." 194log "$CP -a /etc/lvm \"$dir/lvm\" 2>> \"$log\"" 195 196myecho "Gathering /dev listing..." 197log "$LS -laR /dev > \"$dir/dev_listing\" 2>> \"$log\"" 198 199myecho "Gathering /sys/block listing..." 200log "$LS -laR /sys/block > \"$dir/sysblock_listing\" 2>> \"$log\"" 201log "$LS -laR /sys/devices/virtual/block >> \"$dir/sysblock_listing\" 2>> \"$log\"" 202 203if (( $metadata )); then 204 myecho "Gathering LVM metadata from Physical Volumes..." 205 206 log "$MKDIR -p \"$dir/metadata\"" 207 208 pvs="$("$LVM" pvs --separator , --noheadings --units s --nosuffix -o \ 209 name,pe_start 2>> "$log" | $SED -e 's/^ *//')" 210 for line in $pvs 211 do 212 test -z "$line" && continue 213 pv="$(echo $line | $CUT -d, -f1)" 214 pe_start="$(echo $line | $CUT -d, -f2)" 215 name="$($BASENAME "$pv")" 216 myecho " $pv" 217 log "$DD if=$pv \"of=$dir/metadata/$name\" bs=512 count=$pe_start 2>> \"$log\"" 218 done 219fi 220 221if test -z "$userdir"; then 222 lvm_dump="$dirbase.tgz" 223 myecho "Creating report tarball in $HOME/$lvm_dump..." 224fi 225 226warnings 227 228if test -z "$userdir"; then 229 cd "$HOME" 230 "$TAR" czf "$lvm_dump" "$dirbase" 2>/dev/null 231 "$RM" -rf "$dir" 232fi 233 234exit 0 235 236