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
217 exectest sysdump && sysdump > ./sysdump 2>./sysdump.error
219 exectest cpuid && cpuid > ./cpuid 2>./cpuid.error
221 exectest uptime && uptime > ./uptime 2>./uptime.error
227 exectest discover && discover -v --type-summary --enable-bus all > ./discover 2>./discover.error
228 exectest hwinfo && hwinfo log=hwinfo
229 exectest numactl && numactl --hardware > ./numactl
230 exectest x86info && x86info > ./x86info 2>./x86info.error
231 exectest lscpu && lscpu > ./lscpu
232 exectest lscpu && lscpu -e > ./lscpu_extended
235 exectest efibootmgr && efibootmgr -v > efibootmgr
237 # net stuff, net-tools:
238 exectest ifconfig && ifconfig -v -a > ./ifconfig
239 exectest route && route -n > ./route
241 # net stuff, iproute:
242 exectest ip && ip addrlabel list > ip_addrlabel
243 exectest ip && ip addr show > ip_addr
244 exectest ip && ip link show > ip_link
245 exectest ip && ip maddr show > ip_maddr
246 exectest ip && ip mroute show > ip_mroute
247 exectest ip && ip mrule show > ip_mrule 2>ip_mrule.error
248 exectest ip && ip neigh show > ip_neigh
249 exectest ip && ip netconf > ip_netconf
250 exectest ip && ip netns list > ip_netns
251 exectest ip && ip ntable show > ip_ntable
252 exectest ip && ip route show > ip_route
253 exectest ip && if [ -r /etc/iproute2/rt_tables ] ; then
254 grep -v '^#' /etc/iproute2/rt_tables | while read table _ ; do
255 ip route show table "${table}" > "ip_route_table_${table}"
258 exectest ip && ip rule show > ip_rule
259 exectest ip && ip tunnel show > ip_tunnel
260 exectest ip && ip tuntap show > ip_tuntap
263 if exectest dpkg ; then
264 dpkg --get-selections > dpkg_get_selections
265 COLUMNS=300 dpkg --list > dpkg_list
269 exectest laptop-detect && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
270 if [ -r /proc/acpi/info ] ; then
271 cat /proc/acpi/info > acpi_info
274 if exectest acpi ; then
275 acpi > ./acpi 2>acpi.error
276 acpi --everything > ./acpi.everything 2>./acpi.everything.error
277 acpi -v > ./acpi.version
279 [ -r /proc/apm/ ] && apm > ./apm
281 if exectest mcelog ; then
282 mcelog > ./mcelog 2>./mcelog.error
286 if [ -r /proc/config.gz ] ; then
287 zcat /proc/config.gz > kernelconfig
289 [ -r "/boot/config-${UNAME}" ] && cat "/boot/config-${UNAME}" > kernelconfig
292 exectest dpkg && COLUMNS=1000 dpkg -l "linux-image-${UNAME}" 2>running_kernel.error \
293 | grep "linux-image-${UNAME}" | tr -s ' ' > running_kernel 2>>running_kernel.error
294 dpkg -S "/boot/vmlinuz-$(uname -r)" >> running_kernel 2>>running_kernel.error
297 if [ -n "${DISPLAY}" ] ; then
298 exectest xviddetect && xviddetect > ./xviddetect
299 exectest xvidtune && xvidtune -show > ./xdivtune
300 exectest xrandr && xrandr > ./xrandr
301 exectest xdpyinfo && xdpyinfo > ./xdpyinfo
302 X -version > x_version 2>&1
305 for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
306 cp /var/log/$i log_$i 2>/dev/null
309 if [ -r "$HOME"/.local/share/xorg/Xorg.0.log ] ; then
310 cp "$HOME"/.local/share/xorg/Xorg.0.log user_Xorg.0.log
313 cp /etc/X11/xorg.conf xorg.conf 2>/dev/null
314 cp /etc/modules modules 2>/dev/null
315 cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
318 if [ -n "$NOTROOT" ] ; then
319 echo "not running as root" > root
321 echo "running as root" > root
323 exectest sfdisk && sfdisk -d > ./sfdisk 2>./sfdisk.error
324 exectest dmidecode && dmidecode > ./dmidecode
326 exectest dconf && dconf -o dconf
328 if exectest mcelog ; then
329 mcelog --dmi > mcelog_dmi 2>mcelog_dmi.error
332 if exectest edac-util ; then
333 edac-util > ./edac-util 2>./edac-util.error
334 edac-util --report=full > edac-util_report 2>edac-util_report.error
337 if exectest decode-dimms ; then
338 decode-dimms > ./decode-dimms 2>./decode-dimms.error
339 elif [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
340 /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
343 if exectest acpidump ; then
344 acpidump > ./acpidump 2>./acpidump.error
347 if exectest mokutil ; then
348 mokutil --sb-state > ./mokutil_state 2>./mokutil_state.error
352 exectest qm && qm list > ./qm 2>./qm.error
354 exectest virsh && virsh list >./virsh 2>./virsh.error
356 exectest vzlist && vzlist >./vzlist 2>./vzlist.error
358 exectest vserver-stat && vserver-stat >./vserver-stat 2>./vserver-stat.error
360 exectest mdadm && mdadm --detail /dev/md[0-9]* >> ./mdadm 2>./mdadm.error
363 exectest pvs && pvs > ./pvs 2>./pvs.error
364 exectest vgs && vgs > ./vgs 2>./vgs.error
365 exectest lvs && lvs > ./lvs 2>./lvs.error
366 exectest lvdisplay && lvdisplay > ./lvdisplay 2>./lvdisplay.error
368 exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
369 exectest dmsetup && dmsetup ls --tree > dmsetup_ls_tree 2>dmsetup_ls_tree.error
370 exectest lsblk && lsblk > ./lsblk 2>./lsblk.error
373 if exectest iscsiadm ; then
374 iscsiadm -m session > iscsiadm_session 2>iscsiadm_session.error
375 iscsiadm -m fw > iscsiadm_fw 2>iscsiadm_fw.error
376 iscsiadm -m host > iscsiadm_host 2>iscsiadm_host.error
377 iscsiadm -m iface > iscsiadm_iface 2>iscsiadm_iface.error
378 iscsiadm -m node > iscsiadm_node 2>iscsiadm_node.error
379 iscsiadm -m discovery > iscsiadm_discovery 2>iscsiadm_discovery.error
382 if exectest lsscsi ; then
383 lsscsi > ./lsscsi 2>./lsscsi.error
384 lsscsi -t > ./lsscsi_transport 2>./lsscsi_transport.error
387 for disk in $disklist; do
388 if exectest smartctl ; then
389 echo -e "smartctl -a /dev/${disk}:\n" >> smartctl
390 smartctl -a "/dev/$disk" >> ./smartctl
391 echo -e "\n\n" >> ./smartctl
394 if exectest hdparm ; then
395 echo -e "hdparm -iv /dev/${disk}:\n" >> hdparm
396 hdparm -iv "/dev/$disk" >> ./hdparm 2>> ./hdparm.error
397 echo -e "\n\n" >> hdparm
400 if exectest fdisk ; then
401 echo -e "fdisk -lu /dev/${disk}:\n" >> fdisk
402 fdisk -lu "/dev/$disk" >> ./fdisk 2>> ./fdisk.error
403 echo -e "\n\n" >> fdisk
406 if exectest parted ; then
407 echo -e "parted -s /dev/${disk}:\n" >> parted
408 parted -s "/dev/$disk" print >> ./parted
409 echo -e "\n\n" >> parted
412 if exectest sdparm ; then
413 echo -e "sdparm --all --long /dev/${disk}:\n" >> sdparm
414 sdparm --all --long "/dev/$disk" >> ./sdparm
415 echo -e "\n\n" >> sdparm
418 if exectest sg_inq ; then
419 echo -e "sg_inq /dev/${disk}:\n" >> sg_inq
420 sg_inq "/dev/$disk" >> ./sg_inq 2>> ./sg_inq.error
421 echo -e "\n\n" >> sg_inq
424 file -s "/dev/${disk}"?* | grep -v ": empty" >> file_disk
429 # get rid of empty files
430 for file in *.error ; do
431 test -s "$file" || rm -- "$file"
439 if [ -n "$GENERATE_FILE" ] ; then
440 tar acf "${OUTFILE}" "${OUTDIRNAME}"
441 if ! $_opt_quiet ; then
442 # shellcheck disable=SC2012
443 [ -r "$OUTFILE" ] && echo "$OUTFILE ($(ls -ahl -- "$OUTFILE" | awk '{print $5}')) has been generated."
447 # remove (temporary) output directory if needed, else keep it, as it doubles
448 # as the real output directory.
449 if [ -z "$GENERATE_DIRECTORY" ] ; then
452 if ! $_opt_quiet ; then
453 [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
459 ## END OF FILE##################################################################