span_assignments: -k / --keys and more
authorOron Peled <oron.peled@xorcom.com>
Sun, 29 Sep 2013 08:09:56 +0000 (10:09 +0200)
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>
Sun, 13 Oct 2013 15:01:56 +0000 (11:01 -0400)
* New functionality (documented in the script header):
  - Alternative "keys" for device matching
  - Added new command line options: --help, --dry-run, --verbose, --key

* Clean sysfs attribute contents from special characters in every use-case.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

span_assignments

index 8f29d39..96e49cd 100755 (executable)
 # Without further arguments, it operates on all existing spans
 # With one or more sysfs dahdi_devices it is limited to those.
 #
+# We may use alternative "keys" for device matching:
+# * Available keys:
+#   - "hwid"       - Hardware id attribute from sysfs
+#   - "@location"  - Location attribute from sysfs (embeded inside '<>')
+#   - "/devpath"   - The sysfs absolute devpath
+#
+# * During "dumpconfig", for each device we take the first available key:
+#   - The preference is: "hwid" or else "@location" or else "/devpath"
+#   - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable
+#     or the '{-k|--key} key' command line option.
+#
+# * During "add":
+#   - Any key match is valid (hwid/location/devpath)
+#   - Shell globs (wildcards: '*', '?', '[...]') may be optionally used.
+#
+# Command line options:
+#  - The '-h|--help' show a usage message.
+#  - The '-n|--dry-run' affects the "add" and "remove" operations.
+#  - The '-v|--verbose' currently shows device matches during "add" operation.
+#  - The '-k <key>|--key <key>' overrides the SPAN_ASSIGNMENTS_KEY environment
+#    variable.
+#
 # Examples:
 #    span_assignments list
-#    span_assignments add      # all
-#    span_assignments add /sys/bus/dahdi_devices/devices/astribanks:xbus-00
-#    span_assignments remove   # all
+#    span_assignments add      # all unassigned devices
+#    span_assignments add       /sys/bus/dahdi_devices/devices/astribanks:xbus-00
+#    span_assignments remove   # all assigned devices
+#    span_assignments -k location dumpconfig
 #
 
 devbase='/sys/bus/dahdi_devices/devices'
 DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}"
 pinned_spans_conf="$DAHDICONFDIR/pinned-spans.conf"
+SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid}
+dry_run=
+verbose=
 
 usage() {
-       echo >&2 "Usage: $0 {auto|add|remove|list|dumpconfig} [devpath ...]"
+       echo >&2 "Usage: $0 [options] action [devpath ...]"
+       echo >&2 "       action:"
+       echo >&2 "         auto       - trigger driver auto_assign attribute for given devices"
+       echo >&2 "         add        - assign spans, according to /etc/dahdi/pinned-spans.conf"
+       echo >&2 "         remove     - unassign spans"
+       echo >&2 "         list       - human-readable list of all spans"
+       echo >&2 "         dumpconfig - dump current state as new configuration"
+       echo >&2 ""
+       echo >&2 "       options:"
+       echo >&2 "         -h|--help      - Show this help"
+       echo >&2 "         -n|--dry-run   - For 'add/remove' actions"
+       echo >&2 "         -v|--versbose  - Show matches during 'add' action"
+       echo >&2 "         -k|--key <k>   - Override prefered key during dumpconfig action"
        exit 1
 }
 
+# Parse command line options
+TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key: -n "$0" -- "$@"`
+if [ $? != 0 ]; then
+       echo >&2 "Bad options"
+       usage
+fi
+
+# Note the quotes around `$TEMP': they are essential!
+eval set -- "$TEMP"
+
+while true ; do
+       case "$1" in
+       -h|--help)
+               usage
+               ;;
+       -n|--dry-run)
+               dry_run='true'
+               shift
+               ;;
+       -v|--verbose)
+               verbose='true'
+               shift
+               ;;
+       -k|--key)
+               SPAN_ASSIGNMENTS_KEY="$2"
+               shift
+               shift
+               ;;
+       --)
+               shift
+               break
+               ;;
+       *)
+               echo "Internal error!"
+               exit 1
+               ;;
+       esac
+done
+
 if [ "$#" -eq 0 ]; then
+       echo >&2 "Missing action argument"
        usage
 fi
 action="$1"
 shift
 
+# Validate SPAN_ASSIGNMENTS_KEY
+case "$SPAN_ASSIGNMENTS_KEY" in
+hwid|location|devpath)
+       ;;
+*)
+       echo >&2 "Bad SPAN_ASSIGNMENTS_KEY='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)"
+       usage
+       ;;
+esac
+
 if [ ! -d "$devbase" ]; then
        echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)"
        exit 1
@@ -56,12 +144,18 @@ else
        DEVICES=`echo $devbase/*`
 fi
 
