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.

223 lines
6.5 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. }
  125. done
  126. }
  127. watchcat_ping() {
  128. failure_period="$1"
  129. force_reboot_delay="$2"
  130. ping_hosts="$3"
  131. ping_frequency_interval="$4"
  132. ping_size="$5"
  133. time_now="$(cat /proc/uptime)"
  134. time_now="${time_now%%.*}"
  135. [ "$time_now" -lt "$failure_period" ] && sleep "$((failure_period - time_now))"
  136. time_now="$(cat /proc/uptime)"
  137. time_now="${time_now%%.*}"
  138. time_lastcheck="$time_now"
  139. time_lastcheck_withinternet="$time_now"
  140. ping_size="$(get_ping_size "$ping_size")"
  141. while true; do
  142. # 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.
  143. time_now="$(cat /proc/uptime)"
  144. time_now="${time_now%%.*}"
  145. time_diff="$((time_now - time_lastcheck))"
  146. [ "$time_diff" -lt "$ping_frequency_interval" ] && sleep "$((ping_frequency_interval - time_diff))"
  147. time_now="$(cat /proc/uptime)"
  148. time_now="${time_now%%.*}"
  149. time_lastcheck="$time_now"
  150. for host in $ping_hosts; do
  151. if [ "$iface" != "" ]; then
  152. ping_result="$(
  153. ping -I "$iface" -s "$ping_size" -c 1 "$host" &>/dev/null
  154. echo $?
  155. )"
  156. else
  157. ping_result="$(
  158. ping -s "$ping_size" -c 1 "$host" &>/dev/null
  159. echo $?
  160. )"
  161. fi
  162. if [ "$ping_result" -eq 0 ]; then
  163. time_lastcheck_withinternet="$time_now"
  164. else
  165. logger -p daemon.info -t "watchcat[$$]" "Could not reach $host for $((time_now - time_lastcheck_withinternet)). Rebooting after reaching $failure_period"
  166. fi
  167. done
  168. [ "$((time_now - time_lastcheck_withinternet))" -ge "$failure_period" ] && reboot_now "$force_reboot_delay"
  169. done
  170. }
  171. mode="$1"
  172. # Fix potential typo in mode and provide backward compatibility.
  173. [ "$mode" = "allways" ] && mode="periodic_reboot"
  174. [ "$mode" = "always" ] && mode="periodic_reboot"
  175. [ "$mode" = "ping" ] && mode="ping_reboot"
  176. case "$mode" in
  177. periodic_reboot)
  178. watchcat_periodic "$2" "$3"
  179. ;;
  180. ping_reboot)
  181. watchcat_ping "$2" "$3" "$4" "$5" "$6"
  182. ;;
  183. restart_iface)
  184. watchcat_monitor_network "$2" "$3" "$4" "$5" "$6" "$7"
  185. ;;
  186. *)
  187. echo "Error: invalid mode selected: $mode"
  188. ;;
  189. esac