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 ; do
202 exectest $i && $i > ./$i
205 if exectest lsusb ; then
207 lsusb -v > ./lsusb_verbose 2>./lsusb_verbose.error
210 swapon -s > ./swapon 2>./swapon.error
213 for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
214 mdstat meminfo modules mtrr pci uptime version ; do
215 [ -r /proc/$i ] && cat /proc/$i > proc_$i
218 if ! $_opt_quiet ; then
219 echo "Starting sysdump..."
220 echo " NOTE: if it seems to be hanging at this stage file a bug report with output of:"
221 echo " lsof -p \$(pgrep -f "\$\(which sysdump\)")"
223 exectest sysdump && sysdump > ./sysdump 2>./sysdump.error
224 if ! $_opt_quiet ; then
225 echo "Execution of sysdump finished."
228 exectest cpuid && cpuid > ./cpuid 2>./cpuid.error
230 exectest uptime && uptime > ./uptime 2>./uptime.error
236 exectest discover && discover -v --type-summary --enable-bus all > ./discover 2>./discover.error
237 exectest hwinfo && hwinfo log=hwinfo
238 exectest numactl && numactl --hardware > ./numactl
239 exectest x86info && x86info > ./x86info 2>./x86info.error
240 exectest lscpu && lscpu > ./lscpu
241 exectest lscpu && lscpu -e > ./lscpu_extended
244 exectest efibootmgr && efibootmgr -v >efibootmgr 2>efibootmgr.error
246 # net stuff, net-tools:
247 exectest ifconfig && ifconfig -v -a > ./ifconfig
248 exectest route && route -n > ./route
250 # net stuff, iproute:
251 exectest ip && ip addrlabel list > ip_addrlabel
252 exectest ip && ip addr show > ip_addr
253 exectest ip && ip link show > ip_link
254 exectest ip && ip maddr show > ip_maddr
255 exectest ip && ip mroute show > ip_mroute
256 exectest ip && ip mrule show > ip_mrule 2>ip_mrule.error
257 exectest ip && ip neigh show > ip_neigh
258 exectest ip && ip netconf > ip_netconf
259 exectest ip && ip netns list > ip_netns
260 exectest ip && ip ntable show > ip_ntable
261 exectest ip && ip route show > ip_route
262 exectest ip && if [ -r /etc/iproute2/rt_tables ] ; then
263 grep -v '^#' /etc/iproute2/rt_tables | while read table _ ; do
264 ip route show table "${table}" > "ip_route_table_${table}" 2> "ip_route_table_${table}".error
267 exectest ip && ip rule show > ip_rule
268 exectest ip && ip tunnel show > ip_tunnel
269 exectest ip && ip tuntap show > ip_tuntap
272 if exectest dpkg ; then
273 dpkg --get-selections > dpkg_get_selections
274 COLUMNS=300 dpkg --list > dpkg_list
278 exectest laptop-detect && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
279 if [ -r /proc/acpi/info ] ; then
280 cat /proc/acpi/info > acpi_info
283 if exectest acpi ; then
284 acpi > ./acpi 2>acpi.error
285 acpi --everything > ./acpi.everything 2>./acpi.everything.error
286 acpi -v > ./acpi.version
288 [ -r /proc/apm/ ] && apm > ./apm
290 if exectest mcelog ; then
291 mcelog > ./mcelog 2>./mcelog.error
295 if [ -r /proc/config.gz ] ; then
296 zcat /proc/config.gz > kernelconfig
298 [ -r "/boot/config-${UNAME}" ] && cat "/boot/config-${UNAME}" > kernelconfig
301 exectest dpkg && COLUMNS=1000 dpkg -l "linux-image-${UNAME}" 2>running_kernel.error \
302 | grep "linux-image-${UNAME}" | tr -s ' ' > running_kernel 2>>running_kernel.error
303 dpkg -S "/boot/vmlinuz-$(uname -r)" >> running_kernel 2>>running_kernel.error
306 if [ -n "${DISPLAY}" ] ; then
307 exectest xviddetect && xviddetect > ./xviddetect
308 exectest xvidtune && xvidtune -show > ./xdivtune
309 exectest xrandr && xrandr > ./xrandr
310 exectest xdpyinfo && xdpyinfo > ./xdpyinfo
311 X -version > x_version 2>&1
314 for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
315 cp /var/log/$i log_$i 2>/dev/null
318 if [ -r "$HOME"/.local/share/xorg/Xorg.0.log ] ; then
319 cp "$HOME"/.local/share/xorg/Xorg.0.log user_Xorg.0.log
322 cp /etc/X11/xorg.conf xorg.conf 2>/dev/null
323 cp /etc/modules modules 2>/dev/null
324 cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
327 if [ -n "$NOTROOT" ] ; then
328 echo "not running as root" > root
330 echo "running as root" > root
333 exectest dmidecode && dmidecode > ./dmidecode
335 if exectest mcelog ; then
336 mcelog --dmi > mcelog_dmi 2>mcelog_dmi.error
339 if exectest edac-util ; then
340 edac-util > ./edac-util 2>./edac-util.error
341 edac-util --report=full > edac-util_report 2>edac-util_report.error
344 if exectest decode-dimms ; then
345 decode-dimms > ./decode-dimms 2>./decode-dimms.error
346 elif [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
347 /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
350 if exectest acpidump ; then
351 acpidump > ./acpidump 2>./acpidump.error
354 if exectest mokutil ; then
355 mokutil --sb-state > ./mokutil_state 2>./mokutil_state.error
359 exectest qm && qm list > ./qm 2>./qm.error
361 exectest virsh && virsh list >./virsh 2>./virsh.error
363 exectest vzlist && vzlist >./vzlist 2>./vzlist.error
365 exectest vserver-stat && vserver-stat >./vserver-stat 2>./vserver-stat.error
367 exectest mdadm && mdadm --detail /dev/md[0-9]* >> ./mdadm 2>./mdadm.error
370 exectest pvs && pvs > ./pvs 2>./pvs.error
371 exectest vgs && vgs > ./vgs 2>./vgs.error
372 exectest lvs && lvs > ./lvs 2>./lvs.error
373 exectest lvdisplay && lvdisplay > ./lvdisplay 2>./lvdisplay.error
375 exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
376 exectest dmsetup && dmsetup ls --tree > dmsetup_ls_tree 2>dmsetup_ls_tree.error
377 exectest lsblk && lsblk > ./lsblk 2>./lsblk.error
380 if exectest iscsiadm ; then
381 iscsiadm -m session > iscsiadm_session 2>iscsiadm_session.error
382 iscsiadm -m fw > iscsiadm_fw 2>iscsiadm_fw.error
383 iscsiadm -m host > iscsiadm_host 2>iscsiadm_host.error
384 iscsiadm -m iface > iscsiadm_iface 2>iscsiadm_iface.error
385 iscsiadm -m node > iscsiadm_node 2>iscsiadm_node.error
386 iscsiadm -m discovery > iscsiadm_discovery 2>iscsiadm_discovery.error
389 if exectest lsscsi ; then
390 lsscsi > ./lsscsi 2>./lsscsi.error
391 lsscsi -t > ./lsscsi_transport 2>./lsscsi_transport.error
394 for disk in $disklist; do
395 if exectest sfdisk && [[ -b "/dev/${disk}" ]] ; then
396 sfdisk -d "/dev/${disk}" > "./sfdisk_${disk}" 2>"./sfdisk_${disk}.error"
399 if exectest smartctl ; then
400 echo -e "smartctl -a /dev/${disk}:\n" >> smartctl
401 smartctl -a "/dev/$disk" >> ./smartctl
402 echo -e "\n\n" >> ./smartctl
405 if exectest hdparm ; then
406 echo -e "hdparm -iv /dev/${disk}:\n" >> hdparm
407 hdparm -iv "/dev/$disk" >> ./hdparm 2>> ./hdparm.error
408 echo -e "\n\n" >> hdparm
411 if exectest fdisk ; then
412 echo -e "fdisk -lu /dev/${disk}:\n" >> fdisk
413 fdisk -lu "/dev/$disk" >> ./fdisk 2>> ./fdisk.error
414 echo -e "\n\n" >> fdisk
417 if exectest parted ; then
418 echo -e "parted -s /dev/${disk}:\n" >> parted
419 parted -s "/dev/$disk" print >> ./parted
420 echo -e "\n\n" >> parted
423 if exectest sdparm ; then
424 echo -e "sdparm --all --long /dev/${disk}:\n" >> sdparm
425 sdparm --all --long "/dev/$disk" >> ./sdparm
426 echo -e "\n\n" >> sdparm
429 if exectest sg_inq ; then
430 echo -e "sg_inq /dev/${disk}:\n" >> sg_inq
431 sg_inq "/dev/$disk" >> ./sg_inq 2>> ./sg_inq.error
432 echo -e "\n\n" >> sg_inq
435 file -s "/dev/${disk}"?* | grep -v ": empty" >> file_disk
440 # get rid of empty files
441 for file in *.error ; do
442 test -s "$file" || rm -- "$file"
450 if [ -n "$GENERATE_FILE" ] ; then
451 tar acf "${OUTFILE}" "${OUTDIRNAME}"
452 if ! $_opt_quiet ; then
453 # shellcheck disable=SC2012
454 [ -r "$OUTFILE" ] && echo "$OUTFILE ($(ls -ahl -- "$OUTFILE" | awk '{print $5}')) has been generated."
458 # remove (temporary) output directory if needed, else keep it, as it doubles
459 # as the real output directory.
460 if [ -z "$GENERATE_DIRECTORY" ] ; then
463 if ! $_opt_quiet ; then
464 [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
470 ## END OF FILE##################################################################