--- bonding.sh-orig 2007-10-23 23:59:26.000000000 +0100 +++ /lib/rcscripts/net/bonding.sh 2009-05-30 19:05:36.000000000 +0100 @@ -15,7 +15,7 @@ # # Expose variables that can be configured bonding_expose() { - variables slaves + variables slaves bonding } # bool bonding_check_installed(void) @@ -23,6 +23,7 @@ # Returns 0 if ifenslave is installed, otherwise 1 bonding_check_installed() { [[ -x /sbin/ifenslave ]] && return 0 + [[ -f /sys/class/net/bonding_masters ]] && return 0 ${1:-false} && eerror "For link aggregation (bonding) support, emerge net-misc/ifenslave" return 1 } @@ -38,8 +39,8 @@ # # Bonds the interface bonding_pre_start() { - local iface="$1" s= ifvar=$(bash_variable "$1") - local -a slaves=() + local iface="$1" s= ifvar=$(bash_variable "$1") b= retval=0 + local -a slaves=() bonding=() slaves="slaves_${ifvar}[@]" [[ -z ${!slaves} ]] && return 0 @@ -48,6 +49,43 @@ # Support space seperated slaves [[ ${#slaves[@]} == 1 ]] && slaves=( ${slaves} ) + bonding="bonding_${ifvar}[@]" + bonding=( "${!bonding}" ) + + # Support space seperated bonding options + [[ ${#bonding[@]} == 1 ]] && bonding=( ${bonding} ) + + # Check for bonding_ifvar config, and load module + if test -n ${bonding} ; then + modprobe bonding >& /dev/null && { + ebegin "Waiting 5 seconds for bonding to settle"; + sleep 5; + eend 0; + } + if test -f /sys/class/net/bonding_masters ; then + # Loading the bonding module can automatically create bonds + # We don't want that. + if [ -d /sys/class/net/${iface} ] ; then + einfo "Bringing ${iface} down, as bonding probably created it" + interface_down "${iface}" && { + ebegin "Waiting 5 seconds for bonding to settle"; + sleep 5; + eend 0; + } + fi + # Create bond + echo "+${iface}" > /sys/class/net/bonding_masters 2> /dev/null + # Set options + for b in "${bonding[@]}" ; do + echo ${b/*=/} > /sys/class/net/${iface}/bonding/${b/=*/} 2> /dev/null + done + else + # Unload module, and complain, if bonding_masters doesn't exist + #rmmod modprobe >& /dev/null + eerror "bonding module older than 3.0.0 (or bonding not available), sysfs support not available" + fi + fi + interface_exists "${iface}" true || return 1 if ! bonding_exists "${iface}" ; then @@ -67,7 +105,7 @@ # Must force the slaves to a particular state before adding them for s in "${slaves[@]}" ; do interface_del_addresses "${s}" - interface_up "${s}" + test -n ${bonding} && interface_down "${s}" || interface_up "${s}" done # now force the master to up @@ -75,8 +113,21 @@ # finally add in slaves eoutdent - /sbin/ifenslave "${iface}" ${slaves[@]} >/dev/null - eend $? + if test -n ${bonding} ; then + for s in "${slaves[@]}" ; do + echo "+${s}" > /sys/class/net/${iface}/bonding/slaves + ret=$? + [[ ${retval} = 0 ]] && retval=${ret} + done + # Set options again, as some don't work earlier + for b in "${bonding[@]}" ; do + echo ${b/*=/} > /sys/class/net/${iface}/bonding/${b/=*/} 2> /dev/null + done + else + /sbin/ifenslave "${iface}" ${slaves[@]} >/dev/null + retval=$? + fi + eend $retval return 0 #important } @@ -103,7 +154,13 @@ eindent einfo "${slaves}" eoutdent - /sbin/ifenslave -d "${iface}" ${slaves} + if test -n "$(cat /sys/class/net/bonding_masters)" ; then + for s in ${slaves}; do + echo "-${s}" > /sys/class/net/${iface}/bonding/slaves + done + else + /sbin/ifenslave -d "${iface}" ${slaves} + fi # reset all slaves for s in ${slaves}; do @@ -112,6 +169,7 @@ interface_down "${s}" fi done + echo "-${iface}" > /sys/class/net/bonding_masters eend 0 return 0