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
openSUSE Build Service is sponsored by