Release new version 0.4.2.
[grml-hwinfo.git] / grml-hwinfo
1 #!/bin/sh
2 # Filename:      grml-hwinfo
3 # Purpose:       get hardware information
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8 # Notice: Some ideas have been taken from
9 # http://club.black.co.at/david/hwdb/infodump
10 # by David Schmitt <david@schmitt.edv-bus.at>
11 ################################################################################
12
13 # variables
14 UNAME="$(uname -r)"
15 PN="$(basename $0)"
16 [ -n "$WORKING_DIR" -a -d "$WORKING_DIR" ] || WORKING_DIR=$(pwd)
17 VERSION='0.4.1'
18
19 # data collection should not be affected by user locale
20 export LANG=C
21 export LC_ALL=C
22
23 TIMESTAMP='+%F--%H-%M-%S-%Z'
24 DATE="$(date $TIMESTAMP)"
25
26 echo "$PN ${VERSION} - collect hardware information"
27
28 GENERATE_FILE='1'
29 GENERATE_DIRECTORY=''
30
31 while getopts "hdf" args; do
32   case "$args" in
33   h) echo "
34 This tool collects information of the hardware this tool is being executed
35 on.  It can be executed as normal user to collect some basic information or
36 with root permissions to collect as much information as possible.  By
37 default, a file named grml-hwinfo-TIMESTAMP.tar.bz2 storing all collected
38 information will be created in the current working directory. Alternatively,
39 you can have it create a directory with all information.
40
41 Options:
42
43   -h    Display this help message
44   -f    Create grml-hwinfo-TIMESTAMP.tar.bz2
45   -d    Create grml-hwinfo-TIMESTAMP as a directory
46   -df   Create both, the directory and the file
47 "
48
49   exit 0;;
50
51   d)
52   GENERATE_FILE=''
53   GENERATE_DIRECTORY='1'
54   ;;
55
56   f) # generating file; default behaviour
57   GENERATE_FILE='1'
58   ;;
59
60   esac
61   done
62
63 # Generate output/temporary directory name & path, and output file path
64 OUTFILE=""
65 OUTDIRNAME="grml-hwinfo-${DATE}"
66 OUTDIR="${WORKING_DIR}/${OUTDIRNAME}"
67 mkdir "${OUTDIR}" || { echo 'Directory "'${OUTDIR}'" already exists, aborting.'>&2 ; exit 1; }
68
69 if [ -n "$GENERATE_FILE" ] ; then
70    OUTFILE_="${OUTDIR}.tar.bz2"
71    [ -e "${OUTFILE_}" ] && { echo 'File "'${OUTFILE_}'" already exists, aborting.'>&2 ; rm -r "${OUTDIR}"; exit 1; }
72    OUTFILE=${OUTFILE_}
73    touch "${OUTFILE}"
74 fi
75
76 if [ "$(id -u)" != "0" ] ; then
77    NOTROOT=1
78    echo "W: Running without root permissions. Not all data will be collected."
79 fi
80
81 # check whether a binary is available and executable
82 exectest() {
83 if [ -z "$1" ] ; then
84    echo 'Usage: exectest <binary>'>&2
85    return 1
86 else
87    test -e "$(which $1)" && return 0 || return 1
88 fi
89 }
90
91 # echo a list of all disks and their size
92 # taken from http://cvs.debian.org/fai/lib/disk-info
93 diskandsize() {
94     local isdisk major minor blocks device suffix
95     while read major minor blocks device suffix; do
96         isdisk=1
97         # skip ide cdrom
98         [ -f /proc/ide/$device/media ] && grep -q cdrom /proc/ide/$device/media && isdisk=0
99         [ "$isdisk" -eq 1 ] && echo "$device $blocks"
100     done
101 }
102
103 list_disks() {
104 # print only every second entry; used by disk_info
105 i=0
106 for ent in $@; do
107     if [ "$i" -eq 0 ]; then
108         echo $ent
109         i=1
110     else
111         i=0
112     fi
113 done
114 }
115
116 disk_info() {
117     # the variable holds a space separated list of devices and their block size
118     device_size=`grep -E ' cciss/c.d.$| ida/c.d.$| rd/c.d.$| hd.$| sd.$|/disc$' /proc/partitions | diskandsize`
119     # a list of all local disks, without size
120     disklist=`list_disks $device_size`
121 }
122
123
124 cd "${OUTDIR}" || exit 1
125 (
126   [ -n "$GENERATE_FILE" ]      && echo "Output file:      $OUTFILE"
127   [ -n "$GENERATE_DIRECTORY" ] && echo "Output directory: $OUTDIR"
128   echo
129   echo "This might take a few seconds/minutes. Please be patient..."
130
131 # some sysinfo
132   date > date
133   if [ -r /etc/grml_version ] ; then
134      cat /etc/grml_version > grml_version
135   fi
136   if [ -r /etc/debian_version ] ; then
137      cat /etc/debian_version > debian_version
138   fi
139   uname -a > uname
140
141 # disks / devices
142   [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi > scsi
143   (lspci; lspci -n) | sort > lspci
144   [ -r /proc/bus/pnp ] && lspnp > lspnp
145   [ -r /proc/bus/usb ] && lsusb > lsusb
146   cat /proc/partitions > partitions
147   find /proc/ide/ -name geometry -exec grep . {} \; > proc_ide 2>/dev/null
148   df -h > df 2>/dev/null
149   for i in free lsmod mount lsdev ; do
150       exectest $i  && $i > $i
151   done
152
153 # proc stuff
154   for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
155     mdstat meminfo modules mtrr pci version ; do
156     [ -r /proc/$i ] && cat /proc/$i > proc_$i
157   done
158   exectest sysdump  && sysdump > sysdump 2>sysdump.error
159 # for sysnet in `find /proc/sys/net/*/ -type f | grep -v flush`; do cat $sysnet >> sysnet ; done
160
161 # log
162   dmesg > dmesg.cur
163
164 # hwinfo
165   exectest discover && discover -v --type-summary --enable-bus all > discover 2> discover.2
166   exectest hwinfo   && hwinfo log=hwinfo
167   exectest x86info  && x86info > x86info 2>x86info.2
168
169 # net stuff
170   exectest ifconfig  && ifconfig -v -a  > ifconfig
171   exectest ip        && ip route show   > ip_route
172   exectest ip        && ip link show    > ip_link
173   exectest route     && route -n        > route
174
175 # software
176   if exectest dpkg ; then
177      dpkg --get-selections   > dpkg_get_selections
178      COLUMNS=300 dpkg --list > dpkg_list
179      COLUMNS=1000 dpkg -l linux-image-$UNAME | grep linux-image-$UNAME | tr -s ' ' > running_kernel
180   fi
181
182 # power management
183   exectest laptop-detect  && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
184   exectest acpi_available && acpi_available && cat /proc/acpi/info > acpi_info
185   exectest acpi && acpi > acpi 2> acpi.error && acpi -v > acpi.version
186   [ -r /proc/apm/ ] && apm > apm
187
188 # kernel stuff
189   if [ -r /proc/config.gz ] ; then
190      zcat /proc/config.gz > kernelconfig
191   else
192      [ -r /boot/config-$UNAME ] && cat /boot/config-$UNAME > kernelconfig
193   fi
194
195 # X stuff
196   if [ -n "${DISPLAY}" ] ; then
197      exectest xviddetect  && xviddetect         > xviddetect
198      exectest xvidtune    && xvidtune -show     > xdivtune
199      exectest xrandr      && xrandr             > xrandr
200      exectest xdpyinfo    && xdpyinfo           > xdpyinfo
201      X -version > x_version 2>&1
202   fi
203
204   for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
205       cp /var/log/$i log_$i 2>/dev/null
206   done
207
208   cp /etc/X11/xorg.conf    xorg.conf    2>/dev/null
209   cp /etc/modules          modules      2>/dev/null
210   cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
211
212 # not available:
213 # sysinfo -class device -level all
214
215 # as root:
216 if [ -n "$NOTROOT" ] ; then
217    echo "not running as root" > root
218 else
219    echo "running as root" > root
220    disk_info
221    exectest sfdisk     && sfdisk -d > sfdisk 2>sfdisk.error
222    exectest ddcprobe   && ddcprobe  > ddcprobe
223    exectest dmidecode  && dmidecode > dmidecode
224
225    exectest dconf && dconf -o dconf
226
227    if [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
228       /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
229    fi
230
231    for disk in $disklist; do
232       exectest smartctl  && echo "smartctl -a /dev/$disk :\n" >> smartctl && smartctl -a /dev/$disk       >> smartctl             && echo "\n\n" >> smartctl
233       exectest hdparm    && echo "hdparm -iv  /dev/$disk :\n" >> hdparm   && hdparm -iv  /dev/$disk       >> hdparm               && echo "\n\n" >> hdparm
234       exectest fdisk     && echo "fdisk -lu   /dev/$disk :\n" >> fdisk    && fdisk -lu   /dev/$disk       >> fdisk 2>>fdisk.error && echo "\n\n" >> fdisk
235       exectest parted    && echo "parted -s   /dev/$disk :\n" >> parted   && parted -s   /dev/$disk print >> parted               && echo "\n\n" >> parted
236       file -s /dev/$disk?* | grep -v ": empty" >> file_disk
237    done
238 fi
239 )
240
241 echo
242
243 cd "${WORKING_DIR}"
244
245 # create tarball
246 if [ -n "$GENERATE_FILE" ] ; then
247   tar jcf "${OUTFILE}" "${OUTDIRNAME}"
248   [ -r "$OUTFILE" ] && echo "$OUTFILE ("$(ls -ahl "$OUTFILE" | awk '{print $5}')") has been generated."
249 fi
250
251 # remove (temporary) output directory if needed, else keep it, as it doubles
252 # as the real output directory.
253 if [ -z "$GENERATE_DIRECTORY" ] ; then
254   rm -r "${OUTDIR}"
255 else
256   [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
257 fi
258
259 exit 0
260
261 ## END OF FILE##################################################################