Support numactl to retrieve NUMA information
[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 numactl  && numactl --hardware > numactl
168   exectest x86info  && x86info > x86info 2>x86info.2
169
170 # net stuff
171   exectest ifconfig  && ifconfig -v -a  > ifconfig
172   exectest ip        && ip route show   > ip_route
173   exectest ip        && ip link show    > ip_link
174   exectest route     && route -n        > route
175
176 # software
177   if exectest dpkg ; then
178      dpkg --get-selections   > dpkg_get_selections
179      COLUMNS=300 dpkg --list > dpkg_list
180      COLUMNS=1000 dpkg -l linux-image-$UNAME | grep linux-image-$UNAME | tr -s ' ' > running_kernel
181   fi
182
183 # power management
184   exectest laptop-detect  && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
185   exectest acpi_available && acpi_available && cat /proc/acpi/info > acpi_info
186   exectest acpi && acpi > acpi 2> acpi.error && acpi -v > acpi.version
187   [ -r /proc/apm/ ] && apm > apm
188
189 # kernel stuff
190   if [ -r /proc/config.gz ] ; then
191      zcat /proc/config.gz > kernelconfig
192   else
193      [ -r /boot/config-$UNAME ] && cat /boot/config-$UNAME > kernelconfig
194   fi
195
196 # X stuff
197   if [ -n "${DISPLAY}" ] ; then
198      exectest xviddetect  && xviddetect         > xviddetect
199      exectest xvidtune    && xvidtune -show     > xdivtune
200      exectest xrandr      && xrandr             > xrandr
201      exectest xdpyinfo    && xdpyinfo           > xdpyinfo
202      X -version > x_version 2>&1
203   fi
204
205   for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
206       cp /var/log/$i log_$i 2>/dev/null
207   done
208
209   cp /etc/X11/xorg.conf    xorg.conf    2>/dev/null
210   cp /etc/modules          modules      2>/dev/null
211   cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
212
213 # not available:
214 # sysinfo -class device -level all
215
216 # as root:
217 if [ -n "$NOTROOT" ] ; then
218    echo "not running as root" > root
219 else
220    echo "running as root" > root
221    disk_info
222    exectest sfdisk     && sfdisk -d > sfdisk 2>sfdisk.error
223    exectest ddcprobe   && ddcprobe  > ddcprobe
224    exectest dmidecode  && dmidecode > dmidecode
225
226    exectest dconf && dconf -o dconf
227
228    if [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
229       /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
230    fi
231
232    for disk in $disklist; do
233       exectest smartctl  && echo "smartctl -a /dev/$disk :\n" >> smartctl && smartctl -a /dev/$disk       >> smartctl             && echo "\n\n" >> smartctl
234       exectest hdparm    && echo "hdparm -iv  /dev/$disk :\n" >> hdparm   && hdparm -iv  /dev/$disk       >> hdparm               && echo "\n\n" >> hdparm
235       exectest fdisk     && echo "fdisk -lu   /dev/$disk :\n" >> fdisk    && fdisk -lu   /dev/$disk       >> fdisk 2>>fdisk.error && echo "\n\n" >> fdisk
236       exectest parted    && echo "parted -s   /dev/$disk :\n" >> parted   && parted -s   /dev/$disk print >> parted               && echo "\n\n" >> parted
237       file -s /dev/$disk?* | grep -v ": empty" >> file_disk
238    done
239 fi
240 )
241
242 echo
243
244 cd "${WORKING_DIR}"
245
246 # create tarball
247 if [ -n "$GENERATE_FILE" ] ; then
248   tar jcf "${OUTFILE}" "${OUTDIRNAME}"
249   [ -r "$OUTFILE" ] && echo "$OUTFILE ("$(ls -ahl "$OUTFILE" | awk '{print $5}')") has been generated."
250 fi
251
252 # remove (temporary) output directory if needed, else keep it, as it doubles
253 # as the real output directory.
254 if [ -z "$GENERATE_DIRECTORY" ] ; then
255   rm -r "${OUTDIR}"
256 else
257   [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
258 fi
259
260 exit 0
261
262 ## END OF FILE##################################################################