You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
5.6 KiB

  1. #!/bin/sh
  2. #
  3. # Copyright (C) 2010 segal.di.ubi.pt
  4. # Copyright (C) 2020 nbembedded.com
  5. #
  6. # This is free software, licensed under the GNU General Public License v2.
  7. #
  8. get_ping_size() {
  9. ps=$1
  10. case "$ps" in
  11. small)
  12. ps="1"
  13. ;;
  14. windows)
  15. ps="32"
  16. ;;
  17. standard)
  18. ps="56"
  19. ;;
  20. big)
  21. ps="248"
  22. ;;
  23. huge)
  24. ps="1492"
  25. ;;
  26. jumbo)
  27. ps="9000"
  28. ;;
  29. *)
  30. echo "Error: invalid ping_size. ping_size should be either: small, windows, standard, big, huge or jumbo"
  31. echo "Cooresponding ping packet sizes (bytes): small=1, windows=32, standard=56, big=248, huge=1492, jumbo=9000"
  32. ;;
  33. esac
  34. echo $ps
  35. }
  36. reboot_now() {
  37. reboot &
  38. [ "$1" -ge 1 ] && {
  39. sleep "$1"
  40. echo 1 > /proc/sys/kernel/sysrq
  41. echo b > /proc/sysrq-trigger # Will immediately reboot the system without syncing or unmounting your disks.
  42. }
  43. }
  44. watchcat_periodic() {
  45. failure_period="$1"
  46. force_reboot_delay="$2"
  47. sleep "$failure_period" && reboot_now "$force_reboot_delay"
  48. }
  49. watchcat_restart_modemmanager_iface() {
  50. [ "$2" -gt 0 ] && {
  51. logger -t INFO "Resetting current-bands to 'any' on modem: \"$1\" now."
  52. /usr/bin/mmcli -m any --set-current-bands=any
  53. }
  54. logger -t INFO "Reconnecting modem: \"$1\" now."
  55. /etc/init.d/modemmanager restart
  56. ifup "$1"
  57. }
  58. watchcat_restart_network_iface() {
  59. logger -t INFO "Restarting network interface: \"$1\"."
  60. ip link set "$1" down
  61. ip link set "$1" up
  62. }
  63. watchcat_restart_all_network() {
  64. logger -t INFO "Restarting networking now by running: /etc/init.d/network restart"
  65. /etc/init.d/network restart
  66. }
  67. watchcat_monitor_network() {
  68. failure_period="$1"
  69. ping_hosts="$2"
  70. ping_frequency_interval="$3"
  71. ping_size="$4"
  72. iface="$5"
  73. mm_iface_name="$6"
  74. mm_iface_unlock_bands="$7"
  75. time_now="$(cat /proc/uptime)"
  76. time_now="${time_now%%.*}"
  77. [ "$time_now" -lt "$failure_period" ] && sleep "$((failure_period - time_now))"
  78. time_now="$(cat /proc/uptime)"
  79. time_now="${time_now%%.*}"
  80. time_lastcheck="$time_now"
  81. time_lastcheck_withinternet="$time_now"
  82. ping_size="$(get_ping_size "$ping_size")"
  83. while true; do
  84. # account for the time ping took to return. With a ping time of 5s, ping might take more than that, so it is important to avoid even more delay.
  85. time_now="$(cat /proc/uptime)"
  86. time_now="${time_now%%.*}"
  87. time_diff="$((time_now - time_lastcheck))"
  88. [ "$time_diff" -lt "$ping_frequency_interval" ] && sleep "$((ping_frequency_interval - time_diff))"
  89. time_now="$(cat /proc/uptime)"
  90. time_now="${time_now%%.*}"
  91. time_lastcheck="$time_now"
  92. for host in $ping_hosts; do
  93. if [ "$iface" != "" ]; then
  94. ping_result="$(
  95. ping -I "$iface" -s "$ping_size" -c 1 "$host" &> /dev/null
  96. echo $?
  97. )"
  98. else
  99. ping_result="$(
  100. ping -s "$ping_size" -c 1 "$host" &> /dev/null
  101. echo $?
  102. )"
  103. fi
  104. if [ "$ping_result" -eq 0 ]; then
  105. time_lastcheck_withinternet="$time_now"
  106. else
  107. if [ "$iface" != "" ]; then
  108. logger -p daemon.info -t "watchcat[$$]" "Could not reach $host via \"$iface\" for \"$((time_now - time_lastcheck_withinternet))\" seconds. Restarting \"$iface\" after reaching \"$failure_period\" seconds"
  109. else
  110. logger -p daemon.info -t "watchcat[$$]" "Could not reach $host for \"$((time_now - time_lastcheck_withinternet))\" seconds. Restarting networking after reaching \"$failure_period\" seconds"
  111. fi
  112. fi
  113. done
  114. [ "$((time_now - time_lastcheck_withinternet))" -ge "$failure_period" ] && {
  115. if [ "$mm_iface_name" != "" ]; then
  116. watchcat_restart_modemmanager_iface "$mm_iface_name" "$mm_iface_unlock_bands"
  117. fi
  118. if [ "$iface" != "" ]; then
  119. watchcat_restart_network_iface "$iface"
  120. else
  121. watchcat_restart_all_network
  122. fi
  123. /etc/init.d/watchcat start
  124. # Restart timer cycle.
  125. time_lastcheck_withinternet="$time_now"
  126. }
  127. done
  128. }
  129. watchcat_ping() {
  130. failure_period="$1"
  131. force_reboot_delay="$2"
  132. ping_hosts="$3"
  133. ping_frequency_interval="$4"
  134. ping_size="$5"
  135. time_now="$(cat /proc/uptime)"
  136. time_now="${time_now%%.*}"
  137. [ "$time_now" -lt "$failure_period" ] && sleep "$((failure_period - time_now))"
  138. time_now="$(cat /proc/uptime)"
  139. time_now="${time_now%%.*}"
  140. time_lastcheck="$time_now"
  141. time_lastcheck_withinternet="$time_now"
  142. ping_size="$(get_ping_size "$ping_size")"
  143. while true; do
  144. # account for the time ping took to return. With a ping time of 5s, ping might take more than that, so it is important to avoid even more delay.
  145. time_now="$(cat /proc/uptime)"
  146. time_now="${time_now%%.*}"
  147. time_diff="$((time_now - time_lastcheck))"
  148. [ "$time_diff" -lt "$ping_frequency_interval" ] && sleep "$((ping_frequency_interval - time_diff))"
  149. time_now="$(cat /proc/uptime)"
  150. time_now="${time_now%%.*}"
  151. time_lastcheck="$time_now"
  152. for host in $ping_hosts; do
  153. if [ "$iface" != "" ]; then
  154. ping_result="$(
  155. ping -I "$iface" -s "$ping_size" -c 1 "$host" &> /dev/null
  156. echo $?
  157. )"
  158. else
  159. ping_result="$(
  160. ping -s "$ping_size" -c 1 "$host" &> /dev/null
  161. echo $?
  162. )"
  163. fi
  164. if [ "$ping_result" -eq 0 ]; then
  165. time_lastcheck_withinternet="$time_now"
  166. else
  167. logger -p daemon.info -t "watchcat[$$]" "Could not reach $host for $((time_now - time_lastcheck_withinternet)). Rebooting after reaching $failure_period"
  168. fi
  169. done
  170. [ "$((time_now - time_lastcheck_withinternet))" -ge "$failure_period" ] && reboot_now "$force_reboot_delay"
  171. done
  172. }
  173. mode="$1"
  174. # Fix potential typo in mode and provide backward compatibility.
  175. [ "$mode" = "allways" ] && mode="periodic_reboot"
  176. [ "$mode" = "always" ] && mode="periodic_reboot"
  177. [ "$mode" = "ping" ] && mode="ping_reboot"
  178. case "$mode" in
  179. periodic_reboot)
  180. watchcat_periodic "$2" "$3"
  181. ;;
  182. ping_reboot)
  183. watchcat_ping "$2" "$3" "$4" "$5" "$6"
  184. ;;
  185. restart_iface)
  186. watchcat_monitor_network "$2" "$3" "$4" "$5" "$6" "$7"
  187. ;;
  188. *)
  189. echo "Error: invalid mode selected: $mode"
  190. ;;
  191. esac