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 OUTDIR="${WORKING_DIR}/${OUTDIRNAME}"
116 if $_opt_force ; then
119 mkdir "${OUTDIR}" || { echo "Directory '${OUTDIR}' already exists, aborting." >&2 ; exit 1; }
122 if [ -n "$GENERATE_FILE" ] ; then
123 [ -n "$OUTFILE" ] && OUTFILE_="$OUTFILE" || OUTFILE_="${OUTDIR}.tar.bz2"
124 if ! $_opt_force ; then
125 [ -e "${OUTFILE_}" ] && { echo "File '${OUTFILE_}' already exists, aborting." >&2 ; rm -r "${OUTDIR}"; exit 1; }
131 if [ "$(id -u)" != "0" ] ; then
133 $_opt_quiet || echo "W: Running without root permissions. Not all data will be collected."
136 # check whether a binary is available and executable
138 if [ -z "$1" ] ; then
139 echo 'Usage: exectest <binary>'>&2
142 if test -e "$(which "$1")" ; then
145 if ! grep -q "^$1"'$' missing_tools 2>/dev/null ; then
146 $_opt_quiet || echo "$1" >> missing_tools
153 # based on https://github.com/faiproject/fai/blob/master/lib/fai-disk-info
156 while read _ _ _ device _ ; do
159 [ "$(stat -c %G /dev/"${device}")" = "disk" ] || isdisk=0
160 [ "$isdisk" -eq 1 ] && echo "$device"
165 # the variable holds a newline separated list of devices
166 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)
170 cd "${OUTDIR}" || exit 1
172 if ! $_opt_quiet ; then
173 [ -n "$GENERATE_FILE" ] && echo "Output file: $OUTFILE"
174 [ -n "$GENERATE_DIRECTORY" ] && echo "Output directory: $OUTDIR"
176 echo "This might take a few seconds/minutes. Please be patient..."
181 if [ -r /etc/grml_version ] ; then
182 cat /etc/grml_version > grml_version
184 if [ -r /etc/debian_version ] ; then
185 cat /etc/debian_version > debian_version
190 [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi > scsi
191 exectest lspci && lspci -nn > ./lspci
192 cat /proc/partitions > partitions
193 find /proc/ide/ -name geometry -exec grep . {} \; > proc_ide 2>/dev/null
194 df -h > ./df 2>/dev/null
195 for i in free lsmod mount lsdev lspnp lsusb ; do
196 exectest $i && $i > ./$i
198 swapon -s > ./swapon 2>./swapon.error
201 for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
202 mdstat meminfo modules mtrr pci version ; do
203 [ -r /proc/$i ] && cat /proc/$i > proc_$i
205 exectest sysdump && sysdump > ./sysdump 2>./sysdump.error
211 exectest discover && discover -v --type-summary --enable-bus all > ./discover 2>./discover.error
212 exectest hwinfo && hwinfo log=hwinfo
213 exectest numactl && numactl --hardware > ./numactl
214 exectest x86info && x86info > ./x86info 2>./x86info.error
215 exectest lscpu && lscpu > ./lscpu
217 # net stuff, net-tools:
218 exectest ifconfig && ifconfig -v -a > ./ifconfig
219 exectest route && route -n > ./route
221 # net stuff, iproute:
222 exectest ip && ip addrlabel list > ip_addrlabel
223 exectest ip && ip addr show > ip_addr
224 exectest ip && ip link show > ip_link
225 exectest ip && ip maddr show > ip_maddr
226 exectest ip && ip mroute show > ip_mroute
227 exectest ip && ip mrule show > ip_mrule
228 exectest ip && ip neigh show > ip_neigh
229 exectest ip && ip netns list > ip_netns
230 exectest ip && ip ntable show > ip_ntable
231 exectest ip && ip route show > ip_route
232 exectest ip && if [ -r /etc/iproute2/rt_tables ] ; then
233 grep -v '^#' /etc/iproute2/rt_tables | while read table _ ; do
234 ip route show table "${table}" > "ip_route_table_${table}"
237 exectest ip && ip rule show > ip_rule
238 exectest ip && ip tunnel show > ip_tunnel
239 exectest ip && ip tuntap show > ip_tuntap
242 if exectest dpkg ; then
243 dpkg --get-selections > dpkg_get_selections
244 COLUMNS=300 dpkg --list > dpkg_list
248 exectest laptop-detect && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
249 if [ -r /proc/acpi/info ] ; then
250 cat /proc/acpi/info > acpi_info
253 exectest acpi && acpi > ./acpi 2>acpi.error && acpi -v > ./acpi.version
254 [ -r /proc/apm/ ] && apm > ./apm
256 if exectest mcelog ; then
257 mcelog > ./mcelog 2>./mcelog.error
261 if [ -r /proc/config.gz ] ; then
262 zcat /proc/config.gz > kernelconfig
264 [ -r "/boot/config-${UNAME}" ] && cat "/boot/config-${UNAME}" > kernelconfig
267 exectest dpkg && COLUMNS=1000 dpkg -l "linux-image-${UNAME}" 2>running_kernel.error \
268 | grep "linux-image-${UNAME}" | tr -s ' ' > running_kernel 2>>running_kernel.error
269 dpkg -S "/boot/vmlinuz-$(uname -r)" >> running_kernel 2>>running_kernel.error
272 if [ -n "${DISPLAY}" ] ; then
273 exectest xviddetect && xviddetect > ./xviddetect
274 exectest xvidtune && xvidtune -show > ./xdivtune
275 exectest xrandr && xrandr > ./xrandr
276 exectest xdpyinfo && xdpyinfo > ./xdpyinfo
277 X -version > x_version 2>&1
280 for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
281 cp /var/log/$i log_$i 2>/dev/null
284 cp /etc/X11/xorg.conf xorg.conf 2>/dev/null
285 cp /etc/modules modules 2>/dev/null
286 cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
289 if [ -n "$NOTROOT" ] ; then
290 echo "not running as root" > root
292 echo "running as root" > root
294 exectest sfdisk && sfdisk -d > ./sfdisk 2>./sfdisk.error
295 exectest dmidecode && dmidecode > ./dmidecode
297 exectest dconf && dconf -o dconf
299 if exectest mcelog ; then
300 mcelog --dmi > mcelog_dmi 2>mcelog_dmi.error
303 if exectest edac-util ; then
304 edac-util > ./edac-util 2>./edac-util.error
305 edac-util --report=full > edac-util_report 2>edac-util_report.error
308 if exectest decode-dimms ; then
309 decode-dimms > ./decode-dimms 2>./decode-dimms.error
310 elif [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
311 /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
315 exectest qm && qm list > ./qm 2>./qm.error
317 exectest virsh && virsh list >./virsh 2>./virsh.error
319 exectest vzlist && vzlist >./vzlist 2>./vzlist.error
321 exectest vserver-stat && vserver-stat >./vserver-stat 2>./vserver-stat.error
323 exectest mdadm && mdadm --detail /dev/md[0-9]* >> ./mdadm 2>./mdadm.error
326 exectest pvs && pvs > ./pvs 2>./pvs.error
327 exectest vgs && vgs > ./vgs 2>./vgs.error
328 exectest lvs && lvs > ./lvs 2>./lvs.error
329 exectest lvdisplay && lvdisplay > ./lvdisplay 2>./lvdisplay.error
331 exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
332 exectest dmsetup && dmsetup ls --tree > dmsetup_ls_tree 2>dmsetup_ls_tree.error
333 exectest lsblk && lsblk > ./lsblk 2>./lsblk.error
336 if exectest iscsiadm ; then
337 iscsiadm -m session > iscsiadm_session 2>iscsiadm_session.error
338 iscsiadm -m fw > iscsiadm_fw 2>iscsiadm_fw.error
339 iscsiadm -m host > iscsiadm_host 2>iscsiadm_host.error
340 iscsiadm -m iface > iscsiadm_iface 2>iscsiadm_iface.error
341 iscsiadm -m node > iscsiadm_node 2>iscsiadm_node.error
342 iscsiadm -m discovery > iscsiadm_discovery 2>iscsiadm_discovery.error
345 if exectest lsscsi ; then
346 lsscsi > ./lsscsi 2>./lsscsi.error
347 lsscsi -t > ./lsscsi_transport 2>./lsscsi_transport.error
350 for disk in $disklist; do
351 if exectest smartctl ; then
352 echo -e "smartctl -a /dev/${disk}:\n" >> smartctl
353 smartctl -a "/dev/$disk" >> ./smartctl
354 echo -e "\n\n" >> ./smartctl
357 if exectest hdparm ; then
358 echo -e "hdparm -iv /dev/${disk}:\n" >> hdparm
359 hdparm -iv "/dev/$disk" >> ./hdparm
360 echo -e "\n\n" >> hdparm
363 if exectest fdisk ; then
364 echo -e "fdisk -lu /dev/${disk}:\n" >> fdisk
365 fdisk -lu "/dev/$disk" >> ./fdisk 2>> ./fdisk.error
366 echo -e "\n\n" >> fdisk
369 if exectest parted ; then
370 echo -e "parted -s /dev/${disk}:\n" >> parted
371 parted -s "/dev/$disk" print >> ./parted
372 echo -e "\n\n" >> parted
375 if exectest sdparm ; then
376 echo -e "sdparm --all --long /dev/${disk}:\n" >> sdparm
377 sdparm --all --long "/dev/$disk" >> ./sdparm
378 echo -e "\n\n" >> sdparm
381 if exectest sg_inq ; then
382 echo -e "sg_inq /dev/${disk}:\n" >> sg_inq
383 sg_inq "/dev/$disk" >> ./sg_inq
384 echo -e "\n\n" >> sg_inq
387 file -s "/dev/${disk}"?* | grep -v ": empty" >> file_disk
392 # get rid of empty files
393 for file in *.error ; do
394 test -s "$file" || rm -- "$file"
402 if [ -n "$GENERATE_FILE" ] ; then
403 tar acf "${OUTFILE}" "${OUTDIRNAME}"
404 if ! $_opt_quiet ; then
405 # shellcheck disable=SC2012
406 [ -r "$OUTFILE" ] && echo "$OUTFILE ($(ls -ahl -- "$OUTFILE" | awk '{print $5}')) has been generated."
410 # remove (temporary) output directory if needed, else keep it, as it doubles
411 # as the real output directory.
412 if [ -z "$GENERATE_DIRECTORY" ] ; then
415 if ! $_opt_quiet ; then
416 [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
422 ## END OF FILE##################################################################