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 ################################################################################
16 [ -n "$WORKING_DIR" -a -d "$WORKING_DIR" ] || WORKING_DIR=$(pwd)
17 VERSION='***UNRELEASED***'
19 # data collection should not be affected by user locale
23 TIMESTAMP='+%F--%H-%M-%S-%Z'
24 DATE="$(date $TIMESTAMP)"
26 echo "$PN ${VERSION} - collect hardware information"
31 _opt_output_directory=false
32 _opt_output_file=false
36 This tool collects information of the hardware it is being executed on.
37 It can be executed as normal user to collect some basic information or
38 (recommended) with root permissions to collect more system information.
39 If executed without any options a file named grml-hwinfo-TIMESTAMP.tar.bz2
40 storing all collected information is created in the current working directory.
44 -b, --both Create directory + file grml-hwinfo-TIMESTAMP.tar.bz2
45 -d, --directory Create grml-hwinfo-TIMESTAMP as a directory (no file)
46 -f, --file Create grml-hwinfo-TIMESTAMP.tar.bz2 [default action]
47 -h, --help Display this help message
48 --output-directory <dir> Store output files in specified directory
49 --output-file <file> Store output in specified filename (tar.bz2 format)
53 CMDLINE_OPTS=output-directory:,output-file:,both,directory,file,help
54 _opt_temp=$(getopt --name grml-hwinfo -o +bdfh --long $CMDLINE_OPTS -- "$@")
56 echo "Try 'grml-hwinfo --help' for more information." >&2
59 eval set -- "$_opt_temp"
67 shift; OUTDIRNAME="$1"
68 GENERATE_DIRECTORY='1'
69 _opt_output_directory=true
70 $_opt_output_file && GENERATE_FILE='1' || GENERATE_FILE=''
76 $_opt_output_directory && GENERATE_DIRECTORY='1' || GENERATE_DIRECTORY=''
79 GENERATE_DIRECTORY='1'
87 GENERATE_DIRECTORY='1'
94 echo "Internal getopt error!" >&2
101 # Generate output/temporary directory name & path, and output file path
102 [ -n "$OUTDIRNAME" ] || OUTDIRNAME="grml-hwinfo-${DATE}"
103 OUTDIR="${WORKING_DIR}/${OUTDIRNAME}"
104 mkdir "${OUTDIR}" || { echo "Directory '${OUTDIR}' already exists, aborting." >&2 ; exit 1; }
106 if [ -n "$GENERATE_FILE" ] ; then
107 [ -n "$OUTFILE" ] && OUTFILE_="$OUTFILE" || OUTFILE_="${OUTDIR}.tar.bz2"
108 [ -e "${OUTFILE_}" ] && { echo "File '${OUTFILE_}' already exists, aborting." >&2 ; rm -r "${OUTDIR}"; exit 1; }
113 if [ "$(id -u)" != "0" ] ; then
115 echo "W: Running without root permissions. Not all data will be collected."
118 # check whether a binary is available and executable
120 if [ -z "$1" ] ; then
121 echo 'Usage: exectest <binary>'>&2
124 if test -e "$(which "$1")" ; then
127 grep -q "^$1"'$' missing_tools 2>/dev/null || echo "$1" >> missing_tools
133 # echo a list of all disks and their size
134 # taken from http://cvs.debian.org/fai/lib/disk-info
136 local isdisk major minor blocks device suffix
137 while read _ _ blocks device _ ; do
140 [ -f "/proc/ide/${device}/media" ] && grep -q cdrom "/proc/ide/${device}/media" && isdisk=0
141 [ "$isdisk" -eq 1 ] && echo "$device $blocks"
146 # print only every second entry; used by disk_info
149 if [ "$i" -eq 0 ]; then
159 # the variable holds a space separated list of devices and their block size
160 device_size=$(grep -E ' cciss/c.d.$| ida/c.d.$| rd/c.d.$| hd.$| sd.$|/disc$' /proc/partitions | diskandsize)
161 # a list of all local disks, without size
162 disklist=$(list_disks "$device_size")
166 cd "${OUTDIR}" || exit 1
168 [ -n "$GENERATE_FILE" ] && echo "Output file: $OUTFILE"
169 [ -n "$GENERATE_DIRECTORY" ] && echo "Output directory: $OUTDIR"
171 echo "This might take a few seconds/minutes. Please be patient..."
175 if [ -r /etc/grml_version ] ; then
176 cat /etc/grml_version > grml_version
178 if [ -r /etc/debian_version ] ; then
179 cat /etc/debian_version > debian_version
184 [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi > scsi
185 exectest lspci && lspci -nn > ./lspci
186 cat /proc/partitions > partitions
187 find /proc/ide/ -name geometry -exec grep . {} \; > proc_ide 2>/dev/null
188 df -h > ./df 2>/dev/null
189 for i in free lsmod mount lsdev lspnp lsusb ; do
190 exectest $i && $i > ./$i
192 swapon -s > ./swapon 2>./swapon.error
195 for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
196 mdstat meminfo modules mtrr pci version ; do
197 [ -r /proc/$i ] && cat /proc/$i > proc_$i
199 exectest sysdump && sysdump > ./sysdump 2>./sysdump.error
205 exectest discover && discover -v --type-summary --enable-bus all > ./discover 2>./discover.2
206 exectest hwinfo && hwinfo log=hwinfo
207 exectest numactl && numactl --hardware > ./numactl
208 exectest x86info && x86info > ./x86info 2>./x86info.2
209 exectest lscpu && lscpu > ./lscpu
211 # net stuff, net-tools:
212 exectest ifconfig && ifconfig -v -a > ./ifconfig
213 exectest route && route -n > ./route
215 # net stuff, iproute:
216 exectest ip && ip addrlabel list > ip_addrlabel
217 exectest ip && ip addr show > ip_addr
218 exectest ip && ip link show > ip_link
219 exectest ip && ip maddr show > ip_maddr
220 exectest ip && ip mroute show > ip_mroute
221 exectest ip && ip mrule show > ip_mrule
222 exectest ip && ip neigh show > ip_neigh
223 exectest ip && ip netns list > ip_netns
224 exectest ip && ip ntable show > ip_ntable
225 exectest ip && ip route show > ip_route
226 exectest ip && if [ -r /etc/iproute2/rt_tables ] ; then
227 grep -v '^#' /etc/iproute2/rt_tables | while read table _ ; do
228 ip route show table "${table}" > "ip_route_table_${table}"
231 exectest ip && ip rule show > ip_rule
232 exectest ip && ip tunnel show > ip_tunnel
233 exectest ip && ip tuntap show > ip_tuntap
236 if exectest dpkg ; then
237 dpkg --get-selections > dpkg_get_selections
238 COLUMNS=300 dpkg --list > dpkg_list
242 exectest laptop-detect && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
243 if [ -r /proc/acpi/info ] ; then
244 cat /proc/acpi/info > acpi_info
247 exectest acpi && acpi > ./acpi 2>acpi.error && acpi -v > ./acpi.version
248 [ -r /proc/apm/ ] && apm > ./apm
250 if exectest mcelog ; then
251 mcelog > ./mcelog 2>./mcelog.error
255 if [ -r /proc/config.gz ] ; then
256 zcat /proc/config.gz > kernelconfig
258 [ -r "/boot/config-${UNAME}" ] && cat "/boot/config-${UNAME}" > kernelconfig
261 exectest dpkg && COLUMNS=1000 dpkg -l "linux-image-${UNAME}" 2>running_kernel.error \
262 | grep "linux-image-${UNAME}" | tr -s ' ' > running_kernel 2>>running_kernel.error
263 dpkg -S "/boot/vmlinuz-$(uname -r)" >> running_kernel 2>>running_kernel.error
266 if [ -n "${DISPLAY}" ] ; then
267 exectest xviddetect && xviddetect > ./xviddetect
268 exectest xvidtune && xvidtune -show > ./xdivtune
269 exectest xrandr && xrandr > ./xrandr
270 exectest xdpyinfo && xdpyinfo > ./xdpyinfo
271 X -version > x_version 2>&1
274 for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
275 cp /var/log/$i log_$i 2>/dev/null
278 cp /etc/X11/xorg.conf xorg.conf 2>/dev/null
279 cp /etc/modules modules 2>/dev/null
280 cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
283 if [ -n "$NOTROOT" ] ; then
284 echo "not running as root" > root
286 echo "running as root" > root
288 exectest sfdisk && sfdisk -d > ./sfdisk 2>./sfdisk.error
289 exectest dmidecode && dmidecode > ./dmidecode
291 exectest dconf && dconf -o dconf
293 if exectest mcelog ; then
294 mcelog --dmi > mcelog_dmi 2>mcelog_dmi.error
297 if exectest edac-util ; then
298 edac-util > ./edac-util 2>./edac-util.error
299 edac-util --report=full > edac-util_report 2>edac-util_report.error
302 if exectest decode-dimms ; then
303 decode-dimms > ./decode-dimms 2>./decode-dimms.error
304 elif [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
305 /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
309 exectest qm && qm list > ./qm 2>./qm.error
311 exectest virsh && virsh list >./virsh 2>./virsh.error
313 exectest vzlist && vzlist >./vzlist 2>./vzlist.error
315 exectest vserver-stat && vserver-stat >./vserver-stat 2>./vserver-stat.error
317 exectest mdadm && mdadm --detail /dev/md[0-9]* >> ./mdadm 2>./mdadm.error
320 exectest pvs && pvs > ./pvs 2>./pvs.error
321 exectest vgs && vgs > ./vgs 2>./vgs.error
322 exectest lvs && lvs > ./lvs 2>./lvs.error
323 exectest lvdisplay && lvdisplay > ./lvdisplay 2>./lvdisplay.error
325 exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
326 exectest dmsetup && dmsetup ls --tree > dmsetup_ls_tree 2>dmsetup_ls_tree.error
327 exectest lsblk && lsblk > ./lsblk 2>./lsblk.error
330 if exectest iscsiadm ; then
331 iscsiadm -m session > iscsiadm_session 2>iscsiadm_session.error
332 iscsiadm -m fw > iscsiadm_fw 2>iscsiadm_fw.error
333 iscsiadm -m host > iscsiadm_host 2>iscsiadm_host.error
334 iscsiadm -m iface > iscsiadm_iface 2>iscsiadm_iface.error
335 iscsiadm -m node > iscsiadm_node 2>iscsiadm_node.error
336 iscsiadm -m discovery > iscsiadm_discovery 2>iscsiadm_discovery.error
339 if exectest lsscsi ; then
340 lsscsi > ./lsscsi 2>./lsscsi.error
341 lsscsi -t > ./lsscsi_transport 2>./lsscsi_transport.error
344 for disk in $disklist; do
345 if exectest smartctl ; then
346 echo -e "smartctl -a /dev/${disk}:\n" >> smartctl
347 smartctl -a "/dev/$disk" >> ./smartctl
348 echo -e "\n\n" >> ./smartctl
351 if exectest hdparm ; then
352 echo -e "hdparm -iv /dev/${disk}:\n" >> hdparm
353 hdparm -iv "/dev/$disk" >> ./hdparm
354 echo -e "\n\n" >> hdparm
357 if exectest fdisk ; then
358 echo -e "fdisk -lu /dev/${disk}:\n" >> fdisk
359 fdisk -lu "/dev/$disk" >> ./fdisk 2>> ./fdisk.error
360 echo -e "\n\n" >> fdisk
363 if exectest parted ; then
364 echo -e "parted -s /dev/${disk}:\n" >> parted
365 parted -s "/dev/$disk" print >> ./parted
366 echo -e "\n\n" >> parted
369 if exectest sdparm ; then
370 echo -e "sdparm --all --long /dev/${disk}:\n" >> sdparm
371 sdparm --all --long "/dev/$disk" >> ./sdparm
372 echo -e "\n\n" >> sdparm
375 if exectest sg_inq ; then
376 echo -e "sg_inq /dev/${disk}:\n" >> sg_inq
377 sg_inq "/dev/$disk" >> ./sg_inq
378 echo -e "\n\n" >> sg_inq
381 file -s "/dev/${disk}"?* | grep -v ": empty" >> file_disk
386 # get rid of empty files
387 for file in *.error ; do
388 test -s "$file" || rm -- "$file"
396 if [ -n "$GENERATE_FILE" ] ; then
397 tar acf "${OUTFILE}" "${OUTDIRNAME}"
398 # shellcheck disable=SC2012
399 [ -r "$OUTFILE" ] && echo "$OUTFILE ($(ls -ahl -- "$OUTFILE" | awk '{print $5}')) has been generated."
402 # remove (temporary) output directory if needed, else keep it, as it doubles
403 # as the real output directory.
404 if [ -z "$GENERATE_DIRECTORY" ] ; then
407 [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
412 ## END OF FILE##################################################################