pup_event_backend_modprobe 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #!/bin/ash
  2. #(c) Copyright Barry Kauler Nov. 2010. License GPL v3 /usr/share/doc/legal
  3. #a complete rewrite of this script, aiming for extreme simplicity and multi-thread protection.
  4. #101202 usb_storage may have claimed an interface that is needed by another module (dual-mode 3G modems).
  5. #101202 more variability for random usleep.
  6. #101202 /etc/modules/firmware.dep.inst.${KERNVER} now has names of firmware tarballs, not modules.
  7. #101210 put files into /tmp/pup_event_backend (created by rc.sysinit).
  8. #101210 certain modules are loaded explicitly by /usr/sbin/usb_modeswitch_dispatcher.
  9. #101210 protect0, protect1, extra protection mechanisms. 101211: protect2.
  10. #101218 PREFLIST (in /etc/rc.d/MODULESCONFIG) format can have multiple ':', ex: 8139cp:8139too:8139xx (last is most preferred).
  11. #110508 do not allow argument-module if it is blacklisted (note blacklist.conf created in rc.sysinit).
  12. #110508 modprobe -i to ignore "install" and "remove" commands in /etc/modprobe.d/*.conf.
  13. #110509 avoid chance of a module not getting loaded when almost-simultaneous 'add' uevents.
  14. #110516 no longer using setup_alsa_func. now using /etc/modprobe.d/alsa-base.conf (from Ubuntu) only.
  15. #111106 support firmware directories.
  16. #120823 rerwin: $FIRMPKG always written.
  17. #120823 rerwin: --use-blacklist to apply the blacklist commands in the configuration files (if any) to module names as well.
  18. #120828 rerwin: --use-blacklist again.
  19. #120908 rerwin: Change preference processing to ensure preferred module loaded first.
  20. #120909 rerwin: Use temporary blacklisting for preferences to avoid interference and inconsistency.
  21. export LANG=C
  22. . /etc/rc.d/PUPSTATE
  23. . /etc/rc.d/MODULESCONFIG
  24. KERNVER="`uname -r`"
  25. [ "$FASTBOOTMODULESLIST" != "" ] && exit 1 #fastboot, see /etc/rc.d/MODULESCONFIG.
  26. #101121 rerwin: optional $1 supplied by triggered udev rule, see /etc/udev/rules.d/60-udev-modem.rules
  27. RULEMODULE=""
  28. [ $1 ] && RULEMODULE="$1"
  29. SLEEPU=`echo -n ${$} | rev` #110509 ex: pid 3124 becomes 4213, more variability for sleep.
  30. firmware_move_func() {
  31. fPATTERN='[:,]'"${MODULE}"'\.ko|[:,]'"${MODULEx}"'\.ko'
  32. FIRMPKG="`cat /etc/modules/firmware.dep.${KERNVER} | grep -v '^#' | grep ':' | grep -E "$fPATTERN" | cut -f 1 -d ':' | head -n 1`"
  33. if [ "$FIRMPKG" != "" ];then
  34. iPATTERN='^'"${FIRMPKG}"'$'
  35. if [ "`grep "$iPATTERN" /etc/modules/firmware.dep.inst.${KERNVER}`" = "" ];then
  36. FLAGFIRM='no'
  37. if [ -d /lib/modules/all-firmware/${FIRMPKG} ];then #111106 support firmware directories.
  38. cp -a -f --remove-destination /lib/modules/all-firmware/${FIRMPKG}/* /
  39. FLAGFIRM='yes'
  40. fi
  41. if [ "$FLAGFIRM" = "yes" ];then
  42. #execute any post-install script...
  43. if [ -f /pinstall.${FIRMPKG}.sh ];then
  44. BRKCNT=0
  45. while [ 1 ];do #serialise execution of pinstall scripts...
  46. PINSTALLCNT=`find / -maxdepth 1 -type f -name 'pinstall.*.sh' | wc -l`
  47. [ $PINSTALLCNT -eq 1 ] && break
  48. usleep ${SLEEPU}0 #110509
  49. BRKCNT=$(($BRKCNT + 1))
  50. [ $BRKCNT -gt 5 ] && break
  51. done
  52. cd /
  53. /pinstall.${FIRMPKG}.sh >/dev/null 2>&1
  54. rm -f /pinstall.${FIRMPKG}.sh >/dev/null 2>&1
  55. fi
  56. echo "$FIRMPKG" >> /etc/modules/firmware.dep.inst.${KERNVER} #101202 120823 moved.
  57. fi
  58. fi
  59. fi
  60. }
  61. #120908...
  62. write_preference_log() {
  63. echo "$(date +%H:%M:%S.%N | cut -c 1-12) ${$} $MODULE - $1" >> /tmp/pup_event_backend/preferences.log
  64. }
  65. #note, no longer using /tmp/pup_event_modprobe.conf (which was created in rc.sysinit)...
  66. #110508 -i to ignore "install" and "remove" commands in /etc/modprobe.d/*.conf...
  67. #120823 rerwin: --use-blacklist (or -b) to apply the blacklist commands in the configuration files (if any) to module names as well...
  68. MODULE="`/sbin/modprobe -i --use-blacklist --show-depends $MODALIAS 2>/dev/null | tail -n 1 | rev | cut -f 1 -d '/' | rev | cut -f 1 -d '.' | tr '\-' '_'`"
  69. if [ "$RULEMODULE" != "" ];then
  70. if [ "$MODULE" = "" -o "$MODULE" = "usb_storage" -o "$MODULE" = "snd_hda_intel" ];then
  71. #110508 do not allow argument-module if it is blacklisted (note blacklist.conf created in rc.sysinit)...
  72. [ "`cat /etc/modprobe.d/blacklist*.conf | grep -w "${RULEMODULE}"`" = "" ] && MODULE="$RULEMODULE" #101121 rerwin: Use module from argument
  73. fi
  74. fi
  75. [ "$MODULE" = "" ] && exit 1
  76. #101202 usb_storage may have claimed an interface that is needed by another module (dual-mode 3G modems)...
  77. if [ "$MODULE" = "usb_storage" ];then
  78. if [ "`lsmod | grep '^usb_storage '`" != "" ];then
  79. if [ ! -f /etc/modprobe.d/blacklist-usb_storage.conf ];then
  80. echo 'blacklist usb_storage' > /etc/modprobe.d/blacklist-usb_storage.conf
  81. #120828 rerwin: --use-blacklist (or -b) to apply the blacklist commands in the configuration files (if any) to module names as well...
  82. MODULE="`/sbin/modprobe -i --use-blacklist --show-depends $MODALIAS 2>/dev/null | tail -n 1 | rev | cut -f 1 -d '/' | rev | cut -f 1 -d '.' | tr '\-' '_'`" #110508 120828
  83. [ "$MODULE" = "" ] && exit 1
  84. fi
  85. fi
  86. fi
  87. case $MODALIAS in
  88. pci:*)
  89. #######/etc/rc.d/MODULESCONFIG overrides######
  90. #may need to do substitution for specific pci interface...
  91. VENDOR='0x'"`echo -n "$MODALIAS" | cut -f 2 -d 'v' | cut -b 1-8 | tr [A-Z] [a-z]`"
  92. DEVICE='0x'"`echo -n "$MODALIAS" | cut -f 2 -d 'v' | cut -b 10-17 | tr [A-Z] [a-z]`"
  93. aPATTERN="$VENDOR $DEVICE"
  94. REPLACEMENT="`echo "$PCI_OVERRIDES" | grep "$aPATTERN" | cut -f 1 -d ' '`"
  95. [ "$REPLACEMENT" = "(none)" ] && exit 1
  96. #101121 rerwin: RULEMODULE: replace only if not already forced by udev rule...
  97. [ "$REPLACEMENT" != "" ] && [ "$RULEMODULE" = "" ] && MODULE="$REPLACEMENT"
  98. #####BAD HACKS SECTION#####
  99. if [ "$MODULE" = "mwave" ];then
  100. #only install firmware tarball, do not load module (firmware script does it).
  101. firmware_move_func
  102. exit 1
  103. fi
  104. ;;
  105. esac
  106. #101218 bugfix, improve...
  107. #preferences list, ex rt2500usb and rt73usb both hits, then choose latter...
  108. modPATTERN='^'"$MODULE"':'
  109. PREFHIT="`echo -n "$PREFLIST" | tr ' ' '\n' | grep "$modPATTERN" | head -n 1`" #120908
  110. if [ "$PREFHIT" != "" ];then
  111. origMODULE="$MODULE" #120908
  112. cat /etc/modprobe.d/* 2>/dev/null | grep -o '^blacklist *[^ ]*' | tr -s ' ' > /tmp/pup_event_backend/blacklist-$$.conf #120909
  113. PREFMODS="`echo -n "$PREFHIT" | cut -f 2-9 -d ':' | tr ':' ' '`"
  114. for PREFMOD in $PREFMODS #format can have multiple ':', ex: 8139cp:8139too:8139xx (last is most preferred).
  115. do
  116. echo "blacklist $MODULE" >> /tmp/pup_event_backend/blacklist-$$.conf #120909
  117. #120828 rerwin: --use-blacklist (or -b) to apply the blacklist commands in the configuration files (if any) to module names as well...
  118. xMODULE="`/sbin/modprobe -i --use-blacklist --config /tmp/pup_event_backend/blacklist-$$.conf --show-depends $MODALIAS 2>/dev/null | tail -n 1 | rev | cut -f 1 -d '/' | rev | cut -f 1 -d '.' | tr '\-' '_'`" #110508 120828 120909
  119. [ "$xMODULE" = "$PREFMOD" ] && MODULE="$xMODULE"
  120. done
  121. rm -f /tmp/pup_event_backend/blacklist-$$.conf #120909
  122. [ "$MODULE" = "$origMODULE" ] \
  123. && sleep 1 \
  124. && write_preference_log "Retained ($PREFHIT)" \
  125. || write_preference_log "Substituted for module $origMODULE ($PREFHIT)" #120908
  126. fi
  127. #module already loaded, exit...
  128. mREGEX='MODULE='"$MODULE"' DEVPATH'
  129. if cat /tmp/pup_event_backend/pup_event_module_devpath_log* 2>/dev/null | grep "${mREGEX}" ;then exit ;fi
  130. #110509 there may be almost-simultaneous executions of this script to load the same module...
  131. touch /tmp/pup_event_backend/lock1-${$} #start lock region.
  132. mREGEX=" ${MODULE} "
  133. echo "${$} ${MODULE} " > /tmp/pup_event_backend/protect1-${$}
  134. for NUM in 1 2
  135. do
  136. SIMULT="`cat /tmp/pup_event_backend/protect1-* | grep "${mREGEX}"`"
  137. [ $NUM -eq 1 ] && usleep ${SLEEPU}
  138. if [ `echo "$SIMULT" | wc -l` -gt 1 ];then
  139. [ $NUM -eq 2 ] && usleep ${SLEEPU}
  140. #random sleep above means that this process will kill the others before they can kill this one...
  141. for ONEPID in `echo -n "$SIMULT" | cut -f 1 -d ' ' | tr '\n' ' '`
  142. do
  143. [ $ONEPID -eq ${$} ] && continue
  144. [ -f /tmp/pup_event_backend/lock1-${ONEPID} ] && kill $ONEPID #other process within lock region.
  145. [ $? -eq 0 ] && rm -f /tmp/pup_event_backend/protect1-${ONEPID} && rm -f /tmp/pup_event_backend/lock1-${ONEPID}
  146. done
  147. fi
  148. done
  149. #if another process is beyond this point (loading same module), then exit here...
  150. rm -f /tmp/pup_event_backend/lock1-${$} && \
  151. [ `cat /tmp/pup_event_backend/protect1-* | grep "$mREGEX" | wc -l` -gt 1 ] && \
  152. rm -f /tmp/pup_event_backend/protect1-${$} && exit
  153. MODULEx="`echo -n "$MODULE" | tr '_' '-'`"
  154. firmware_move_func
  155. #log to file. rc.sysinit needs this info to find out if any modaliases missed (also above)...
  156. echo "MODULE=$MODULE DEVPATH=$DEVPATH MODALIAS=$MODALIAS" >> /tmp/pup_event_backend/pup_event_module_devpath_log${$}
  157. cd /sbin #v408 rerwin thinks this is needed for slamr module.
  158. #120908 Wait for any preference processing, then ensure a preferred module is loaded first and any active conflicting modules afterward...
  159. if [ "$(ls /tmp/pup_event_backend/preference_processing_active* 2>/dev/null)" != "" ];then
  160. write_preference_log "Began waiting for preference processing"
  161. BRKCNT=0
  162. while [ $BRKCNT -lt 20 ]; do
  163. sleep 0.1
  164. BRKCNT=$(($BRKCNT + 1))
  165. [ "$(ls /tmp/pup_event_backend/preference_processing_active* 2>/dev/null)" = "" ] && break
  166. done
  167. write_preference_log "Resumed loading after preference processing"
  168. fi
  169. NONPREFS="$(echo -n "$PREFLIST" | tr ' ' '\n' | grep -w -o ".*:${MODULE}$" | sed -e 's/:[^:]*$//' | tr : '\n')"
  170. [ "$NONPREFS" = "" ] \
  171. || [ "$(lsmod | sed 's/ .*//' | grep -E "$(echo $MODULE $NONPREFS | tr ' ' '|')" | tail -n 1 | sed "s/^${MODULE}$//")" = "" ] \
  172. && exec /sbin/modprobe $MODULE
  173. touch /tmp/pup_event_backend/preference_processing_active-${$}
  174. write_preference_log "Began preference reload processing"
  175. NPRELOADS=""
  176. ALLDEPENDERS=""
  177. for ONEMODULE in $NONPREFS;do
  178. LOADEDNP="$(lsmod | grep "^$ONEMODULE ")"
  179. if [ "$LOADEDNP" = "" ];then
  180. LOADEDNP="$(grep -o "^MODULE=${ONEMODULE} " /tmp/pup_event_backend/pup_event_module_devpath_log* | grep -o '[^=]*$')"
  181. DEPENDERS=""
  182. else
  183. DEPENDERS="$(echo -n $LOADEDNP | tr -s ' ' | cut -f 4 -d ' ' | tr -d - | tr , ' ' | tr '\n' ' ' | sed 's/^ *$//')"
  184. fi
  185. if [ "$LOADEDNP" != "" ];then
  186. if [ "$DEPENDERS" != "" ];then
  187. /sbin/modprobe -r -i -q $DEPENDERS
  188. wait
  189. ALLDEPENDERS="${ALLDEPENDERS}${DEPENDERS}"
  190. fi
  191. /sbin/modprobe -r -i -q $ONEMODULE
  192. wait
  193. NPRELOADS="${ONEMODULE} ${NPRELOADS}" #reverse order
  194. fi
  195. done
  196. for ONEMODULE in $MODULE $NPRELOADS $ALLDEPENDERS;do
  197. lsmod | grep -q -w "^$ONEMODULE" \
  198. && [ "$ONEMODULE" != "$MODULE" ] \
  199. && write_preference_log "Unload failed for module: ${ONEMODULE}"
  200. /sbin/modprobe $ONEMODULE
  201. sleep 0.01 #precaution
  202. done
  203. write_preference_log "Reloaded module(s): ${NPRELOADS}${ALLDEPENDERS}"
  204. rm -f /tmp/pup_event_backend/preference_processing_active-${$}
  205. #120908 end
  206. ###END###