Subversion Repositories configs

Rev

Rev 3 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/bin/sh
#
# ktune         ktune sysctls
#
# chkconfig: - 27 99
# description:  Applies and reverts ktune sysctl settings
#
# config: /etc/sysctl.ktune
# config: /etc/sysconfig/ktune
#

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

# Source ktune configureation.
if [ -f /etc/sysconfig/ktune ] ; then
    . /etc/sysconfig/ktune
else
    echo -n $"$0: /etc/sysconfig/ktune does not exist."; warning; echo
    exit 5
fi

VAR_SUBSYS_KTUNE=/var/lock/subsys/ktune
SAVE_FILE="/var/run/ktune.save"
SYSCTL_SET="/sbin/sysctl -q -w "
SYSCTL_GET="/sbin/sysctl -e"

KERNEL_ELEVATOR="cfq"
/bin/fgrep -q 'elevator=' /proc/cmdline
CMDLINE_ELEVATOR=$?
if [ -n "$ELEVATOR_TUNE_DEVS" ]; then
        SYS_BLOCK_SDX=
        for file in $(eval LANG=C /bin/ls -1d "${ELEVATOR_TUNE_DEVS}" 2>/dev/null); do
                if ! expr match $(readlink -f "$file") '^/sys/.*/queue/scheduler$' >/dev/null; then
                        printf $"$0: '%s' is not a scheduler control file." "$file"
                        warning; echo
                else
                        SYS_BLOCK_SDX="$SYS_BLOCK_SDX $file"
                fi
        done
else
        SYS_BLOCK_SDX=
fi

declare -a KTUNE_FILES
if [ -r "$SYSCTL" ]; then
    KTUNE_FILES[0]="$SYSCTL"
