diff --git a/hook-functions b/hook-functions index 9c495e9..7797377 100644 --- a/hook-functions +++ b/hook-functions @@ -316,10 +316,45 @@ copy_modules_dir() # walk /sys for relevant modules sys_walk_mod_add() { - local driver_path module device_path modalias - device_path="$1" + local driver_path module device_path modalias devlink - while [ "${device_path}" != "/sys" ]; do + # This is a crude way of storing two stacks in "$@" by using + # "--" as a separator between them, to implement iterative + # graph traversal over parent/supplier dependencies. The first + # part is device paths to traverse, the other is visited ones. + set -- "$1" "--" + while [ "$1" != "--" ]; do + device_path="$(readlink -f "$1")" + shift + + # Don't walk into same path twice, avoid infinite recursion + case "$*" in + "${device_path}") continue ;; + "${device_path} "*) continue ;; + *" ${device_path} "*) continue ;; + *" ${device_path}") continue ;; + esac + + if [ "$device_path" = "/sys" ]; then + continue + fi + + # Keep current path to add module/modalias for + set -- "$@" "$device_path" + + # Walk into suppliers in next iteration + for devlink in "${device_path}/supplier:"*; do + if [ -d "$devlink" ]; then + set -- "${devlink}/supplier/" "$@" + fi + done + + # Walk into parent in next iteration + set -- "$(dirname "$device_path")" "$@" + done + shift + + for device_path in "$@"; do # device modalias if [ -e "${device_path}/modalias" ]; then modalias=$(cat "${device_path}/modalias") @@ -336,8 +371,6 @@ sys_walk_mod_add() manual_add_modules "${module}" fi fi - - device_path="$(dirname "${device_path}")" done }