#! /bin/sh # # /usr/sbin/span_assignments: # # this script can be used both from udev and # from the command line to assign/unassign and list # current span assignments. # # It uses a configuration file: $DAHDICONFDIR/pinned-spans.conf # (default DAHDICONFDIR=/etc/dahdi) # # The first argument is an action: # "auto" - trigger driver auto_assign attribute for given devices # (no configuration file is used) # "add" - assign (spans which are not already assigned), according # to /etc/dahdi/pinned-spans.conf configuration file # "remove" - unassign spans which are not already unassigned # "list" - human-readable list of all spans (with/without assignments) # "dumpconfig" - dump current assignments in a /etc/dahdi/pinned-spans.conf # compatible format # # Without further arguments, it operates on all existing spans # With one or more sysfs dahdi_devices it is limited to those. # # Examples: # span_assignments list # span_assignments add # all # span_assignments add /sys/bus/dahdi_devices/devices/astribanks:xbus-00 # span_assignments remove # all # devbase='/sys/bus/dahdi_devices/devices' DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" pinned_spans_conf="$DAHDICONFDIR/pinned-spans.conf" usage() { echo >&2 "Usage: $0 {auto|add|remove|list|dumpconfig} [devpath ...]" exit 1 } if [ "$#" -eq 0 ]; then usage fi action="$1" shift if [ ! -d "$devbase" ]; then echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)" exit 1 fi # Use given devices or otherwise, all existing devices if [ "$#" -gt 0 ]; then DEVICES="$@" else DEVICES=`echo $devbase/*` fi show_devices() { for device in $DEVICES do hw_id=`cat "$device/hardware_id"` location=`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` for local_spanno in `cut -d: -f1 "$device/spantype"` do span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` if [ "$span" != '' ]; then spanno=`echo $span | sed 's/^.*-//'` name=`cat 2>/dev/null "$device/$span/name"` basechan=`cat 2>/dev/null "$device/$span/basechan"` else spanno='-' basechan='-' fi printf "%-8s %-14s %s\n" "$local_spanno:$spanno:$basechan" "[$hw_id]" "@$location" done | sort -n done } dump_config() { echo '#' echo "# Autogenerated by $0 on `date`" echo "# Map devices + local spans to span + base channel number" 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" else id="$location" fi echo "# Device: [$hw_id] $location" for local_spanno in `cut -d: -f1 "$device/spantype"` do span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` if [ "$span" != '' ]; then spanno=`echo $span | sed 's/^.*-//'` name=`cat 2>/dev/null "$device/$span/name"` basechan=`cat 2>/dev/null "$device/$span/basechan"` printf "%-30s %s\n" "$id" "$local_spanno:$spanno:$basechan" else echo "# Skipped unassigned local span $local_spanno" fi done | sort echo '' done } unassign_all_spans() { for device in $DEVICES do find "$device" -follow -maxdepth 1 -name 'span-*' -type d | \ sort | while read spandir; do local_spanno=`cat "$spandir/local_spanno"` echo "unassign $device $local_spanno" if ! echo "$local_spanno" > "$device/unassign_span"; then echo >&2 "$0: failed unassigning '$local_spanno' in '$device'" fi done done } # Allow comments and empty lines in config file 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 do local_spanno=`echo "$s" | cut -d: -f1` spanno=`echo "$s" | cut -d: -f2` span="$device/span-$spanno" 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..." continue fi echo "assign $device: $s" if ! echo "$s" > "$device/assign_span"; then echo >&2 "$0: failed assigning '$s' to '$device'" fi done } match_device() { device="$1" location='@'`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` 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 "$location" in $id) #echo "match location($id ~ $location): $spanspecs" assign_device_spans "$device" ;; esac # We use case to enable shell-style globbing in configuration case "$hardware_id" in $id) #echo "match hardware_id([$id] ~ $hardware_id): $spanspecs" assign_device_spans "$device" ;; esac done } assign_devices() { if [ ! -f "$pinned_spans_conf" ]; then echo >&2 "$0: Missing '$pinned_spans_conf'" exit 1 fi echo "using '$pinned_spans_conf'" for device in $DEVICES do match_device "$device" done } auto_assign_devices() { for device in $DEVICES do echo "auto-assign $device" echo 1 > "$device/auto_assign" done } case "$action" in auto) auto_assign_devices ;; add) assign_devices ;; remove) unassign_all_spans ;; list) show_devices ;; dumpconfig) dump_config ;; *) usage ;; esac