summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'net-scripts/init.d')
-rwxr-xr-xnet-scripts/init.d/net.lo307
1 files changed, 163 insertions, 144 deletions
diff --git a/net-scripts/init.d/net.lo b/net-scripts/init.d/net.lo
index 523dd65..f1dbfdc 100755
--- a/net-scripts/init.d/net.lo
+++ b/net-scripts/init.d/net.lo
@@ -17,7 +17,7 @@ depend() {
# Load any custom depend functions for the given interface
# For example, br0 may need eth0 and eth1
local iface="${myservice##*.}"
- [[ $( type -t depend_${iface} ) == "function" ]] && depend_${iface}
+ [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface}
return 0
}
@@ -34,30 +34,27 @@ source "${MODULES_DIR}/helpers.d/functions"
# Make some wrappers to fudge after/before/need/use depend flags.
# These are callbacks so MODULE will be set.
after() {
- local x="$*"
- [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
- eval "${MODULE}_after() { echo \"$x\"; }"
+ eval "${MODULE}_after() { echo \"$*\"; }"
}
before() {
- local x="$*"
- [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
- eval "${MODULE}_before() { echo \"$x\"; }"
+ eval "${MODULE}_before() { echo \"$*\"; }"
}
need() {
- local x="$*"
- [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
- eval "${MODULE}_need() { echo \"$x\"; }"
+ eval "${MODULE}_need() { echo \"$*\"; }"
}
installed() {
- local x="$*"
- [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
# We deliberately misspell this as _installed will probably be used
# at some point
- eval "${MODULE}_instlled() { echo \"$x\"; }"
+ eval "${MODULE}_instlled() { echo \"$*\"; }"
}
-
-sort() {
- LC_ALL=C /bin/sort "$@"
+provide() {
+ eval "${MODULE}_provide() { echo \"$*\"; }"
+}
+functions() {
+ eval "${MODULE}_functions() { echo \"$*\"; }"
+}
+variables() {
+ eval "${MODULE}_variables() { echo \"$*\"; }"
}
# void go_background(void)
@@ -85,8 +82,8 @@ module_load_minimum() {
return 1
fi
- for f in check_installed provides check_depends depend; do
- [[ $( type -t "${MODULE}_${f}" ) == "function" ]] && continue
+ for f in depend; do
+ is_function "${MODULE}_${f}" && continue
eerror "${MODULE} does not support the required function ${f}"
return 1
done
@@ -99,7 +96,7 @@ module_load_minimum() {
# Load and check each module for sanity
# If the module is not installed, the functions are to be removed
modules_load_auto() {
- local i j
+ local i j inst
# Populate the MODULES array
# Basically we treat evey file in ${MODULES_DIR} as a module
@@ -122,10 +119,16 @@ modules_load_auto() {
eerror "interface is a reserved name - cannot load a module called interface"
return 1
fi
+
(
u=0;
module_load_minimum "${MODULES[i]}" || u=1;
- [[ ${u} == 0 ]] && ${MODULES[i]##*/}_check_installed false || u=1;
+ if [[ ${u} == 0 ]]; then
+ inst="${MODULES[i]##*/}_check_installed";
+ if is_function "${inst}" ; then
+ ${inst} false || u=1;
+ fi
+ fi
exit "${u}";
)
@@ -154,11 +157,13 @@ modules_check_installed() {
local i j missingdeps nmods="${#MODULES[@]}"
for (( i=0; i<nmods; i++ )); do
- [[ $( type -t "${MODULES[i]}_instlled" ) != "function" ]] && continue
+ is_function "${MODULES[i]}_instlled" || continue
for j in $( ${MODULES[i]}_instlled ); do
missingdeps=true
- if [[ $( type -t "${j}_check_installed" ) == "function" ]]; then
+ if is_function "${j}_check_installed" ; then
${j}_check_installed && missingdeps=false
+ elif is_function "${j}_depend" ; then
+ missingdeps=false
fi
${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break
done
@@ -209,13 +214,12 @@ modules_check_user() {
)
unset MODULES[j]
unset PROVIDES[j]
- break
fi
done
continue
fi
- if [[ $( type -t "${umods[i]}_provides" ) != "function" ]]; then
+ if ! is_function "${umods[i]}_depend" ; then
# If the module is one of our preferred modules, then
# ignore this error; whatever is available will be
# used instead.
@@ -225,14 +229,19 @@ modules_check_user() {
# not installed. Load the module and report its error
if [[ -e "${MODULES_DIR}/${umods[i]}" ]]; then
source "${MODULES_DIR}/${umods[i]}"
- ${umods[i]}_check_installed true
+ is_function "${umods[i]}_check_installed" \
+ && ${umods[i]}_check_installed true
else
eerror "The module \"${umods[i]}\" does not exist"
fi
return 1
fi
- mod=$( ${umods[i]}_provides )
+ if is_function "${umods[i]}_provide" ; then
+ mod=$( ${umods[i]}_provide )
+ else
+ mod="${umods[i]}"
+ fi
for (( j=0; j<nmods; j++ )); do
[[ -z ${MODULES[j]} ]] && continue
if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]]; then
@@ -269,84 +278,82 @@ modules_check_user() {
}
# void modules_sort(void)
-
+#
+# Sort our modules
modules_sort() {
- local -a modnums sort_history modafter modbefore
- local i j k p changed_something nmods="${#MODULES[@]}"
-
- # Sort our modules
- # We do this by assigning numbers to each module
- # We also assign modbefore and modafter so we don't
- # shell out as much because it's expensive on CPU.
- modnums=()
- for (( i=0; i<nmods; i++ )); do
- modnums[i]="${i}"
- [[ $( type -t "${MODULES[i]}_after" ) == "function" ]] \
- && modafter[i]=$( ${MODULES[i]}_after )
- [[ $( type -t "${MODULES[i]}_before" ) == "function" ]] \
- && modbefore[i]=$( ${MODULES[i]}_before )
+ local i j nmods=${#MODULES[@]} m
+ local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=()
+
+ # Make our provide list
+ for ((i=0; i<nmods; i++)); do
+ dead[i]="false"
+ if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then
+ local provided=false
+ for ((j=0; j<${#provide[@]}; j++)); do
+ if [[ ${provide[j]} == "${PROVIDES[i]}" ]]; then
+ provide_list[j]="${provide_list[j]} ${MODULES[i]}"
+ provided=true
+ fi
+ done
+ if ! ${provided}; then
+ provide[j]="${PROVIDES[i]}"
+ provide_list[j]="${MODULES[i]}"
+ fi
+ fi
done
- # Then we swap numbers based on and after/before flags
- # until we don't swap anymore. The sort_history array prevents
- # the possibility of an infinite loop
- sort_history[0]="${modnums[*]}"
- for (( k=1; 1; k++ )); do
- changed_something=false
- for (( i=0; i<nmods; i++ )); do
- for p in ${modafter[i]}; do
- for (( j=0; j<nmods; j++ )); do
- [[ ${p} != "${MODULES[j]}" && ${p} != "${PROVIDES[j]}" ]] \
- && continue
-
- if [[ ${modnums[i]} -lt "${modnums[j]}" ]]; then
- tmp="${modnums[i]}"
- modnums[i]="${modnums[j]}"
- modnums[j]="${tmp}"
- changed_something=true
- fi
- done
- done
- for p in ${modbefore[i]}; do
- for (( j=0; j<nmods; j++ )); do
- [[ ${p} != "${MODULES[j]}" && ${p} != "${PROVIDES[j]}" ]] \
- && continue
-
- if [[ ${modnums[i]} -gt "${modnums[j]}" ]]; then
- tmp="${modnums[i]}"
- modnums[i]="${modnums[j]}"
- modnums[j]="${tmp}"
- changed_something=true
+ # Create an after array, which holds which modules the module at
+ # index i must be after
+ for ((i=0; i<nmods; i++)); do
+ if is_function "${MODULES[i]}_after" ; then
+ after[i]=" ${after[i]} $(${MODULES[i]}_after) "
+ fi
+ if is_function "${MODULES[i]}_before" ; then
+ for m in $(${MODULES[i]}_before); do
+ for ((j=0; j<nmods; j++)) ; do
+ if [[ ${PROVIDES[j]} == "${m}" ]]; then
+ after[j]=" ${after[j]} ${MODULES[i]} "
+ break
fi
done
done
- done
- ${changed_something} || break
-
- # Make sure we aren't repeating a previous state
- # First time through, k=1, k/2=0
- sort_history[k]="${modnums[*]}"
- if [[ ${sort_history[k]} == "${sort_history[k/2]}" ]]; then
- eerror "Detected an infinite loop sorting modules; blundering ahead"
- break
fi
done
- # Finally we sort our modules in number order
- um=""
- for (( i=0; i<nmods; i++ )); do
- um="${um}${modnums[i]} ${MODULES[i]} ${PROVIDES[i]}\n"
+ # Replace the after list modules with real modules
+ for ((i=0; i<nmods; i++)); do
+ if [[ -n ${after[i]} ]]; then
+ for ((j=0; j<${#provide[@]}; j++)); do
+ after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }"
+ done
+ fi
done
+
+ # We then use the below code to provide a topologial sort
+ module_after_visit() {
+ local name=$1 i x
- p=( $( echo -e "${um}" | sort -n | cut -d' ' -f2,3 ) )
- MODULES=()
- PROVIDES=()
- j=0
- for (( i=0; i<${#p[@]}; i+=2 )); do
- MODULES[j]="${p[i]}"
- PROVIDES[j]="${p[i+1]}"
- (( j++ ))
+ for ((i=0; i<nmods; i++)); do
+ [[ ${MODULES[i]} == "$1" ]] && break
+ done
+
+ ${dead[i]} && return
+ dead[i]="true"
+
+ for x in ${after[i]} ; do
+ module_after_visit "${x}"
+ done
+
+ sorted=( "${sorted[@]}" "${MODULES[i]}" )
+ sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" )
+ }
+
+ for x in ${MODULES[@]}; do
+ module_after_visit "${x}"
done
+
+ MODULES=( "${sorted[@]}" )
+ PROVIDES=( "${sortedp[@]}" )
}
# bool modules_check_depends(bool showprovides)
@@ -355,7 +362,7 @@ modules_check_depends() {
local missingdeps p interface=false
for (( i=0; i<nmods; i++ )); do
- if [[ $( type -t "${MODULES[i]}_need" ) == "function" ]]; then
+ if is_function "${MODULES[i]}_need" ; then
for needmod in $( ${MODULES[i]}_need ); do
missingdeps=true
for (( j=0; j<nmods; j++ )); do
@@ -372,7 +379,15 @@ modules_check_depends() {
done
fi
- ${MODULES[i]}_check_depends || return 1
+ if is_function "${MODULES[i]}_functions" ; then
+ for f in $( ${MODULES[i]}_functions ); do
+ if ! is_function "${f}" ; then
+ eerror "${MODULES[i]}: missing required function \"${f}\""
+ return 1
+ fi
+ done
+ fi
+
[[ ${PROVIDES[i]} == "interface" ]] && interface=true
if ${showprovides} ; then
@@ -418,57 +433,63 @@ modules_load() {
j="${#modules_force[@]}"
for (( i=0; i<j; i++ )); do
module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1
- ${modules_force[i]}_check_installed || unset modules_force[i]
- done
- modules_force=( "${modules_force[@]}" )
-
- # Strip any duplicate modules providing the same thing
- j="${#modules_force[@]}"
- for (( i=0; i<j-1; i++ )); do
- [[ -z ${modules_force[i]} ]] && continue
- for (( k=i+1; k<j; k++ )); do
- [[ -z ${modules_force[k]} ]] && continue
- [[ $( ${modules_force[i]}_provides ) \
- == $( ${modules_force[k]}_provides ) ]] \
- && unset modules_force[k]
- done
+ if is_function "${modules_force[i]}_check_installed" ; then
+ ${modules_force[i]}_check_installed || unset modules_force[i]
+ fi
done
-
MODULES=( "${modules_force[@]}" )
fi
- # We now buffer the _provides functions for a big speed boost
j="${#MODULES[@]}"
for (( i=0; i<j; i++ )); do
- PROVIDES[i]=$( ${MODULES[i]}_provides )
+ # Now load our dependencies - we need to use the MODULE variable
+ # here as the after/before/need functions use it
+ MODULE="${MODULES[i]}"
+ ${MODULE}_depend
+
+ # If no provide is given, assume module name
+ if is_function "${MODULES[i]}_provide" ; then
+ PROVIDES[i]=$( ${MODULES[i]}_provide )
+ else
+ PROVIDES[i]="${MODULES[i]}"
+ fi
done
- if [[ -z ${modules_force[@]} ]]; then
+ if [[ -n ${modules_force[@]} ]]; then
+ # Strip any duplicate modules providing the same thing
+ j="${#MODULES[@]}"
+ for (( i=0; i<j-1; i++ )); do
+ [[ -z ${MODULES[i]} ]] && continue
+ for (( k=i+1; k<j; k++ )); do
+ if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]]; then
+ unset MODULES[k]
+ unset PROVIDES[k]
+ fi
+ done
+ done
+ MODULES=( "${MODULES[@]}" )
+ PROVIDES=( "${PROVIDES[@]}" )
+ else
if ${starting}; then
modules_check_user || return 1
+ else
+ # Always prefer iproute2 for taking down interfaces
+ if is_function iproute2_provide ; then
+ function_wrap iproute2 $(iproute2_provide)
+ fi
fi
fi
-
- # Setup class wrappers: interface_up -> iproute2_up, for example
+
+ # Wrap our modules
j="${#MODULES[@]}"
for (( i=0; i<j; i++ )); do
function_wrap "${MODULES[i]}" "${PROVIDES[i]}"
-
- # Now load our dependencies - we need to use the MODULE variable
- # here as the after/before/need functions use it
- if [[ -z ${modules_force[@]} ]]; then
- MODULE="${MODULES[i]}"
- ${MODULE}_depend
- fi
done
-
- # Some modules may be installed, but not selected by user preference
- # so we wrap these if needed
j="${#WRAP_MODULES[@]}"
for (( i=0; i<j; i++ )); do
- function_wrap "${WRAP_MODULES[i]}"
+ function_wrap ${WRAP_MODULES[i]}
done
-
+
if [[ -z ${modules_force[@]} ]]; then
modules_check_installed || return 1
modules_sort || return 1
@@ -506,7 +527,7 @@ iface_start() {
# pre Start any modules with
for mod in ${MODULES[@]}; do
- if [[ $( type -t "${mod}_pre_start" ) == "function" ]]; then
+ if is_function "${mod}_pre_start" ; then
${mod}_pre_start "${iface}" || { eend 1; return 1; }
fi
done
@@ -554,7 +575,7 @@ iface_start() {
# Otherwise a default of NULL
if [[ -z ${config} ]]; then
# if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then
- if [[ $( type -t "dhcp_start" ) == "function" ]]; then
+ if is_function "dhcp_start" ; then
config=( "dhcp" )
ewarn "Configuration not set for ${iface} - assuming dhcp"
else
@@ -585,7 +606,7 @@ iface_start() {
einfo "${conf[0]}"
# Do we have a function for our config?
- if [[ $( type -t "${conf[0]}_start" ) == "function" ]]; then
+ if is_function "${conf[0]}_start" ; then
eindent
${conf[0]}_start "${iface}" ; x=$?
eoutdent
@@ -594,9 +615,9 @@ iface_start() {
# We do this by testing if the 1st character is a digit
elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]]; then
x="0"
- if [[ ${RC_AUTO_INTERFACE} == "yes" \
- && $(type -t address_exists ) == "function" ]]; then
- if address_exists "${iface}" "${conf[0]}" ; then
+ if [[ ${RC_AUTO_INTERFACE} == "yes" ]] \
+ && is_function arping_address_exists ; then
+ if arping_address_exists "${iface}" "${conf[0]}" ; then
eerror "${conf[0]%%/*} already taken on ${iface}"
x="1"
fi
@@ -629,7 +650,7 @@ iface_start() {
# Start any modules with _post_start
for mod in ${MODULES[@]}; do
- if [[ $( type -t "${mod}_post_start" ) == "function" ]]; then
+ if is_function "${mod}_post_start" ; then
${mod}_post_start "${iface}" || return 1
fi
done
@@ -649,8 +670,7 @@ iface_stop() {
# pre Stop any modules
for mod in ${MODULES[@]}; do
- [[ $( type -t "${mod}_pre_stop" ) == "function" ]] \
- && ${mod}_pre_stop "${iface}"
+ is_function "${mod}_pre_stop" && ${mod}_pre_stop "${iface}"
done
einfo "Bringing down ${iface}"
@@ -667,7 +687,7 @@ iface_stop() {
for i in ${aliases} ${iface}; do
# Stop all our modules
for mod in ${MODULES[@]}; do
- [[ $( type -t "${mod}_stop" ) == "function" ]] && ${mod}_stop "${i}"
+ is_function "${mod}_stop" && ${mod}_stop "${i}"
done
# A module may have removed the interface
@@ -690,8 +710,7 @@ iface_stop() {
# post Stop any modules
for mod in ${MODULES[@]}; do
# We have already taken down the interface, so no need to error
- [[ $( type -t "${mod}_post_stop" ) == "function" ]] \
- && ${mod}_post_stop "${iface}"
+ is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}"
done
return 0
@@ -730,7 +749,7 @@ run_start() {
fi
# Call user-defined preup function if it exists
- if [[ $( type -t preup ) == "function" ]]; then
+ if is_function preup ; then
einfo "Running preup function"
eindent
( preup "${iface}" )
@@ -762,7 +781,7 @@ run_start() {
fi
# Call user-defined postup function if it exists
- if [[ $( type -t postup ) == "function" ]]; then
+ if is_function postup ; then
einfo "Running postup function"
eindent
( postup "${iface}" )
@@ -786,7 +805,7 @@ run_stop() {
[[ -n ${ESSID} ]] && ESSIDVAR=$( bash_variable "${ESSID}" )
# Call user-defined predown function if it exists
- if [[ $( type -t predown ) == "function" ]]; then
+ if is_function predown ; then
einfo "Running predown function"
eindent
( predown "${iface}" )
@@ -800,7 +819,7 @@ run_stop() {
iface_stop "${iface}" || return 1 # always succeeds, btw
# Call user-defined postdown function if it exists
- if [[ $( type -t postdown ) == "function" ]]; then
+ if is_function postdown ; then
einfo "Running postdown function"
eindent
( postdown "${iface}" )
@@ -870,7 +889,7 @@ run() {
else
if [[ ${cmd} == "start" ]]; then
# Call user-defined failup if it exists
- if [[ $( type -t failup ) == "function" ]]; then
+ if is_function failup ; then
einfo "Running failup function"
eindent
( failup "${iface}" )
@@ -878,7 +897,7 @@ run() {
fi
else
# Call user-defined faildown if it exists
- if [[ $( type -t faildown ) == "function" ]]; then
+ if is_function faildown ; then
einfo "Running faildown function"
eindent
( faildown "${iface}" )