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
234 exectest efibootmgr && efibootmgr -v > efibootmgr
236 # net stuff, net-tools:
237 exectest ifconfig && ifconfig -v -a > ./ifconfig
238 exectest route && route -n > ./route
240 # net stuff, iproute:
241 exectest ip && ip addrlabel list > ip_addrlabel
242 exectest ip && ip addr show > ip_addr
243 exectest ip && ip link show > ip_link
244 exectest ip && ip maddr show > ip_maddr
245 exectest ip && ip mroute show > ip_mroute
246 exectest ip && ip mrule show > ip_mrule 2>ip_mrule.error
247 exectest ip && ip neigh show > ip_neigh
248 exectest ip && ip netns list > ip_netns
249 exectest ip && ip ntable show > ip_ntable
250 exectest ip && ip route show > ip_route
251 exectest ip && if [ -r /etc/iproute2/rt_tables ] ; then
252 grep -v '^#' /etc/iproute2/rt_tables | while read table _ ; do
253 ip route show table "${table}" > "ip_route_table_${table}"
256 exectest ip && ip rule show > ip_rule
257 exectest ip && ip tunnel show > ip_tunnel
258 exectest ip && ip tuntap show > ip_tuntap
261 if exectest dpkg ; then
262 dpkg --get-selections > dpkg_get_selections
263 COLUMNS=300 dpkg --list > dpkg_list
267 exectest laptop-detect && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
268 if [ -r /proc/acpi/info ] ; then
269 cat /proc/acpi/info > acpi_info
272 if exectest acpi ; then
273 acpi > ./acpi 2>acpi.error
274 acpi --everything > ./acpi.everything 2>./acpi.everything.error
275 acpi -v > ./acpi.version
277 [ -r /proc/apm/ ] && apm > ./apm
279 if exectest mcelog ; then
280 mcelog > ./mcelog 2>./mcelog.error
284 if [ -r /proc/config.gz ] ; then
285 zcat /proc/config.gz > kernelconfig
287 [ -r "/boot/config-${UNAME}" ] && cat "/boot/config-${UNAME}" > kernelconfig
290 exectest dpkg && COLUMNS=1000 dpkg -l "linux-image-${UNAME}" 2>running_kernel.error \
291 | grep "linux-image-${UNAME}" | tr -s ' ' > running_kernel 2>>running_kernel.error
292 dpkg -S "/boot/vmlinuz-$(uname -r)" >> running_kernel 2>>running_kernel.error
295 if [ -n "${DISPLAY}" ] ; then
296 exectest xviddetect && xviddetect > ./xviddetect
297 exectest xvidtune && xvidtune -show > ./xdivtune
298 exectest xrandr && xrandr > ./xrandr
299 exectest xdpyinfo && xdpyinfo > ./xdpyinfo
300 X -version > x_version 2>&1
303 for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
304 cp /var/log/$i log_$i 2>/dev/null
307 if [ -r "$HOME"/.local/share/xorg/Xorg.0.log ] ; then
308 cp "$HOME"/.local/share/xorg/Xorg.0.log user_Xorg.0.log
311 cp /etc/X11/xorg.conf xorg.conf 2>/dev/null
312 cp /etc/modules modules 2>/dev/null
313 cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
316 if [ -n "$NOTROOT" ] ; then
317 echo "not running as root" > root
319 echo "running as root" > root
321 exectest sfdisk && sfdisk -d > ./sfdisk 2>./sfdisk.error
322 exectest dmidecode && dmidecode > ./dmidecode
324 exectest dconf && dconf -o dconf
326 if exectest mcelog ; then
327 mcelog --dmi > mcelog_dmi 2>mcelog_dmi.error
330 if exectest edac-util ; then
331 edac-util > ./edac-util 2>./edac-util.error
332 edac-util --report=full > edac-util_report 2>edac-util_report.error
335 if exectest decode-dimms ; then
336 decode-dimms > ./decode-dimms 2>./decode-dimms.error
337 elif [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
338 /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
341 if exectest acpidump ; then
342 acpidump > ./acpidump 2>./acpidump.error
345 if exectest mokutil ; then
346 mokutil --sb-state > ./mokutil_state 2>./mokutil_state.error
350 exectest qm && qm list > ./qm 2>./qm.error
352 exectest virsh && virsh list >./virsh 2>./virsh.error
354 exectest vzlist && vzlist >./vzlist 2>./vzlist.error
356 exectest vserver-stat && vserver-stat >./vserver-stat 2>./vserver-stat.error
358 exectest mdadm && mdadm --detail /dev/md[0-9]* >> ./mdadm 2>./mdadm.error
361 exectest pvs && pvs > ./pvs 2>./pvs.error
362 exectest vgs && vgs > ./vgs 2>./vgs.error
363 exectest lvs && lvs > ./lvs 2>./lvs.error
364 exectest lvdisplay && lvdisplay > ./lvdisplay 2>./lvdisplay.error
366 exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
367 exectest dmsetup && dmsetup ls --tree > dmsetup_ls_tree 2>dmsetup_ls_tree.error
368 exectest lsblk && lsblk > ./lsblk 2>./lsblk.error
371 if exectest iscsiadm ; then
372 iscsiadm -m session > iscsiadm_session 2>iscsiadm_session.error
373 iscsiadm -m fw > iscsiadm_fw 2>iscsiadm_fw.error
374 iscsiadm -m host > iscsiadm_host 2>iscsiadm_host.error
375 iscsiadm -m iface > iscsiadm_iface 2>iscsiadm_iface.error
376 iscsiadm -m node > iscsiadm_node 2>iscsiadm_node.error
377 iscsiadm -m discovery > iscsiadm_discovery 2>iscsiadm_discovery.error
380 if exectest lsscsi ; then
381 lsscsi > ./lsscsi 2>./lsscsi.error
382 lsscsi -t > ./lsscsi_transport 2>./lsscsi_transport.error
385 for disk in $disklist; do
386 if exectest smartctl ; then
387 echo -e "smartctl -a /dev/${disk}:\n" >> smartctl
388 smartctl -a "/dev/$disk" >> ./smartctl
389 echo -e "\n\n" >> ./smartctl
392 if exectest hdparm ; then
393 echo -e "hdparm -iv /dev/${disk}:\n" >> hdparm
394 hdparm -iv "/dev/$disk" >> ./hdparm 2>> ./hdparm.error
395 echo -e "\n\n" >> hdparm
398 if exectest fdisk ; then
399 echo -e "fdisk -lu /dev/${disk}:\n" >> fdisk
400 fdisk -lu "/dev/$disk" >> ./fdisk 2>> ./fdisk.error
401 echo -e "\n\n" >> fdisk
404 if exectest parted ; then
405 echo -e "parted -s /dev/${disk}:\n" >> parted
406 parted -s "/dev/$disk" print >> ./parted
407 echo -e "\n\n" >> parted
410 if exectest sdparm ; then
411 echo -e "sdparm --all --long /dev/${disk}:\n" >> sdparm
412 sdparm --all --long "/dev/$disk" >> ./sdparm
413 echo -e "\n\n" >> sdparm
416 if exectest sg_inq ; then
417 echo -e "sg_inq /dev/${disk}:\n" >> sg_inq
418 sg_inq "/dev/$disk" >> ./sg_inq 2>> ./sg_inq.error
419 echo -e "\n\n" >> sg_inq
422 file -s "/dev/${disk}"?* | grep -v ": empty" >> file_disk
427 # get rid of empty files
428 for file in *.error ; do
429 test -s "$file" || rm -- "$file"
437 if [ -n "$GENERATE_FILE" ] ; then
438 tar acf "${OUTFILE}" "${OUTDIRNAME}"
439 if ! $_opt_quiet ; then
440 # shellcheck disable=SC2012
441 [ -r "$OUTFILE" ] && echo "$OUTFILE ($(ls -ahl -- "$OUTFILE" | awk '{print $5}')) has been generated."
445 # remove (temporary) output directory if needed, else keep it, as it doubles
446 # as the real output directory.
447 if [ -z "$GENERATE_DIRECTORY" ] ; then
450 if ! $_opt_quiet ; then
451 [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
457 ## END OF FILE##################################################################