File qlcnic.sh of Package qlogic-rules
#!/bin/sh
#***********************************************************************#
# QLogic qlcnic firmware dump collection script
# Copyright (C) 2013-2014 QLogic Corporation
# (www.qlogic.com)
#
# 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, 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.
#
# A copy of the GNU General Public License, version 2 can be found at
# http://www.gnu.org/licenses/gpl-2.0.txt
#***********************************************************************#
#
# ACTION FILE: located in /lib/udev/
#
PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/sbin:/bin
export PATH
err() {
echo "$@" >&2
if [ -x /bin/logger ]; then
/bin/logger -t "${0##*/}[$$]" "$@"
fi
if [ -x /usr/bin/logger ]; then
/usr/bin/logger -t "${0##*/}[$$]" "$@"
fi
}
qlcnic_verify_selinux_packages() {
which semanage &> /dev/null
if [ $? -eq 0 ];then
which restorecon &> /dev/null
if [ $? -eq 0 ];then
err "Found semanage and restorecon tools"
selinux_pkg=1
else
err ""restorecon" command not available"
fi
else
err ""semanage" command not available"
fi
}
qlcnic_restore_default_context() {
semanage fcontext -d "/opt/QLogic_Corporation/FW_Dumps(/.*)?" &> /dev/null
if [ $? -ne 0 ];then
err "Restoring default SeLinux context of directory "$DFILE_PATH" failed"
return
fi
restorecon -R -v $DFILE_PATH &> /dev/null
if [ $? -ne 0 ];then
err "Restoring default SeLinux context of directory "$DFILE_PATH" failed"
return
fi
err "SeLinux context of directory "$DFILE_PATH" restored successfully"
}
qlcnic_log_selinux_error(){
err "Failed to change SeLinux context of directory "$DFILE_PATH" to make it write permissive"
err "Minidump extraction failed by udev script"
err "Try saving the dump using command:- \"ethtool -w $ETH data $DFILE\""
exit 1
}
qlcnic_change_selinux_context() {
## Check if selinux packages are available or not to change selinux context ##
qlcnic_verify_selinux_packages
if [ $selinux_pkg -eq 1 ]; then
semanage fcontext -a -t ifconfig_var_run_t "/opt/QLogic_Corporation/FW_Dumps(/.*)?" &> /dev/null
if [ $? -ne 0 ];then
err ""semanage" command failed to change type "ifconfig_var_run_t" of directory "$DFILE_PATH""
qlcnic_log_selinux_error
else
restorecon -R -v $DFILE_PATH &> /dev/null
if [ $? -ne 0 ];then
err ""restorecon" command failed"
qlcnic_log_selinux_error
fi
err "SeLinux context of directory "$DFILE_PATH" changed successfully"
selinux_ctxt_change=1
fi
else
qlcnic_log_selinux_error
fi
}
qlcnic_check_selinux_mode() {
str=`getenforce` &> /dev/null
if [ $? -eq 0 ]; then
if [ $str == "Enforcing" ];then
err "SeLinux is running in enforcing mode"
selinux_mode="Enforcing"
fi
fi
return
}
count=0
MAX_COUNT=20
DRV_NAME=qlcnic
SYSFS=/sys
ETH=${FW_DUMP}
QFWD=${SYSFS}/class/net/${ETH}/device/fw_dump
DFILE_PATH=/opt/QLogic_Corporation/FW_Dumps
DFILE=${DFILE_PATH}/${DRV_NAME}_fw_dump_${ETH}_`eval date +%Y%m%d_%H%M%S`.bin
selinux_mode=""
selinux_pkg=0
selinux_ctxt_change=0
mkdir -p $DFILE_PATH &> /dev/null
# Verify fw_dump binary-attribute file
if ! test -f ${QFWD} ; then
err "qlcnic: no firmware dump file at interface $ETH!!!"
err "qlcnic: trying firmware dump extraction using ethtool"
while [ $count -le $MAX_COUNT ]
do
ls /sbin/ethtool &> /dev/null
if [ $? -eq 0 ]; then
/sbin/ethtool -i $ETH &> /dev/null
if [ $? -eq 0 ]; then
/sbin/ethtool -h | grep "get-dump" | grep "Get dump flag, data" &> /dev/null
if [ $? -ne 0 ];then
err "Ethtool command option is not present to extract minidump"
err "Please update your ethtool program in \"/sbin\" directory to extract minidump"
err "qlcnic: minidump extraction failed by udev script"
exit 1
else
rm -f $DFILE
qlcnic_check_selinux_mode
if [ $selinux_mode == "Enforcing" ];then
qlcnic_change_selinux_context
fi
/sbin/ethtool -w "${ETH}" data $DFILE &> /dev/null
if [ $? -eq 0 ];then
gzip ${DFILE}
err "qlcnic: firmware dump saved to file ${DFILE}.gz."
else
err "qlcnic: minidump extraction failed by udev script"
fi
if [ $selinux_ctxt_change -eq 1 ];then
qlcnic_restore_default_context
fi
exit 0
fi
else
(( count++ ))
sleep 1
fi
else
err "Ethtool program is not present in standard path \"/sbin\""
err "qlcnic: minidump extraction failed by udev script"
exit 1
fi
done
err "qlcnic: $ETH interface is not available to extract minidump"
err "qlcnic: minidump extraction failed by udev script"
exit 1
fi
# Go with dump
rm -f $DFILE
size=`cat /sys/class/net/${ETH}/device/fwdump_size`
(( remainder = size%4096 ))
(( loops = size/4096 ))
if [ $remainder != "0" ]; then
(( loops++ ))
fi
for (( i = 0; i < $loops ; i++ ))
do
echo "Page: $i"
cat /sys/class/net/${ETH}/device/fw_dump >> $DFILE
done
if ! test -s "${DFILE}" ; then
err "qlcnic: no firmware dump file at interface ${ETH}!!!"
rm ${DFILE}
exit 1
fi
gzip ${DFILE}
err "qlcnic: firmware dump saved to file ${DFILE}.gz."
exit 0