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)"
29 _opt_output_directory=false
30 _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 -q, --quiet Don't display informational text (useful for cron usage)
49 --force Don't abort but overwrite possibly existing output file
50 --output-directory <dir> Store output files in specified directory
51 --output-file <file> Store output in specified filename (tar.XX format)
55 CMDLINE_OPTS=output-directory:,output-file:,both,directory,file,help,quiet,force
56 _opt_temp=$(getopt --name grml-hwinfo -o +bdfhq --long $CMDLINE_OPTS -- "$@")
58 echo "Try 'grml-hwinfo --help' for more information." >&2
61 eval set -- "$_opt_temp"
69 shift; OUTDIRNAME="$1"
70 GENERATE_DIRECTORY='1'
71 _opt_output_directory=true
72 $_opt_output_file && GENERATE_FILE='1' || GENERATE_FILE=''
78 $_opt_output_directory && GENERATE_DIRECTORY='1' || GENERATE_DIRECTORY=''
81 GENERATE_DIRECTORY='1'
89 GENERATE_DIRECTORY='1'
102 echo "Internal getopt error!" >&2
109 if ! $_opt_quiet ; then
110 echo "$PN ${VERSION} - collect hardware information"
113 # Generate output/temporary directory name & path, and output file path
114 [ -n "$OUTDIRNAME" ] || OUTDIRNAME="grml-hwinfo-${DATE}"
115 if $_opt_output_directory ; then
116 OUTDIR="${OUTDIRNAME}"
118 OUTDIR="${WORKING_DIR}/${OUTDIRNAME}"
121 if $_opt_force ; then
124 mkdir "${OUTDIR}" || { echo "Directory '${OUTDIR}' already exists, aborting." >&2 ; exit 1; }
127 if [ -n "$GENERATE_FILE" ] ; then
128 [ -n "$OUTFILE" ] && OUTFILE_="$OUTFILE" || OUTFILE_="${OUTDIR}.tar.bz2"
129 if ! $_opt_force ; then
130 [ -e "${OUTFILE_}" ] && { echo "File '${OUTFILE_}' already exists, aborting." >&2 ; rm -r "${OUTDIR}"; exit 1; }
136 if [ "$(id -u)" != "0" ] ; then
138 $_opt_quiet || echo "W: Running without root permissions. Not all data will be collected."
141 # check whether a binary is available and executable
143 if [ -z "$1" ] ; then
144 echo 'Usage: exectest <binary>'>&2
147 if test -e "$(which "$1")" ; then
150 if ! grep -q "^$1"'$' missing_tools 2>/dev/null ; then
151 $_opt_quiet || echo "$1" >> missing_tools
158 # based on https://github.com/faiproject/fai/blob/master/lib/fai-disk-info
161 while read _ _ _ device _ ; do
164 [ "$(stat -c %G /dev/"${device}")" = "disk" ] || isdisk=0
165 [ "$isdisk" -eq 1 ] && echo "$device"
170 # the variable holds a newline separated list of devices
171 disklist=$(egrep ' etherd/e[[:digit:]]+\.[[:digit:]]+\b| i2o/hd.+\b| cciss/c.+d.+\b| ida/c.+d.+\b| rd/c.+d.+\b| fio.\b| hd.\b| sd[a-z]{1,2}\b|/disc\b| vd.\b| xvd.\b' /proc/partitions | checkdisk)
175 cd "${OUTDIR}" || exit 1
177 if ! $_opt_quiet ; then
178 [ -n "$GENERATE_FILE" ] && echo "Output file: $OUTFILE"
179 [ -n "$GENERATE_DIRECTORY" ] && echo "Output directory: $OUTDIR"
181 echo "This might take a few seconds/minutes. Please be patient..."
186 if [ -r /etc/grml_version ] ; then
187 cat /etc/grml_version > grml_version
189 if [ -r /etc/debian_version ] ; then
190 cat /etc/debian_version > debian_version
195 [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi > scsi
196 exectest lspci && lspci -nn > ./lspci
197 exectest lspci && lspci -vvnn > ./lspci_verbose
198 cat /proc/partitions > partitions
199 find /proc/ide/ -name geometry -exec grep . {} \; > proc_ide 2>/dev/null
200 df -h > ./df 2>/dev/null
201 for i in free lsmod mount lsdev lspnp lsusb ; do
202 exectest $i && $i > ./$i
204 swapon -s > ./swapon 2>./swapon.error
207 for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
208 mdstat meminfo modules mtrr pci version ; do
209 [ -r /proc/$i ] && cat /proc/$i > proc_$i
211 exectest sysdump && sysdump > ./sysdump 2>./sysdump.error
217 exectest discover && discover -v --type-summary --enable-bus all > ./discover 2>./discover.error
218 exectest hwinfo && hwinfo log=hwinfo
219 exectest numactl && numactl --hardware > ./numactl
220 exectest x86info && x86info > ./x86info 2>./x86info.error
221 exectest lscpu && lscpu > ./lscpu
224 exectest efibootmgr && efibootmgr -v > efibootmgr
226 # net stuff, net-tools:
227 exectest ifconfig && ifconfig -v -a > ./ifconfig
228 exectest route && route -n > ./route
230 # net stuff, iproute:
231 exectest ip && ip addrlabel list > ip_addrlabel
232 exectest ip && ip addr show > ip_addr
233 exectest ip && ip link show > ip_link
234 exectest ip && ip maddr show > ip_maddr
235 exectest ip && ip mroute show > ip_mroute
236 exectest ip && ip mrule show > ip_mrule 2>ip_mrule.error
237 exectest ip && ip neigh show > ip_neigh
238 exectest ip && ip netns list > ip_netns
239 exectest ip && ip ntable show > ip_ntable
240 exectest ip && ip route show > ip_route
241 exectest ip && if [ -r /etc/iproute2/rt_tables ] ; then
242 grep -v '^#' /etc/iproute2/rt_tables | while read table _ ; do
243 ip route show table "${table}" > "ip_route_table_${table}"
246 exectest ip && ip rule show > ip_rule
247 exectest ip && ip tunnel show > ip_tunnel
248 exectest ip && ip tuntap show > ip_tuntap
251 if exectest dpkg ; then
252 dpkg --get-selections > dpkg_get_selections
253 COLUMNS=300 dpkg --list > dpkg_list
257 exectest laptop-detect && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
258 if [ -r /proc/acpi/info ] ; then
259 cat /proc/acpi/info > acpi_info
262 if exectest acpi ; then
263 acpi > ./acpi 2>acpi.error
264 acpi --everything > ./acpi.everything 2>./acpi.everything.error
265 acpi -v > ./acpi.version
267 [ -r /proc/apm/ ] && apm > ./apm
269 if exectest mcelog ; then
270 mcelog > ./mcelog 2>./mcelog.error
274 if [ -r /proc/config.gz ] ; then
275 zcat /proc/config.gz > kernelconfig
277 [ -r "/boot/config-${UNAME}" ] && cat "/boot/config-${UNAME}" > kernelconfig
280 exectest dpkg && COLUMNS=1000 dpkg -l "linux-image-${UNAME}" 2>running_kernel.error \
281 | grep "linux-image-${UNAME}" | tr -s ' ' > running_kernel 2>>running_kernel.error
282 dpkg -S "/boot/vmlinuz-$(uname -r)" >> running_kernel 2>>running_kernel.error
285 if [ -n "${DISPLAY}" ] ; then
286 exectest xviddetect && xviddetect > ./xviddetect
287 exectest xvidtune && xvidtune -show > ./xdivtune
288 exectest xrandr && xrandr > ./xrandr
289 exectest xdpyinfo && xdpyinfo > ./xdpyinfo
290 X -version > x_version 2>&1
293 for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
294 cp /var/log/$i log_$i 2>/dev/null
297 cp /etc/X11/xorg.conf xorg.conf 2>/dev/null
298 cp /etc/modules modules 2>/dev/null
299 cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
302 if [ -n "$NOTROOT" ] ; then
303 echo "not running as root" > root
305 echo "running as root" > root
307 exectest sfdisk && sfdisk -d > ./sfdisk 2>./sfdisk.error
308 exectest dmidecode && dmidecode > ./dmidecode
310 exectest dconf && dconf -o dconf
312 if exectest mcelog ; then
313 mcelog --dmi > mcelog_dmi 2>mcelog_dmi.error
316 if exectest edac-util ; then
317 edac-util > ./edac-util 2>./edac-util.error
318 edac-util --report=full > edac-util_report 2>edac-util_report.error
321 if exectest decode-dimms ; then
322 decode-dimms > ./decode-dimms 2>./decode-dimms.error
323 elif [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
324 /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
327 if exectest acpidump ; then
328 acpidump > ./acpidump 2>./acpidump.error
332 exectest qm && qm list > ./qm 2>./qm.error
334 exectest virsh && virsh list >./virsh 2>./virsh.error
336 exectest vzlist && vzlist >./vzlist 2>./vzlist.error
338 exectest vserver-stat && vserver-stat >./vserver-stat 2>./vserver-stat.error
340 exectest mdadm && mdadm --detail /dev/md[0-9]* >> ./mdadm 2>./mdadm.error
343 exectest pvs && pvs > ./pvs 2>./pvs.error
344 exectest vgs && vgs > ./vgs 2>./vgs.error
345 exectest lvs && lvs > ./lvs 2>./lvs.error
346 exectest lvdisplay && lvdisplay > ./lvdisplay 2>./lvdisplay.error
348 exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
349 exectest dmsetup && dmsetup ls --tree > dmsetup_ls_tree 2>dmsetup_ls_tree.error
350 exectest lsblk && lsblk > ./lsblk 2>./lsblk.error
353 if exectest iscsiadm ; then
354 iscsiadm -m session > iscsiadm_session 2>iscsiadm_session.error
355 iscsiadm -m fw > iscsiadm_fw 2>iscsiadm_fw.error
356 iscsiadm -m host > iscsiadm_host 2>iscsiadm_host.error
357 iscsiadm -m iface > iscsiadm_iface 2>iscsiadm_iface.error
358 iscsiadm -m node > iscsiadm_node 2>iscsiadm_node.error
359 iscsiadm -m discovery > iscsiadm_discovery 2>iscsiadm_discovery.error
362 if exectest lsscsi ; then
363 lsscsi > ./lsscsi 2>./lsscsi.error
364 lsscsi -t > ./lsscsi_transport 2>./lsscsi_transport.error
367 for disk in $disklist; do
368 if exectest smartctl ; then
369 echo -e "smartctl -a /dev/${disk}:\n" >> smartctl
370 smartctl -a "/dev/$disk" >> ./smartctl
371 echo -e "\n\n" >> ./smartctl
374 if exectest hdparm ; then
375 echo -e "hdparm -iv /dev/${disk}:\n" >> hdparm
376 hdparm -iv "/dev/$disk" >> ./hdparm 2>> ./hdparm.error
377 echo -e "\n\n" >> hdparm
380 if exectest fdisk ; then
381 echo -e "fdisk -lu /dev/${disk}:\n" >> fdisk
382 fdisk -lu "/dev/$disk" >> ./fdisk 2>> ./fdisk.error
383 echo -e "\n\n" >> fdisk
386 if exectest parted ; then
387 echo -e "parted -s /dev/${disk}:\n" >> parted
388 parted -s "/dev/$disk" print >> ./parted
389 echo -e "\n\n" >> parted
392 if exectest sdparm ; then
393 echo -e "sdparm --all --long /dev/${disk}:\n" >> sdparm
394 sdparm --all --long "/dev/$disk" >> ./sdparm
395 echo -e "\n\n" >> sdparm
398 if exectest sg_inq ; then
399 echo -e "sg_inq /dev/${disk}:\n" >> sg_inq
400 sg_inq "/dev/$disk" >> ./sg_inq 2>> ./sg_inq.error
401 echo -e "\n\n" >> sg_inq
404 file -s "/dev/${disk}"?* | grep -v ": empty" >> file_disk
409 # get rid of empty files
410 for file in *.error ; do
411 test -s "$file" || rm -- "$file"
419 if [ -n "$GENERATE_FILE" ] ; then
420 tar acf "${OUTFILE}" "${OUTDIRNAME}"
421 if ! $_opt_quiet ; then
422 # shellcheck disable=SC2012
423 [ -r "$OUTFILE" ] && echo "$OUTFILE ($(ls -ahl -- "$OUTFILE" | awk '{print $5}')) has been generated."
427 # remove (temporary) output directory if needed, else keep it, as it doubles
428 # as the real output directory.
429 if [ -z "$GENERATE_DIRECTORY" ] ; then
432 if ! $_opt_quiet ; then
433 [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
439 ## END OF FILE##################################################################