#!/bin/sh
#
# $Id$
#
# multi-ethtool
#
# chkconfig: - 95 99
# description:	pS-Performance Toolkit script to configure the NIC parameters
# 
# see:
# http://code.google.com/p/perfsonar-ps/issues/detail?id=122
# https://bugzilla.redhat.com/show_bug.cgi?id=179877
#
#

# Source function library.
. /etc/init.d/functions

#always set these on perfsonar hosts
DISABLE_TCP_OFFLOAD=1
DISABLE_INTERRUPT_COALESCING=1
TXQUEUELEN=10000

# find all the interfaces besides loopback.
# ignore aliases, alternative configurations, and editor backup files
interfaces=$(ls /etc/sysconfig/network-scripts/ifcfg* | \
            LANG=C sed -e "$__sed_discard_ignored_files" \
                       -e '/\(ifcfg-lo\|:\|ifcfg-.*-range\)/d' \
                       -e '/ifcfg-[A-Za-z0-9\._-]\+$/ { s/^ifcfg-//g;s/[0-9]/ &/}' | \
            LANG=C sort -k 1,1 -k 2n | \
            LANG=C sed 's/ //' | \
            LANG=C cut -d/ -f 5 | \
        LANG=C sed -e 's/ifcfg-//g' )

start() {
ret=0

# Do not save and apply if we've already run
for interface in $interfaces; do
    /sbin/ip link show $interface > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        continue;
    fi

    if [ $DISABLE_INTERRUPT_COALESCING ]; then
        # test if this interface supports IC adjustments
        /sbin/ethtool -c $interface > /dev/null 2>&1
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            # apply multi-ethtool settings
            echo -n $"disabling interrupt coalescing for interface $interface: "
            IC_OFF $interface
            if [ $? -eq 0 ]; then
                success; echo
            else
                failure; echo; ret=1
            fi
        fi
    fi

    if [ $DISABLE_TCP_OFFLOAD ]; then
        echo -n $"disabling TCP offload for interface $interface: "
        TSO_OFF $interface
        if [ $? -eq 0 ]; then
            success; echo
        else
            failure; echo; ret=1
        fi
    fi

    if [ $TXQUEUELEN -ne 0 ]; then
        echo -n $"Setting txqueuelen for $interface to $TXQUEUELEN: "
        TXQUEUELEN_SET $interface $TXQUEUELEN
        if [ $? -eq 0 ]; then
            success; echo
        else
            failure; echo; ret=1
        fi
    fi
done

return $ret
}

TXQUEUELEN_SET() {
/sbin/ip link set $1 txqueuelen $2
}

IC_OFF() {
IC_RET=0
for i in "$1"; do
    if ! /usr/sbin/ethtool -c $i | grep -q '^rx-frames: 1$'; then
         /usr/sbin/ethtool -C $i rx-frames 1 || IC_RET=$?
    fi

    if ! /usr/sbin/ethtool -c $i | grep -q '^rx-usecs: 0$'; then
         /usr/sbin/ethtool -C $i rx-usecs 0 || IC_RET=$?
    fi
done
return $IC_RET
}

TSO_ON() {
/usr/sbin/ethtool -K "$1" tso on
}

TSO_OFF() {
/usr/sbin/ethtool -K "$1" tso off
}


case "$1" in
    start)
        [ -f "$VAR_SUBSYS_TCP_TUNING" ] && exit 0
        start
        RETVAL=$?
        ;;
    *)
        echo $"Usage: $0 {start}"
        RETVAL=2
        ;;
esac

exit $RETVAL
