commit a20a2ca085b399f00cb9faabf7d1c77b85b868b1 Author: Tanguy Person Date: Sat May 25 14:52:48 2013 +0200 Add Rank as profile option, use it in ifplugd.action to sort profiles. diff --git a/docs/netctl.profile.5.txt b/docs/netctl.profile.5.txt index caffdc9..c88b9d6 100644 --- a/docs/netctl.profile.5.txt +++ b/docs/netctl.profile.5.txt @@ -87,6 +87,10 @@ GENERAL OPTIONS A command that is executed before a connection is brought down. Similar precautions should be taken as with 'ExecUpPost'. +'Rank=':: + Integer, rank used to sort profiles. A high value gives more + importance to the profile. Defaults to '++0++'. + IP OPTIONS ---------- diff --git a/docs/netctl.special.7.txt b/docs/netctl.special.7.txt index 668f7b1..d0cc738 100644 --- a/docs/netctl.special.7.txt +++ b/docs/netctl.special.7.txt @@ -53,8 +53,9 @@ netctl-auto@.service:: netctl-ifplugd@.service:: This unit starts ifplugd on the interface it is used for. It will try to start a netctl profile whenever a cable is plugged into the - interface and stop the profile when the cable is unplugged. Note - that this unit does not provide network.target. + interface and stop the profile when the cable is unplugged. The order + in which profiles are tried depends on the Rank, AutoWired and Dhcp + profile options. Note that this unit does not provide network.target. SEE ALSO diff --git a/src/ifplugd.action b/src/ifplugd.action index 617902f..10eb3d2 100755 --- a/src/ifplugd.action +++ b/src/ifplugd.action @@ -6,6 +6,36 @@ PROFILE_FILE="$STATE_DIR/ifplugd_$1.profile" +## List compatible profiles, sorted by score (best score first) +# $1: the interface +function list_elligible_profiles_sorted_by_score () { + declare -a elligible_profiles_by_score + while read -r profile; do + local score + score=$( + source "$PROFILE_DIR/$profile" + [[ "$Interface" == "$1" && "$Connection" == "ethernet" ]] || continue + local -i score + local -i rank="${Rank:-0}" + let score=$rank + let score=$score*2 + is_yes "${AutoWired:-no}" && let score++ # user preferred AUTO profile + let score=$score*2 + [[ "$IP" == "dhcp" ]] && let score++ # dhcp profile + echo "$score" + ) + [[ ! -z "$score" ]] && elligible_profiles_by_score[$score]="${elligible_profiles_by_score[$score]} $profile" + done < <(list_profiles) + local sorted_indexes=$((for i in ${!elligible_profiles_by_score[@]}; do echo $i; done) | sort --sort=numeric --reverse) + local index + for index in $sorted_indexes; do + local profile + for profile in ${elligible_profiles_by_score[$index]}; do + echo "$profile" + done + done +} + case "$2" in up) # Look for a dhcp based profile to try first @@ -16,25 +46,7 @@ case "$2" in declare -a preferred_profiles declare -a dhcp_profiles declare -a static_profiles - while read -r profile; do - ( - echo "Reading profile '$profile'" - source "$PROFILE_DIR/$profile" - [[ "$Interface" == "$1" && "$Connection" == "ethernet" ]] || continue - is_yes "${AutoWired:-no}" && exit 1 # user preferred AUTO profile - [[ "$IP" == "dhcp" ]] && exit 2 # dhcp profile - exit 3 # static profile - ) - case $? in - 1) preferred_profiles+=("$profile");; - 2) dhcp_profiles+=("$profile");; - 3) static_profiles+=("$profile");; - esac - done < <(list_profiles) - if [[ ${#preferred_profiles[@]} > 1 ]]; then - echo "AutoWired flag for '$1' set in more than one profile (${preferred_profiles[*]})" - fi - for profile in "${preferred_profiles[@]}" "${dhcp_profiles[@]}" "${static_profiles[@]}"; do + for profile in $(list_elligible_profiles_sorted_by_score "$1"); do if ForceConnect=yes "$SUBR_DIR/network" start "$profile"; then mkdir -p "$(dirname "$PROFILE_FILE")" printf "%s" "$profile" > "$PROFILE_FILE"