#!/bin/sh -e # ***** BEGIN LICENSE BLOCK ***** # * Copyright (C) 2007 Alexey Gladkov # * # * This program is free software; you can redistribute it and/or modify # * it under the terms of the GNU General Public License as published by # * the Free Software Foundation; either version 2 of the License, or # * (at your option) any later version. # * # * This program is distributed in the hope that it will be useful, # * but WITHOUT ANY WARRANTY; without even the implied warranty of # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # * GNU General Public License for more details. # * # * You should have received a copy of the GNU General Public License # * along with this program; if not, write to the Free Software # * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # ***** END LICENSE BLOCK ***** WITHOUT_RC_COMPAT=1 . /etc/init.d/functions . shell-error . shell-args cwd="$PWD" outfile= begin_msg() { [ -z "$quiet" ] || return 0 [ -z "$*" ] || printf '%s ' "$*" } end_msg() { [ -z "$quiet" ] || return 0 if [ "$BOOTUP" = color ]; then local rc=$1 case "$rc" in 17) echo_passed ;; 0) echo_success ;; *) echo_failure ;; esac ||: fi echo } show_help() { local rc="${1:-0}" cat <; -q, --quiet Try to be more quiet; -v, --verbose Print a message for each action; -V, --version Print program version and exit; -h, --help Show this message. EOF exit "$rc" } timestamp() { printf '# ' > "$1" date >> "$1" 2>&1 } workdir= exit_handler() { local rc=$? trap - EXIT [ ! -d "$workdir" ] || rm -rf -- "$workdir" exit $rc } ################ ### Information ################ # Information about udev events in the system export no_save_udevtrigger= save_udevtrigger_msg='Obtaining kernel devices events' save_udevtrigger() { [ -z "$no_save_udevtrigger" ] || return 0 local r='sysreport.udevtrigger' timestamp "$r" printf "# 'udevtrigger --dry-run --verbose' output\n\n" >> "$r" udevtrigger --dry-run --verbose >>"$r" 2>&1 || return } # Information about modules and device modaliases module_sysinfo() { local path="$1" module= params= module="${path##*/}" if [ -d "$path/parameters" ]; then for p in "$path/parameters"/*; do [ "$p" != "$path/parameters/*" ] || break params="$params ${p##*/}=$(cat "$p")" done fi printf "%s\t%s\n" "$module" "$params" } modalias_info() { local path="$1" p real_path if [ ! -e "$path/driver" ]; then printf "\t\n" return fi if ! real_path="$(readlink -ev "$path/driver/module" 2>/dev/null)"; then printf "\t\n" return fi module_sysinfo "$real_path" } export no_save_modalias= save_modalias_msg='Obtaining modalias' save_modalias() { [ -z "$no_save_modalias" ] || return 0 local p r='sysreport.modalias' timestamp "$r" printf "# Format: \n\n" >> "$r" udevtrigger --dry-run --verbose | while read p; do if [ -f "/sys/$p/modalias" ]; then modalias="$(cat "/sys/$p/modalias")" info="$(modalias_info "/sys/$p")" printf "%s\t%s\n" "$modalias" "$info" fi done >> "$r" } # Information about kernel modules and params via /sys export no_save_modules= save_modules_msg='Obtaining kernel modules and params via /sys' save_modules() { [ -z "$no_save_modules" ] || return 0 local r='sysreport.kmodules' timestamp "$r" printf '# Format: \n\n' >> "$r" local path= for path in /sys/module/*; do [ "$path" != "/sys/module/*" ] || break module_sysinfo "$path" done >> "$r" } # List all PCI devices export no_save_lspci= save_lspci_msg='Obtaining PCI device list' save_lspci() { [ -z "$no_save_lspci" ] || return 0 local r='sysreport.lspci' timestamp "$r" printf "# 'lspci -vvnn' output\n\n" >> "$r" lspci -vvnn >>"$r" 2>&1 || return } # Modules in the Linux Kernel export no_save_lsmod= save_lsmod_msg='Obtaining kernel modules list' save_lsmod() { [ -z "$no_no_save_lspci" ] || return 0 local r='sysreport.lsmod' timestamp "$r" printf "# 'lsmod' output\n\n" >> "$r" lsmod >>"$r" 2>&1 || return } # Information from the kernel ring buffer export no_save_dmesg= save_dmesg_msg='Obtaining kernel ring buffer' save_dmesg() { [ -z "$no_save_dmesg" ] || return 0 local r='sysreport.dmesg' timestamp "$r" printf "# 'dmesg' output\n\n" >> "$r" dmesg >>"$r" 2>&1 || return } export no_save_commoninfo= save_commoninfo_msg='Obtaining system information' save_commoninfo() { [ -z "$no_save_commoninfo" ] || return 0 local r='sysreport.systeminfo' timestamp "$r" printf "# 'uname -a'\n" >> "$r" uname -a >>"$r" 2>&1 || return for f in /proc/cmdline /proc/meminfo /proc/cpuinfo /proc/filesystems /proc/mdstat do printf "\n# 'cat %s'\n" "$f" >> "$r" cat "$f" 2>&1 >> "$r" || return done printf \\n >> "$r" } # EVMS information export no_save_evmsinfo= save_evmsinfo_msg='Obtaining EVMS information' save_evmsinfo() { [ -z "$no_save_evmsinfo" ] || return 0 [ -x /sbin/evms_activate ] || return 17 local r='sysreport.evmsplugins' timestamp "$r" evms_activate >> "$r" 2>&1 || return printf "# 'evms_query plugins -i' output\n\n" >> "$r" evms_query plugins -i >> "$r" 2>&1 || return r='sysreport.evms' timestamp "$r" printf "# 'evms_query info' output\n\n" >> "$r" evms_query info >> "$r" 2>&1 || return printf "\n# 'evms_query disks' output\n" >> "$r" evms_query disks 2>&1 >> "$r" || return local d for d in `evms_query disks`; do printf "\n# 'evms_query volumes $d' output\n" >> "$r" evms_query volumes "$d" 2>&1 >> "$r" || return done for d in `evms_query volumes`; do printf "\n# 'evms_query info $d' output\n" >> "$r" evms_query info "$d" 2>&1 >> "$r" || return done [ ! -s "/var/log/evms-engine.log" ] || cp -p /var/log/evms-engine.log "sysreport.evms-engine.log" } # Partition table information via fdisk export no_save_fdisk= save_fdisk_msg='Obtaining FDISK information' save_fdisk() { [ -z "$no_save_fdisk" ] || return 0 local r='sysreport.fdisk' timestamp "$r" printf "# 'fdisk -l' output\n\n" >> "$r" fdisk -l >> "$r" 2>&1 || return } # VESA Display Data Channel (or DDC) export no_save_ddcprobe= save_ddcprobe_msg='Obtaining VESA Display Data Channel' save_ddcprobe() { [ -z "$no_save_ddcprobe" ] || return 0 [ -x /usr/sbin/ddcprobe ] || return 17 local r='sysreport.ddcprobe' timestamp "$r" printf "# 'ddcprobe' output\n\n" >> "$r" LC_ALL=C /usr/sbin/ddcprobe >> "$r" 2>&1 || return } # DMI (some say SMBIOS) table information export no_save_dmidecode= save_dmidecode_msg='Obtaining DMI table information' save_dmidecode() { [ -z "$no_save_dmidecode" ] || return 0 [ -x /usr/sbin/dmidecode ] || return 17 local r='sysreport.dmidecode' timestamp "$r" printf "# 'dmidecode' output\n\n" >> "$r" LC_ALL=C /usr/sbin/dmidecode >> "$r" 2>&1 || return } # The "vital product data" information export no_save_vpddecode= save_vpddecode_msg='Obtaining vital product data' save_vpddecode() { [ -z "$no_save_vpddecode" ] || return 0 [ -x /usr/sbin/vpddecode ] || return 17 local r='sysreport.vpddecode' timestamp "$r" printf "# 'vpddecode' output\n\n" >> "$r" LC_ALL=C /usr/sbin/vpddecode >> "$r" 2>&1 || return } # BIOS information export no_save_biosdecode= save_biosdecode_msg='Obtaining BIOS information' save_biosdecode() { [ -z "$no_no_save_vpddecode" ] || return 0 [ -x /usr/sbin/biosdecode ] || return 17 local r='sysreport.biosdecode' timestamp "$r" printf "# 'biosdecode' output\n\n" >> "$r" LC_ALL=C /usr/sbin/biosdecode >> "$r" 2>&1 || return } save_env="$(printenv |sed -ne 's/^\(no_save_[a-z]\+\)=.*/\1/pg' |sort -u)" getopt_save="$(printf %s "$save_env" |sed -e 's/^no_//' |tr _ - |tr -s '[:space:]' ',')" getopt_no_save="$(printf %s "$save_env" |tr _ - |tr -s '[:space:]' ',')" TEMP=`getopt -n $PROG -o o:,$getopt_common_opts -l outfile:,save:,no-save:,$getopt_save,$getopt_no_save,$getopt_common_longopts -- "$@"` || show_usage eval set -- "$TEMP" while :; do case "$1" in --save|--no-save) mode="$1" shift save_value= [ -n "${mode##--no-save*}" ] || save_value=1 if [ -n "$(printf %s "$1" |tr -d '[:alpha:],[:space:]')" ]; then message "$mode: invalid argument: $1" show_usage fi for arg in `printf %s "$1" |tr , ' '`; do name="no_save_$arg" if ! echo "$save_env" |grep -qs "^$name\$"; then message "$mode: invalid argument: $arg" show_usage fi eval "$name=$save_value" done ;; --save-|--no-save-) show_usage ;; --save-[a-z]*) arg="no_save_${1##--save-}" eval $arg= ;; --no-save-[a-z]*) arg="no_save_${1##--no-save-}" eval $arg=1 ;; -o|--outfile) shift; outfile="$1" ;; --) shift; break ;; *) parse_common_option "$1" ;; esac shift done trap exit_handler HUP PIPE INT QUIT TERM EXIT workdir="`mktemp -dt "$PROG.XXXXXXXXXX"`" cd "$workdir" for f in \ save_udevtrigger save_modalias save_modules save_lspci save_lsmod save_dmesg save_commoninfo \ save_evmsinfo save_fdisk save_ddcprobe save_dmidecode save_vpddecode save_biosdecode ; do eval msg="\${${f}_msg:-Obtaining unknown information}" begin_msg "$msg" "$f" && rc=0 || rc=$? end_msg "$rc" done if ls -1 sysreport.* >/dev/null 2>&1; then [ -n "$outfile" ] || outfile="$cwd/sysreport-$(date +"%Y%m%d").tar.bz2" begin_msg "Saving system information to $outfile" tar -cjf "$outfile" sysreport.* && rc=0 || rc=$? end_msg "$rc" printf '\n\nPlease submit %s to sysreport@altlinux.org\n\n' "$outfile" fi