ACC SHELL

Path : /etc/sysconfig/network/scripts/
File Upload :
Current File : //etc/sysconfig/network/scripts/link_wait

#!/bin/bash
#
# Copyright (c) 2010 SUSE LINUX Products GmbH, Germany.
# All rights reserved.
#
# 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., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# Authors: Marius Tomaschewski <mt@suse.de>
#
usage () {
	echo $@
	echo "usage: if-up.d/$SCRIPTNAME [<config>] <interface> [-o <options>]"
	echo ""
	echo "Options are:"
	echo "    [on]boot : we are currently booting (or shutting down)"
	echo "    debug    : be verbose"
	echo "    rc       : indicates that we are called from rcnetwork"
	echo ""
	echo "Any another options are ignored"
	echo ""
	echo "Per interface ifcfg-<config> file variables are:"
	echo "  LINK_WAIT=no    (or empty/unset)"
	echo "    - default, don't do anything"
	echo "  LINK_WAIT=check (or yes)"
	echo "    - check the link state flags"
	echo "  LINK_WAIT=<secs>"
	echo "    - seconds to just sleep without any check"
	echo "  LINK_WAIT_PING_IPV4=<ipv4 address to ping>"
	echo "    - sleep half of the time in LINK_WAIT, then"
	echo "      ping the address the rest of the time"
	echo ""
	echo "Install using:"
	echo "  ln -s ../scripts/link_wait /etc/sysconfig/network/if-up.d/"
	echo ""
	exit $R_USAGE
}

######################################################################
# change the working direcory and source some common files
#
R_INTERNAL=1      # internal error, e.g. no config or missing scripts
cd /etc/sysconfig/network || exit $R_INTERNAL
test -f ./config && . ./config
test -f scripts/functions && . scripts/functions || exit $R_INTERNAL

######################################################################
# check arguments and how we are called (in case of links)
#
SCRIPTNAME=${0##*/}
debug $*
case $1 in ""|-h|*help*) usage ;; esac
CONFIG="$1"
shift
if [ "x$1" != x -a "x$1" != "x-o" ] ; then
        INTERFACE="$1"
else
        INTERFACE="$CONFIG"
fi
shift
test "x$1" = "x-o" && shift
MODE=''
RUN_FROM_RC=no
DEBUG=${DEBUG:-no}
while [ $# -gt 0 ]; do
	case $1 in
		boot|onboot) MODE=onboot ;;
		debug)       DEBUG=yes ;;
		rc)          RUN_FROM_RC=yes ;;
		*)           debug unknown option $1 ;;
	esac
	shift
done


# filter out some special interface types
case "$INTERFACE" in
	all|noiface|lo) exit 0 ;;
esac
is_iface_available "$INTERFACE" || exit 0

# source interface config and make sure we use the
# per interface setting for wait for link check...
unset LINK_WAIT
unset LINK_WAIT_PING_IPV4
test -f ./ifcfg-$CONFIG && . ./ifcfg-$CONFIG || exit 0

# usage: ifprint <err_mesg|mesg|...> message text...
ifprint() {
	func=${1}  ; shift
	test "x$func" = x -o "x$INTERFACE" = x && return 1
	if [ "$RUN_FROM_RC" = yes -a "$INTERFACE" != all ] ; then
		$func "`printf "    %-9s " "$INTERFACE"`$*"
	else
		$func "$*"
	fi
}

check_link_detected () {
	local c=`cat /sys/class/net/${1}/carrier 2>/dev/null`
	local d=`cat /sys/class/net/${1}/dormant 2>/dev/null`
	local o=`cat /sys/class/net/${1}/operstate 2>/dev/null`

	debug "link detection ${1}: carrier=$c, dormant=$d, operstate=$o"

	if test -e "/sys/class/net/${1}/operstate" ; then
		# SLE 11 has carrier + operstate + dormant
		test "$c" = "1" -a "$d" = "0" -a \
		    \( "$o" = "up" -o "$o" = "unknown" \) && return 0
	else
		# SLE 10 does not have operstate/dormant
		test "$c" = "1" && return 0
	fi
}

do_ping()
{
	local ifname=$1
	local target=$2
	local -i limit=$3
	local -i ret=0
	local beg now sec rest
	IFS=. read beg rest < /proc/uptime
	for ((now=$beg; $now < ($beg + $limit); )) ; do
		sec=$(($limit - ($now - $beg)))
		out=`ping -q -I $ifname -w $sec -c 1 $target 2>&1`
		ret=$?
		debug "$out"
		test $ret -eq 0 && break
		IFS=. read now rest < /proc/uptime
	done
	return $ret
}

case $0 in
*if-up.d*)
	if test "$MODE" = onboot -a "${LINK_WAIT:-no}" != no ;
	then
            test "$LINK_WAIT" = yes && LINK_WAIT=check

	    if test "$LINK_WAIT" != check -a $(( $LINK_WAIT )) -gt 0 ;
	    then
		# don't wait more than WAIT_FOR_INTERFACES / 3
	    	test $(( $LINK_WAIT )) -gt \
		     $(( $WAIT_FOR_INTERFACES / 4 )) && \
		LINK_WAIT=$(( $WAIT_FOR_INTERFACES / 4 ))

	    	case $LINK_WAIT_PING_IPV4 in
		(*\.*\.*\.*)
			declare -i secs=$(( $LINK_WAIT / 2 ))

			ifprint message "waiting $secs secs"
			sleep $secs

			ifprint message "pinging $LINK_WAIT_PING_IPV4 up to $secs secs"
			do_ping "$INTERFACE" "$LINK_WAIT_PING_IPV4" $secs
			ifprint message "ping returned $?"
		;;
		(*)
			declare -i secs=$(( $LINK_WAIT ))

	    		ifprint message "waiting $secs secs"
			sleep $secs
		;;
		esac
	    else
		# don't wait more than WAIT_FOR_INTERFACES / 3
		declare -i secs=$(( $WAIT_FOR_INTERFACES / 4 ))
		declare -i lmax=$secs
		declare -i loop=0
	    	case $LINK_WAIT_PING_IPV4 in
		(*\.*\.*\.*) lmax=$(( $lmax / 2 )) ;;
		esac

		check_link_detected "$INTERFACE"   || \
		ifprint message "no link detected ... waiting up to $secs secs"

		while ! check_link_detected "$INTERFACE" ; do
			sleep 1
			test $((++loop)) -ge $lmax && break
		done

		check_link_detected "$INTERFACE" \
		&& ifprint message "link detected after $loop secs" \
		|| ifprint message "no link detected ... continue"

		case $LINK_WAIT_PING_IPV4 in
		(*\.*\.*\.*)
			ifprint message "pinging $LINK_WAIT_PING_IPV4 up to $secs secs"
			do_ping "$INTERFACE" "$LINK_WAIT_PING_IPV4" $(( $secs - $loop ))
			ifprint message "ping returned $?"
		;;
		esac
	    fi

	fi
;;
*if-down.d*)
;;
*)
	usage
;;
esac


ACC SHELL 2018