fi
if [ "x$USE_KTUNE_D" = "xyes" ]; then
    while read file; do
        [ -r "$file" ] || continue
        KTUNE_FILES[${#KTUNE_FILES[*]}]="${file}"
    done <<EOF 
$(LANG=C /bin/ls -1 /etc/ktune.d/*.conf 2>/dev/null)
EOF
fi

function is_int
{
  [ ! -z "${1##*[^0-9]*}" ]
}

load_file() {
    local file=$1
    local save=$2
    local curr_value

    ret_s=0
    errors=
    # apply ktune settings
    while read line; do
        [ "${line:0:1}" == "#" -o "${line:0:1}" == ";" ] && continue
        [ -z "$line" ] && continue

        key=$(echo $line | awk '{ match($0,"[ \t]*=[ \t]*") && $0=substr($0,1,RSTART-1); print $0}')
        value=$(echo $line | awk '/=/ { match($0,"[ \t]*=[ \t]*"); $0=substr($0,RSTART+RLENGTH); print $0}')

        curr_value=""
        if [ "${value:0:1}" = '>' ]; then
            value=${value:1}
            curr_value=$($SYSCTL_GET -n "$key")
        fi

        if [ "${value:0:1}" = '$' ]; then
            value=${value:1}
            value=${!value}
        fi

        is_int "$curr_value" && is_int "$value" && [ "$value" -lt "$curr_value" ] && value="$curr_value"

        [ $save -ne 0 ] && save_value=$($SYSCTL_GET "$key")

        setting=$key
        if [ "$value" ]; then
            [ -n "$value" ] && setting+="=${value}"

            error="$($SYSCTL_SET "${setting}" 2>&1)"
            ret=$?
            if [ $save -ne 0 -a $ret -eq 0 ] && ! grep -q "^${key} =" $SAVE_FILE 2>/dev/null; then
                echo "$save_value" >> "$SAVE_FILE"
            fi
            [ -n "$error" ] && errors+="${error}\n"

            let ret_s+=$ret
        fi
    done < "$file"

    if [ $ret_s -eq 0 ]; then
        success; echo
    else
        failure; echo; ret=1
        echo -e "$errors" | while read line; do echo -e "  ${line}"; done
    fi
}

call_script() {
    local script=$1
    local option=$2

    if [ -x "$script" ]; then
        echo -n "Calling '$script $option': "
        ("$script" "$option")
        ret=$?

        if [ $ret -eq 0 ]; then
            success; echo
        else
            failure; echo; ret=1
        fi
    fi
}

load_sysctl() {
    # Remove save file
    /bin/rm -f "$SAVE_FILE"

    if [ ${#KTUNE_FILES[@]} -gt 0 ]; then
        # Apply general sysctl settings beforehand
        for f in $SYSCTL_PRE; do
            if [ -r "$f" ]; then
                echo $"Applying sysctl settings from $f"
                sysctl -e -p "$f" >/dev/null 2>&1
            fi
        done

        echo $"Applying ktune sysctl settings:"

        # Apply ktune files.
        for file in "${KTUNE_FILES[@]}"; do
            echo -n $"$file: "
            load_file "$file" 1
            call_script "${file%.conf}.sh" start
        done

        # Apply general sysctl settings afterwards
        for f in $SYSCTL_POST; do
            if [ -r "$f" ]; then
                echo $"Applying sysctl settings from $f"
                sysctl -e -p "$f" >/dev/null 2>&1
            fi
        done
    fi
}

revert_sysctl() {
    if [ -r "$SAVE_FILE" ]; then
        if [ "$KTUNE_REVERT_SYSCTL" = 1 ]; then
            echo -n $"Reverting to saved sysctl settings: "
            load_file "$SAVE_FILE" 0
        fi
        /bin/rm -f "$SAVE_FILE"
    fi

    if [ ${#KTUNE_FILES[@]} -gt 0 ]; then
        for file in "${KTUNE_FILES[@]}"; do
            call_script "${file%.conf}.sh" stop
        done
    fi
}

start() {
    [ "$EUID" != "0" ] && exit 4
    ret=0

    # if no elevator on command line, apply the ktune elevator
    if [ -n "$ELEVATOR" -a -n "$SYS_BLOCK_SDX" -a $CMDLINE_ELEVATOR -ne 0 ]; then
        ret_e=0
        echo -n $"Applying ${ELEVATOR} elevator: "
        for i in $SYS_BLOCK_SDX; do
            dev="${i%%/queue*}"; echo -n "${dev##*/} "
            echo "$ELEVATOR" > "$i" 2>/dev/null;
            let ret_e+=$?
        done
        if [ $ret_e -eq 0 ]; then
            success; echo
        else
            failure; echo; ret=1
        fi
    fi

    load_sysctl

    /bin/touch $VAR_SUBSYS_KTUNE
    return $ret
}

reload() {
    [ "$EUID" != "0" ] && exit 4
    revert_sysctl
    load_sysctl
}

stop() {
    [ "$EUID" != "0" ] && exit 4
    ret=0

    revert_sysctl

    # if no elevator on command line, apply the default elevator
    if [ -n "$ELEVATOR" -a -n "$SYS_BLOCK_SDX" -a $CMDLINE_ELEVATOR -ne 0 ]; then
        ret_e=0
        echo -n $"Reverting to ${KERNEL_ELEVATOR} elevator: "
        for i in $SYS_BLOCK_SDX; do
            dev="${i%%/queue*}"; echo -n "${dev##*/} "
            echo "$KERNEL_ELEVATOR" > "$i" 2>/dev/null;
            let ret_e+=$?
        done
        if [ $ret_e -eq 0 ]; then
            success; echo
        else
            failure; echo; ret=1
        fi
    fi

    /bin/rm -f $VAR_SUBSYS_KTUNE
    return $ret
}

status() {
    [ "$EUID" != "0" ] && exit 4

    if [ ! -f "$VAR_SUBSYS_KTUNE" ]; then
        echo $"ktune settings are not applied."
        return 3
    fi

    echo $"Current ktune sysctl settings:"
    if [ -e $SAVE_FILE ]; then
        keys=$(awk '/^[#;]/ { next } /=/ { match($1,"=") && $1=substr($1,1,RSTART-1); print $1 }' "$SAVE_FILE")
        for key in $keys; do
            $SYSCTL_GET $key
        done
    else
        echo $"None"
    fi

    if [ -n "$ELEVATOR" -a -n "$SYS_BLOCK_SDX" -a $CMDLINE_ELEVATOR -ne 0 ]; then
        echo
        echo $"Current elevator settings:"
        for i in $SYS_BLOCK_SDX; do
            echo -n "${i}: "; cat "$i"
        done
    fi

    return 0
}

case "$1" in
    start)
        [ -f "$VAR_SUBSYS_KTUNE" ] && exit 0
        start
        RETVAL=$?
        ;;
    stop)
        [ -f "$VAR_SUBSYS_KTUNE" ] || exit 0
        stop
        RETVAL=$?
        ;;
    reload)
        [ -f "$VAR_SUBSYS_KTUNE" ] && reload
        RETVAL=$?
        ;;
    restart|force-reload)
        [ -f "$VAR_SUBSYS_KTUNE" ] && stop
        start
        RETVAL=$?
        ;;
    condrestart|try-restart)
        [ -f "$VAR_SUBSYS_KTUNE" ] || exit 0
        stop
        start
        RETVAL=$?
        ;;
    status)
        status
        RETVAL=$?
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart|condrestart|status}"
        RETVAL=2
        ;;
esac

exit $RETVAL