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 # echo a list of all disks and their size
154 # taken from http://cvs.debian.org/fai/lib/disk-info
156 local isdisk major minor blocks device suffix
157 while read _ _ blocks device _ ; do
160 [ -f "/proc/ide/${device}/media" ] && grep -q cdrom "/proc/ide/${device}/media" && isdisk=0
161 [ "$isdisk" -eq 1 ] && echo "$device $blocks"
166 # print only every second entry; used by disk_info
169 if [ "$i" -eq 0 ]; then
179 # the variable holds a space separated list of devices and their block size
180 device_size=$(grep -E ' cciss/c.d.$| ida/c.d.$| rd/c.d.$| hd.$| sd.$|/disc$' /proc/partitions | diskandsize)
181 # a list of all local disks, without size
182 disklist=$(list_disks "$device_size")
186 cd "${OUTDIR}" || exit 1
188 if ! $_opt_quiet ; then
189 [ -n "$GENERATE_FILE" ] && echo "Output file: $OUTFILE"
190 [ -n "$GENERATE_DIRECTORY" ] && echo "Output directory: $OUTDIR"
192 echo "This might take a few seconds/minutes. Please be patient..."
197 if [ -r /etc/grml_version ] ; then
198 cat /etc/grml_version > grml_version
200 if [ -r /etc/debian_version ] ; then
201 cat /etc/debian_version > debian_version
206 [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi > scsi
207 exectest lspci && lspci -nn > ./lspci
208 cat /proc/partitions > partitions
209 find /proc/ide/ -name geometry -exec grep . {} \; > proc_ide 2>/dev/null
210 df -h > ./df 2>/dev/null
211 for i in free lsmod mount lsdev lspnp lsusb ; do
212 exectest $i && $i > ./$i
214 swapon -s > ./swapon 2>./swapon.error
217 for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
218 mdstat meminfo modules mtrr pci version ; do
219 [ -r /proc/$i ] && cat /proc/$i > proc_$i
221 exectest sysdump && sysdump > ./sysdump 2>./sysdump.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
233 # net stuff, net-tools:
234 exectest ifconfig && ifconfig -v -a > ./ifconfig
235 exectest route && route -n > ./route
237 # net stuff, iproute:
238 exectest ip && ip addrlabel list > ip_addrlabel
239 exectest ip && ip addr show > ip_addr
240 exectest ip && ip link show > ip_link
241 exectest ip && ip maddr show > ip_maddr
242 exectest ip && ip mroute show > ip_mroute
243 exectest ip && ip mrule show > ip_mrule
244 exectest ip && ip neigh show > ip_neigh
245 exectest ip && ip netns list > ip_netns
246 exectest ip && ip ntable show > ip_ntable
247 exectest ip && ip route show > ip_route
248 exectest ip && if [ -r /etc/iproute2/rt_tables ] ; then
249 grep -v '^#' /etc/iproute2/rt_tables | while read table _ ; do
250 ip route show table "${table}" > "ip_route_table_${table}"
253 exectest ip && ip rule show > ip_rule
254 exectest ip && ip tunnel show > ip_tunnel
255 exectest ip && ip tuntap show > ip_tuntap
258 if exectest dpkg ; then
259 dpkg --get-selections > dpkg_get_selections
260 COLUMNS=300 dpkg --list > dpkg_list
264 exectest laptop-detect && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
265 if [ -r /proc/acpi/info ] ; then
266 cat /proc/acpi/info > acpi_info
269 exectest acpi && acpi > ./acpi 2>acpi.error && acpi -v > ./acpi.version
270 [ -r /proc/apm/ ] && apm > ./apm
272 if exectest mcelog ; then
273 mcelog > ./mcelog 2>./mcelog.error
277 if [ -r /proc/config.gz ] ; then
278 zcat /proc/config.gz > kernelconfig
280 [ -r "/boot/config-${UNAME}" ] && cat "/boot/config-${UNAME}" > kernelconfig
283 exectest dpkg && COLUMNS=1000 dpkg -l "linux-image-${UNAME}" 2>running_kernel.error \
284 | grep "linux-image-${UNAME}" | tr -s ' ' > running_kernel 2>>running_kernel.error
285 dpkg -S "/boot/vmlinuz-$(uname -r)" >> running_kernel 2>>running_kernel.error
288 if [ -n "${DISPLAY}" ] ; then
289 exectest xviddetect && xviddetect > ./xviddetect
290 exectest xvidtune && xvidtune -show > ./xdivtune
291 exectest xrandr && xrandr > ./xrandr
292 exectest xdpyinfo && xdpyinfo > ./xdpyinfo
293 X -version > x_version 2>&1
296 for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
297 cp /var/log/$i log_$i 2>/dev/null
300 cp /etc/X11/xorg.conf xorg.conf 2>/dev/null
301 cp /etc/modules modules 2>/dev/null
302 cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
305 if [ -n "$NOTROOT" ] ; then
306 echo "not running as root" > root
308 echo "running as root" > root
310 exectest sfdisk && sfdisk -d > ./sfdisk 2>./sfdisk.error
311 exectest dmidecode && dmidecode > ./dmidecode
313 exectest dconf && dconf -o dconf
315 if exectest mcelog ; then
316 mcelog --dmi > mcelog_dmi 2>mcelog_dmi.error
319 if exectest edac-util ; then
320 edac-util > ./edac-util 2>./edac-util.error
321 edac-util --report=full > edac-util_report 2>edac-util_report.error
324 if exectest decode-dimms ; then
325 decode-dimms > ./decode-dimms 2>./decode-dimms.error
326 elif [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
327 /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
331 exectest qm && qm list > ./qm 2>./qm.error
333 exectest virsh && virsh list >./virsh 2>./virsh.error
335 exectest vzlist && vzlist >./vzlist 2>./vzlist.error
337 exectest vserver-stat && vserver-stat >./vserver-stat 2>./vserver-stat.error
339 exectest mdadm && mdadm --detail /dev/md[0-9]* >> ./mdadm 2>./mdadm.error
342 exectest pvs && pvs > ./pvs 2>./pvs.error
343 exectest vgs && vgs > ./vgs 2>./vgs.error
344 exectest lvs && lvs > ./lvs 2>./lvs.error
345 exectest lvdisplay && lvdisplay > ./lvdisplay 2>./lvdisplay.error
347 exectest dmsetup && dmsetup ls > dmsetup_ls 2>dmsetup_ls.error
348 exectest dmsetup && dmsetup ls --tree > dmsetup_ls_tree 2>dmsetup_ls_tree.error
349 exectest lsblk && lsblk > ./lsblk 2>./lsblk.error
352 if exectest iscsiadm ; then
353 iscsiadm -m session > iscsiadm_session 2>iscsiadm_session.error
354 iscsiadm -m fw > iscsiadm_fw 2>iscsiadm_fw.error
355 iscsiadm -m host > iscsiadm_host 2>iscsiadm_host.error
356 iscsiadm -m iface > iscsiadm_iface 2>iscsiadm_iface.error
357 iscsiadm -m node > iscsiadm_node 2>iscsiadm_node.error
358 iscsiadm -m discovery > iscsiadm_discovery 2>iscsiadm_discovery.error
361 if exectest lsscsi ; then
362 lsscsi > ./lsscsi 2>./lsscsi.error
363 lsscsi -t > ./lsscsi_transport 2>./lsscsi_transport.error
366 for disk in $disklist; do
367 if exectest smartctl ; then
368 echo -e "smartctl -a /dev/${disk}:\n" >> smartctl
369 smartctl -a "/dev/$disk" >> ./smartctl
370 echo -e "\n\n" >> ./smartctl
373 if exectest hdparm ; then
374 echo -e "hdparm -iv /dev/${disk}:\n" >> hdparm
375 hdparm -iv "/dev/$disk" >> ./hdparm
376 echo -e "\n\n" >> hdparm
379 if exectest fdisk ; then
380 echo -e "fdisk -lu /dev/${disk}:\n" >> fdisk
381 fdisk -lu "/dev/$disk" >> ./fdisk 2>> ./fdisk.error
382 echo -e "\n\n" >> fdisk
385 if exectest parted ; then
386 echo -e "parted -s /dev/${disk}:\n" >> parted
387 parted -s "/dev/$disk" print >> ./parted
388 echo -e "\n\n" >> parted
391 if exectest sdparm ; then
392 echo -e "sdparm --all --long /dev/${disk}:\n" >> sdparm
393 sdparm --all --long "/dev/$disk" >> ./sdparm
394 echo -e "\n\n" >> sdparm
397 if exectest sg_inq ; then
398 echo -e "sg_inq /dev/${disk}:\n" >> sg_inq
399 sg_inq "/dev/$disk" >> ./sg_inq
400 echo -e "\n\n" >> sg_inq
403 file -s "/dev/${disk}"?* | grep -v ": empty" >> file_disk
408 # get rid of empty files
409 for file in *.error ; do
410 test -s "$file" || rm -- "$file"
418 if [ -n "$GENERATE_FILE" ] ; then
419 tar acf "${OUTFILE}" "${OUTDIRNAME}"
420 if ! $_opt_quiet ; then
421 # shellcheck disable=SC2012
422 [ -r "$OUTFILE" ] && echo "$OUTFILE ($(ls -ahl -- "$OUTFILE" | awk '{print $5}')) has been generated."
426 # remove (temporary) output directory if needed, else keep it, as it doubles
427 # as the real output directory.
428 if [ -z "$GENERATE_DIRECTORY" ] ; then
431 if ! $_opt_quiet ; then
432 [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
438 ## END OF FILE##################################################################