aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'net/bonding.sh')
-rw-r--r--net/bonding.sh223
1 files changed, 223 insertions, 0 deletions
diff --git a/net/bonding.sh b/net/bonding.sh
new file mode 100644
index 0000000..fb00825
--- /dev/null
+++ b/net/bonding.sh
@@ -0,0 +1,223 @@
+# Copyright (c) 2007-2008 Roy Marples <roy@marples.name>
+# Released under the 2-clause BSD license.
+
+bonding_depend()
+{
+ before interface macchanger
+ program /sbin/ifconfig /bin/ifconfig
+ # If you do not have sysfs, you MUST have this binary instead for ioctl
+ # Also you will loose some functionality that cannot be done via sysfs:
+ if [ ! -d /sys/class/net ]; then
+ program /sbin/ifenslave
+ fi
+}
+
+_config_vars="$_config_vars slaves"
+
+_is_bond()
+{
+ [ -f "/proc/net/bonding/${IFACE}" ]
+}
+
+bonding_pre_start()
+{
+ local x= s= n= slaves= primary=
+
+ slaves="$(_get_array "slaves_${IFVAR}")"
+ unset slaves_${IFVAR}
+
+ eval primary="\$primary_${IFVAR}"
+ unset primary_${IFVAR}
+
+ eval subsume="\$subsume_${IFVAR}"
+ unset subsume_${IFVAR}
+
+
+ [ -z "${slaves}" ] && return 0
+
+ # Load the kernel module if required
+ if [ ! -d /proc/net/bonding ]; then
+ if ! modprobe bonding; then
+ eerror "Cannot load the bonding module"
+ return 1
+ fi
+ fi
+
+ if [ ! -d /sys/class/net ]; then
+ ewarn "sysfs is not available! You will be unable to create new bonds, or change dynamic parameters!"
+ fi
+
+ # We can create the interface name we like now, but this
+ # requires sysfs
+ if ! _exists && [ -d /sys/class/net ]; then
+ echo "+${IFACE}" > /sys/class/net/bonding_masters
+ fi
+ _exists true || return 1
+
+ if ! _is_bond; then
+ eerror "${IFACE} is not capable of bonding"
+ return 1
+ fi
+
+ # Interface must be down in order to configure
+ _down
+
+ # Configure the bond mode & link monitoring, then we can reloop to ensure
+ # we configure all other options
+ # mode needs to be done before all other options.
+ # miimon needs to be done BEFORE downdelay
+ [ -d /sys/class/net ] && for n in mode miimon; do
+ x=/sys/class/net/"${IFACE}"/bonding/$n
+ [ -f "${x}" ] || continue
+ eval s=\$${n}_${IFVAR}
+ if [ -n "${s}" ]; then
+ einfo "Setting ${n}: ${s}"
+ echo "${s}" >"${x}" || \
+ eerror "Failed to configure $n (${n}_${IFVAR})"
+ fi
+ done
+ # Nice and dynamic for remaining options:)
+ [ -d /sys/class/net ] && for x in /sys/class/net/"${IFACE}"/bonding/*; do
+ [ -f "${x}" ] || continue
+ n=${x##*/}
+ eval s=\$${n}_${IFVAR}
+ # skip mode and miimon
+ [ "${n}" == "mode" -o "${n}" == "miimon" ] && continue
+ if [ -n "${s}" ]; then
+ einfo "Setting ${n}: ${s}"
+ echo "${s}" >"${x}" || \
+ eerror "Failed to configure $n (${n}_${IFVAR})"
+ fi
+ done
+
+ ebegin "Adding slaves to ${IFACE}"
+ eindent
+ einfo "${slaves}"
+
+ # Check that our slaves exist
+ (
+ for IFACE in ${slaves}; do
+ _exists true || return 1
+ done
+
+ # Unless we are subsuming an existing interface (NFS root), we down
+ # slave interfaces to work around bugs supposedly in some chipsets
+ # that cause failure to enslave from other states.
+ if [ -z "${subsume}" ]; then
+ for IFACE in ${slaves}; do
+ _delete_addresses
+ _down
+ done
+ fi
+ )
+
+ # Now force the master to up
+ # - First test for interface subsume request (required for NFS root)
+ if [ -n "${subsume}" ]; then
+ einfo "Subsuming ${subsume} interface characteristics."
+ eindent
+ local oiface=${IFACE}
+ IFACE=${subsume}
+ local addr="$(_get_inet_address)"
+ einfo "address: ${addr}"
+ IFACE=${oiface}
+ unset oiface
+ eoutdent
+ # subsume (presumably kernel auto-)configured IP
+ ifconfig ${IFACE} ${addr} up
+ else
+ # warn if root on nfs and no subsume interface supplied
+ local root_fs_type=$(mountinfo -s /)
+ if [ "${root_fs_type}" = "nfs" ]; then
+ warn_nfs=1
+ ewarn "NFS root detected!!!"
+ ewarn " If your system crashes here, /etc/conf.d/net needs"
+ ewarn " subsume_${IFACE}=\"<iface>\" ... where <iface> is the"
+ ewarn " existing, (usually kernel auto-)configured interface."
+ fi
+ # up the interface
+ _up
+ fi
+
+ # finally add in slaves
+ # things needed in the process, and if they are done by ifenslave, openrc, and/or the kernel.
+ # down new slave interface: ifenslave, openrc
+ # set mtu: ifenslave, kernel
+ # set slave MAC: ifenslave, kernel
+ eoutdent
+ if [ -d /sys/class/net ]; then
+ sys_bonding_path=/sys/class/net/"${IFACE}"/bonding
+ local oiface
+ oiface=$IFACE
+ if [ -n "${primary}" ]; then
+ IFACE=$primary
+ _down
+ IFACE=$oiface
+ echo "+${primary}" >$sys_bonding_path/slaves
+ echo "${primary}" >$sys_bonding_path/primary
+ fi
+ for s in ${slaves}; do
+ [ "${s}" = "${primary}" ] && continue
+ if ! grep -q ${s} $sys_bonding_path/slaves; then
+ IFACE=$s
+ _down
+ IFACE=$oiface
+ echo "+${s}" >$sys_bonding_path/slaves
+ fi
+ done
+ else
+ ifenslave "${IFACE}" ${slaves} >/dev/null
+ fi
+ eend $?
+
+ return 0 #important
+}
+
+bonding_stop()
+{
+ _is_bond || return 0
+
+ # Wipe subsumed interface
+ if [ -n "${subsume}" ]; then
+ ifconfig ${subsume} 0.0.0.0
+ fi
+
+ local slaves= s=
+ slaves=$( \
+ sed -n -e 's/^Slave Interface: //p' "/proc/net/bonding/${IFACE}" \
+ | tr '\n' ' ' \
+ )
+ [ -z "${slaves}" ] && return 0
+
+ # remove all slaves
+ ebegin "Removing slaves from ${IFACE}"
+ eindent
+ einfo "${slaves}"
+ eoutdent
+ if [ -d /sys/class/net ]; then
+ for s in ${slaves}; do
+ echo -"${s}" > /sys/class/net/"${IFACE}"/bonding/slaves
+ done
+ else
+ ifenslave -d "${IFACE}" ${slaves}
+ fi
+
+ # reset all slaves
+ (
+ for IFACE in ${slaves}; do
+ if _exists; then
+ _delete_addresses
+ _down
+ fi
+ done
+ )
+
+ _down
+
+ if [ -d /sys/class/net ]; then
+ echo "-${IFACE}" > /sys/class/net/bonding_masters
+ fi
+
+ eend 0
+ return 0
+}