+# Beware of special characters in attributes
+attr_clean() {
+       cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_'
+}
+
 show_devices() {
 
        for device in $DEVICES
        do
-               hw_id=`cat "$device/hardware_id"`
-               location=`cd "$device" && pwd -P | sed 's,/sys/devices/,,'`
+               devpath=`cd "$device" && pwd -P`
+               location='@'`attr_clean "$device/location"`
+               hardware_id=`attr_clean "$device/hardware_id"`
                for local_spanno in `cut -d: -f1 "$device/spantype"`
                do
                        span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \
@@ -74,7 +168,7 @@ show_devices() {
                                spanno='-'
                                basechan='-'
                        fi
-                       printf "%-8s %-14s %s\n" "$local_spanno:$spanno:$basechan" "[$hw_id]" "@$location"
+                       printf "%-8s %-14s %s %s\n" "$local_spanno:$spanno:$basechan" "[$hardware_id]" "$location" "$devpath"
                done | sort -n
        done
 }
@@ -86,14 +180,17 @@ dump_config() {
        echo ''
        for device in $DEVICES
        do
-               hw_id=`cat "$device/hardware_id"`
-               location='@'`cd "$device" && pwd -P | sed 's,/sys/devices/,,'`
-               if [ "$hw_id" != '' ]; then
-                       id="$hw_id"
+               devpath=`cd "$device" && pwd -P`
+               location=`attr_clean "$device/location"`
+               hardware_id=`attr_clean "$device/hardware_id"`
+               if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then
+                       id="$hardware_id"
+               elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then
+                       id="@$location"
                else
-                       id="$location"
+                       id="$devpath"
                fi
-               echo "# Device: [$hw_id] $location"
+               echo "# Device: [$hardware_id] @$location $devpath"
                for local_spanno in `cut -d: -f1 "$device/spantype"`
                do
                        span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \
@@ -117,6 +214,10 @@ unassign_all_spans() {
                find "$device" -follow -maxdepth 1 -name 'span-*' -type d | \
                        sort | while read spandir; do
                        local_spanno=`cat "$spandir/local_spanno"`
+                       if [ "$dry_run" = true ]; then
+                               echo "(dry-run) unassign $device $local_spanno"
+                               continue
+                       fi
                        echo "unassign $device $local_spanno"
                        if ! echo "$local_spanno" > "$device/unassign_span"; then
                                echo >&2 "$0: failed unassigning '$local_spanno' in '$device'"
@@ -130,11 +231,6 @@ filter_conf() {
        sed -e 's/#.*//' -e '/^[ \t]*$/d' "$pinned_spans_conf"
 }
 
-# Beware of special characters in attributes
-attr_clean() {
-       cat "$1" | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_'
-}
-
 assign_device_spans() {
        device="$1"
        for s in $spanspecs
@@ -142,12 +238,16 @@ assign_device_spans() {
                local_spanno=`echo "$s" | cut -d: -f1`
                spanno=`echo "$s" | cut -d: -f2`
                span="$device/span-$spanno"
+               if [ "$dry_run" = true ]; then
+                       echo "(dry-run) assign $device: $s"
+                       continue
+               fi
                if [ -d "$span" ]; then
                        span_local_spanno=`cat "$span/local_spanno"`
                        if [ "$span_local_spanno" != "$local_spanno" ]; then
                                echo "WARNING: $span_local_spanno != $local_spanno"
                        fi
-                       echo "$device [$local_spanno] already assigned to $spanno. Skipping..."
+                       echo "$device [$local_spanno] already assigned to span $spanno. Skipping..."
                        continue
                fi
                echo "assign $device: $s"
@@ -159,21 +259,29 @@ assign_device_spans() {
 
 match_device() {
        device="$1"
-       location='@'`cd "$device" && pwd -P | sed 's,/sys/devices/,,'`
+       devpath=`cd "$device" && pwd -P`
+       location='@'`attr_clean "$device/location"`
        hardware_id=`attr_clean "$device/hardware_id"`
        filter_conf | while read id spanspecs
        do
                # We use case to enable shell-style globbing in configuration
+               case "$hardware_id" in
+               $id)
+                       [ "$verbose" = true ] && echo "match by hwid ($id ~ $hardware_id): $spanspecs"
+                       assign_device_spans "$device"
+                       ;;
+               esac
+               # We use case to enable shell-style globbing in configuration
                case "$location" in
                $id)
-                       #echo "match location($id ~ $location): $spanspecs"
+                       [ "$verbose" = true ] && echo "match by location ($id ~ $location): $spanspecs"
                        assign_device_spans "$device"
                        ;;
                esac
                # We use case to enable shell-style globbing in configuration
-               case "$hardware_id" in
+               case "$devpath" in
                $id)
-                       #echo "match hardware_id([$id] ~ $hardware_id): $spanspecs"
+                       [ "$verbose" = true ] && echo "match by devpath ($id ~ $devpath): $spanspecs"
                        assign_device_spans "$device"
                        ;;
                esac
@@ -196,7 +304,9 @@ auto_assign_devices() {
        for device in $DEVICES
        do
                echo "auto-assign $device"
-               echo 1 > "$device/auto_assign"
+               if [ "$dry_run" != true ]; then
+                       echo 1 > "$device/auto_assign"
+               fi
        done
 }
 
@@ -217,6 +327,7 @@ dumpconfig)
        dump_config
        ;;
 *)
+       echo >&2 "Bad action='$action'"
        usage
        ;;
 esac