Apply wrap-and-sort on Debian package
[grml-hwinfo.git] / grml-hwinfo
1 #!/bin/bash
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='***UNRELEASED***'
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   swapon -s > swapon 2>swapon.error
153
154 # proc stuff
155   for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
156     mdstat meminfo modules mtrr pci version ; do
157     [ -r /proc/$i ] && cat /proc/$i > proc_$i
158   done
159   exectest sysdump  && sysdump > sysdump 2>sysdump.error
160 # for sysnet in `find /proc/sys/net/*/ -type f | grep -v flush`; do cat $sysnet >> sysnet ; done
161
162 # log
163   dmesg > dmesg.cur
164
165 # hwinfo
166   exectest discover && discover -v --type-summary --enable-bus all > discover 2> discover.2
167   exectest hwinfo   && hwinfo log=hwinfo
168   exectest numactl  && numactl --hardware > numactl
169   exectest x86info  && x86info > x86info 2>x86info.2
170
171 # net stuff
172   exectest ifconfig  && ifconfig -v -a  > ifconfig
173   exectest ip        && ip route show   > ip_route
174   exectest ip        && ip link show    > ip_link
175   exectest route     && route -n        > route
176
177 # software
178   if exectest dpkg ; then
179      dpkg --get-selections   > dpkg_get_selections
180      COLUMNS=300 dpkg --list > dpkg_list
181      COLUMNS=1000 dpkg -l linux-image-$UNAME | grep linux-image-$UNAME | tr -s ' ' > running_kernel
182   fi
183
184 # power management
185   exectest laptop-detect  && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
186   exectest acpi_available && acpi_available && cat /proc/acpi/info > acpi_info
187   exectest acpi && acpi > acpi 2> acpi.error && acpi -v > acpi.version
188   [ -r /proc/apm/ ] && apm > apm
189
190 # kernel stuff
191   if [ -r /proc/config.gz ] ; then
192      zcat /proc/config.gz > kernelconfig
193   else
194      [ -r /boot/config-$UNAME ] && cat /boot/config-$UNAME > kernelconfig
195   fi
196
197 # X stuff
198   if [ -n "${DISPLAY}" ] ; then
199      exectest xviddetect  && xviddetect         > xviddetect
200      exectest xvidtune    && xvidtune -show     > xdivtune
201      exectest xrandr      && xrandr             > xrandr
202      exectest xdpyinfo    && xdpyinfo           > xdpyinfo
203      X -version > x_version 2>&1
204   fi
205
206   for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
207       cp /var/log/$i log_$i 2>/dev/null
208   done
209
210   cp /etc/X11/xorg.conf    xorg.conf    2>/dev/null
211   cp /etc/modules          modules      2>/dev/null
212   cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
213
214 # not available:
215 # sysinfo -class device -level all
216
217 # as root:
218 if [ -n "$NOTROOT" ] ; then
219    echo "not running as root" > root
220 else
221    echo "running as root" > root
222    disk_info
223    exectest sfdisk     && sfdisk -d > sfdisk 2>sfdisk.error
224    exectest ddcprobe   && ddcprobe  > ddcprobe
225    exectest dmidecode  && dmidecode > dmidecode
226
227    exectest dconf && dconf -o dconf
228
229    if [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
230       /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
231    fi
232
233    exectest mdadm && mdadm --detail /dev/md[0-9]* >> mdadm 2>mdadm.error
234
235    # LVM
236    exectest pvs && pvs > pvs 2>pvs.error
237    exectest vgs && vgs > vgs 2>vgs.error
238    exectest lvs && lvs > lvs 2>lvs.error
239    exectest lvdisplay && lvdisplay > lvdisplay 2>lvdisplay.error
240
241    exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
242
243    for disk in $disklist; do
244       exectest smartctl  && echo "smartctl -a /dev/$disk :\n" >> smartctl && smartctl -a /dev/$disk       >> smartctl             && echo "\n\n" >> smartctl
245       exectest hdparm    && echo "hdparm -iv  /dev/$disk :\n" >> hdparm   && hdparm -iv  /dev/$disk       >> hdparm               && echo "\n\n" >> hdparm
246       exectest fdisk     && echo "fdisk -lu   /dev/$disk :\n" >> fdisk    && fdisk -lu   /dev/$disk       >> fdisk 2>>fdisk.error && echo "\n\n" >> fdisk
247       exectest parted    && echo "parted -s   /dev/$disk :\n" >> parted   && parted -s   /dev/$disk print >> parted               && echo "\n\n" >> parted
248       file -s /dev/$disk?* | grep -v ": empty" >> file_disk
249    done
250 fi
251 )
252
253 echo
254
255 cd "${WORKING_DIR}"
256
257 # create tarball
258 if [ -n "$GENERATE_FILE" ] ; then
259   tar jcf "${OUTFILE}" "${OUTDIRNAME}"
260   [ -r "$OUTFILE" ] && echo "$OUTFILE ("$(ls -ahl "$OUTFILE" | awk '{print $5}')") has been generated."
261 fi
262
263 # remove (temporary) output directory if needed, else keep it, as it doubles
264 # as the real output directory.
265 if [ -z "$GENERATE_DIRECTORY" ] ; then
266   rm -r "${OUTDIR}"
267 else
268   [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
269 fi
270
271 exit 0
272
273 ## END OF FILE##################################################################