Advertisement
Martinski4PBin

CheckStuckProcCmds.sh

Dec 2nd, 2022 (edited)
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 20.80 KB | None | 0 0
  1. #!/bin/sh
  2. ######################################################################
  3. # CheckStuckProcCmds.sh
  4. # To monitor & check if any 'nvram' or 'wl' commands are running
  5. # and see if there's a hang during execution of such commands.
  6. # When such a "stuck" command is found, this script also kills
  7. # the process after a short wait (~10 secs) & logs the event.
  8. #
  9. # EXAMPLE CALLS:
  10. # ./CheckStuckProcCmds.sh
  11. # ./CheckStuckProcCmds.sh -help
  12. # ./CheckStuckProcCmds.sh -setcronjob
  13. # ./CheckStuckProcCmds.sh -setcronjob=2
  14. #---------------------------------------------------------------------
  15. # Creation Date: 2022-Jun-12 [Martinski W.]
  16. # Last Modified: 2022-Dec-27 [Martinski W.]
  17. #
  18. readonly VERSION="0.7.8"
  19. ######################################################################
  20.  
  21. #--------------------------------------------#
  22. # START CUSTOMIZABLE PARAMETERS SECTION.
  23. #--------------------------------------------#
  24. CRON_Mins=5   # Cron Job default frequency in minutes #
  25.  
  26. # Modify these variables as necessary for your environment #
  27. TheLOGdir="/opt/var/log"          # LOG directory #
  28. TheTRCdir="/opt/var/log/Trace"    # TRACE directory #
  29. #--------------------------------------------#
  30. # END CUSTOMIZABLE PARAMETERS SECTION.
  31. #--------------------------------------------#
  32.  
  33. set -u
  34.  
  35. ScriptFName1="${0##*/}"
  36. ScriptFName2="${ScriptFName1%.*}"
  37. ScriptFolder="$(/usr/bin/dirname "$0")"
  38. thePID="$(printf "%05d" "$$")"
  39.  
  40. DoMyLogger=1
  41. ShowDebugMsgs=0
  42. ShowMyDbgMsgs=0
  43.  
  44. CRON_Set=0
  45. UseKillCmd=1
  46. DelaySecs=10
  47. MaxDiffSecs=5
  48. MaxTraceIndex=99999
  49. CRON_Tag="CheckStuckCmds"
  50.  
  51. if [ "$ScriptFolder" != "." ]
  52. then
  53.    ScriptFPath="$0"
  54. else
  55.    ShowDebugMsgs=1
  56.    ScriptFolder="$(pwd)"
  57.    ScriptFPath="$(pwd)/$ScriptFName1"
  58. fi
  59.  
  60. echoCMD=/bin/echo
  61.  
  62. _25KBytes=25600
  63. MaxLogSize=$_25KBytes
  64.  
  65. TheLOGtag=""
  66. TheBKPtag="_BKP"
  67. SetBKPLogFile=1
  68. DEF_LOG_Dir=/tmp/var/tmp
  69. DEF_TRC_Dir=/tmp/var/tmp
  70.  
  71. [ ! -d "$TheLOGdir" ] && mkdir "$TheLOGdir" 2>/dev/null
  72. [ ! -d "$TheTRCdir" ] && mkdir "$TheTRCdir" 2>/dev/null
  73.  
  74. [ ! -d "$TheLOGdir" ] && TheLOGdir="$DEF_LOG_Dir"
  75. [ ! -d "$TheTRCdir" ] && TheTRCdir="$DEF_TRC_Dir"
  76. [ ! -d "$TheTRCdir" ] && mkdir "$TheTRCdir" 2>/dev/null
  77.  
  78. TheLogName="${ScriptFName2}${TheLOGtag}"
  79. BkpLogName="${TheLogName}${TheBKPtag}"
  80.  
  81. TheLogFile="${TheLOGdir}/${TheLogName}.LOG"
  82. BkpLogFile="${TheLOGdir}/${BkpLogName}.LOG"
  83.  
  84. ScriptNDXname="${ScriptFName2}.INDX.txt"
  85. StuckCmdsNDXfile="${TheTRCdir}/${ScriptNDXname}"
  86.  
  87. ## File to store LAST known process cmds possibly "stuck" ##
  88. StuckCmdsLOGname="StuckProcCmds"
  89. StuckCmdsLOGfile="${TheLOGdir}/${StuckCmdsLOGname}.LOG.txt"
  90.  
  91. ## 24-hour format (e.g. "2020-03-01 15:19:14") ##
  92. SysLogTimeFormat="%Y-%m-%d %H:%M:%S"
  93.  
  94. ## 12-hour format (e.g. "2020-Mar-01 03:19:14 PM") ##
  95. MyLogTimeFormat="%Y-%b-%d %I:%M:%S %p"
  96.  
  97. # The "delete mark" #
  98. DelMark="**=OK=**"
  99.  
  100. ##################################################################
  101. _ShowUsage_()
  102. {
  103.    cat <<EOF
  104. -----------------------------------------------
  105. SYNTAX:
  106.  
  107. ./$ScriptFName1 [ -help | -setcronjob | -setcronjob=N ]
  108.  
  109. Where 'N' is the Cron Job run frequency in minutes.
  110.  
  111. Current location of log files: [$TheLOGdir]
  112. Current location of trace files: [$TheTRCdir]
  113.  
  114. You can set new directory locations by modifying the
  115. variables "TheLOGdir" & "TheTRCdir" found at the top
  116. of the script file (CUSTOMIZABLE PARAMETERS SECTION).
  117.  
  118. EXAMPLE CALLS:
  119.  
  120. To run & check for any "stuck" 'nvram' or 'wl' commands:
  121.    ./$ScriptFName1
  122.  
  123. To get this usage & syntax description:
  124.    ./$ScriptFName1 -help
  125.  
  126. To create a Cron Job to run every 5 minutes [the default]:
  127.    ./$ScriptFName1 -setcronjob
  128.  
  129. To create a Cron Job to run every 2 minutes [new interval].
  130.    ./$ScriptFName1 -setcronjob=2
  131. -----------------------------------------------
  132. EOF
  133. }
  134.  
  135. if [ $# -gt 0 ] && [ "$1" = "-help" ]
  136. then _ShowUsage_ ; exit 0 ; fi
  137.  
  138. if [ $# -gt 0 ] && [ "$1" = "-setdelay" ]
  139. then sleep $DelaySecs ; fi
  140.  
  141. #################################################################
  142. _GetFileSize_()
  143. {
  144.    local theFileSize=0
  145.    if [ $# -eq 1 ] && [ -n "$1" ] && [ -f "$1" ]
  146.    then
  147.       theFileSize="$(ls -AlF "$1" | awk -F ' ' '{print $5}')"
  148.    fi
  149.    echo "$theFileSize"
  150. }
  151.  
  152. ################################################################
  153. _CheckMyLogFileSize_()
  154. {
  155.    if [ ! -f "$TheLogFile" ] ; then return 1 ; fi
  156.  
  157.    local TheFileSize=0
  158.    TheFileSize="$(_GetFileSize_ "$TheLogFile")"
  159.  
  160.    if [ "$TheFileSize" -gt "$MaxLogSize" ]
  161.    then
  162.       if [ "$SetBKPLogFile" -eq 1 ]
  163.       then
  164.          cp -fp "$TheLogFile" "$BkpLogFile"
  165.       fi
  166.       rm -f "$TheLogFile"
  167.  
  168.       LogMsg="Deleted $TheLogFile [$TheFileSize]"
  169.       _ShowDebugMsg_ "INFO: $LogMsg"
  170.    fi
  171. }
  172.  
  173. ################################################################
  174. _DoInitMyLogFile_()
  175. {
  176.    if [ "$DoMyLogger" -eq 0 ] ; then return 1 ; fi
  177.    _CheckMyLogFileSize_
  178.    if [ ! -f "$TheLogFile" ] ; then touch "$TheLogFile" ; fi
  179. }
  180.  
  181. ################################################################
  182. _ShowMyDGBMsg_()
  183. {
  184.    if [ "$ShowMyDbgMsgs" -eq 0 ] ; then return 1 ; fi
  185.  
  186.    if [ $# -eq 0 ]
  187.    then echo ""
  188.    elif [ $# -eq 1 ]
  189.    then echo "$1"
  190.    else echo "${1}:" "$2"
  191.    fi
  192. }
  193.  
  194. ##################################################################
  195. _ShowDebugMsg_()
  196. {
  197.    if [ "$ShowDebugMsgs" -eq 0 ] ; then return 1 ; fi
  198.  
  199.    if [ $# -eq 0 ]
  200.    then echo ""
  201.    elif [ $# -eq 1 ]
  202.    then echo "$1"
  203.    else echo "${1}:" "$2"
  204.    fi
  205. }
  206.  
  207. ################################################################
  208. _GetLastLineFromFile_()
  209. {
  210.    local TheFileSize  TheLastLine=""
  211.  
  212.    if [ $# -eq 1 ] && [ -n "$1" ] && [ -f "$1" ]
  213.    then
  214.       TheFileSize="$(_GetFileSize_ "$1")"
  215.       if [ "$TheFileSize" -gt 0 ]
  216.       then TheLastLine="$(tail -n 1 "$1")" ; fi
  217.    fi
  218.    echo "$TheLastLine"
  219. }
  220.  
  221. ################################################################
  222. _LastLogFileLineEmpty_()
  223. {
  224.    local TheLastLine=""
  225.    TheLastLine="$(_GetLastLineFromFile_ "$TheLogFile")"
  226.    if [ -z "$TheLastLine" ]
  227.    then return 0
  228.    else return 1
  229.    fi
  230. }
  231.  
  232. ################################################################
  233. _EscapeChars_()
  234. { printf "%s\n" "$1" | sed 's/[][\/$.*^&-]/\\&/g' ; }
  235.  
  236. ################################################################
  237. _DeleteLastLogFileLineMarked_()
  238. {
  239.    local MarkedLine=0  LastLine
  240.  
  241.    LastLine="$(_GetLastLineFromFile_ "$TheLogFile")"
  242.    if [ -z "$LastLine" ] ; then return 1 ; fi
  243.  
  244.    MarkedLine="$($echoCMD "$LastLine" | grep -c "$(_EscapeChars_ "$DelMark")$")"
  245.  
  246.   if [ "$MarkedLine" -gt 0 ]
  247.   then sed -i '$d' "$TheLogFile" ; fi
  248. }
  249.  
  250. ##################################################################
  251. _AddMsgsToMyLog_()
  252. {
  253.   if [ "$DoMyLogger" -eq 0 ] ; then return 1 ; fi
  254.  
  255.   local TimeNow  HourMinsNow
  256.  
  257.   HourMinsNow="$(date +"%I:%M %p")"
  258.   TimeNow="$(date +"$MyLogTimeFormat")"
  259.  
  260.   if [ $# -eq 0 ]
  261.   then
  262.       echo "" >> "$TheLogFile"
  263.   elif \
  264.      [ $# -eq 1 ]
  265.   then
  266.       echo "$TimeNow $1" >> "$TheLogFile"
  267.   elif \
  268.      [ "$1" = "_NOTIME_" ]
  269.   then
  270.       ## Output *WITHOUT* a TimeStamp ##
  271.       echo "$2" >> "$TheLogFile"
  272.   elif \
  273.      [ "$1" = "_ADDnoMARK_" ] || [ "$1" = "_ADDwithMARK_" ]
  274.   then
  275.       local LogMsg="${TimeNow} ${2}"
  276.  
  277.       _DeleteLastLogFileLineMarked_
  278.  
  279.       if [ "$1" = "_ADDnoMARK_" ] || \
  280.          [ "$HourMinsNow" = "12:00 PM" ]
  281.       then
  282.           ## Output msg WITHOUT being "marked" ##
  283.           echo "$LogMsg" >> "$TheLogFile"
  284.       elif \
  285.          [ "$1" = "_ADDwithMARK_" ]
  286.       then
  287.           ## Output "MARKED" msg (to be deleted later) ##
  288.           $echoCMD "$LogMsg $DelMark" >> "$TheLogFile"
  289.       fi
  290.   else
  291.       echo "$TimeNow ${1}: $2" >> "$TheLogFile"
  292.   fi
  293. }
  294.  
  295. ################################################################
  296. _AddMsgToMyLogNoTime_()
  297. {
  298.   _ShowDebugMsg_ "$1"
  299.   _AddMsgsToMyLog_ "_NOTIME_" "$1"
  300. }
  301.  
  302. ################################################################
  303. _AddMsgsToLogs_()
  304. {
  305.   if [ $# -eq 0 ]
  306.   then
  307.       _AddMsgsToMyLog_
  308.   elif [ $# -eq 1 ]
  309.   then
  310.       _AddMsgsToMyLog_ "$1"
  311.   elif [ $# -eq 2 ]
  312.   then
  313.       _AddMsgsToMyLog_ "$1" "$2"
  314.   fi
  315. }
  316.  
  317. ################################################################
  318. _AddDebugLogMsgs_()
  319. {
  320.   if [ $# -eq 0 ]
  321.   then
  322.       _ShowDebugMsg_
  323.       _AddMsgsToMyLog_
  324.   elif [ $# -eq 1 ]
  325.   then
  326.       _ShowDebugMsg_ "$1"
  327.       _AddMsgsToMyLog_ "$1"
  328.   elif [ $# -eq 2 ]
  329.   then
  330.       _ShowDebugMsg_ "$1" "$2"
  331.       _AddMsgsToMyLog_ "$1" "$2"
  332.   fi
  333. }
  334.  
  335. #################################################################
  336. _ValidCronJobMinutes_()
  337. {
  338.   if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1 ; fi
  339.  
  340.   local RetCode=1
  341.  
  342.   case "$1" in
  343.       [1-6] | 10 | 12 | 15 | 20 | 30 | 60)
  344.          RetCode=0 ;;
  345.       *)
  346.          echo "*ERROR*: INVALID number of minutes [$1] for cron job."
  347.          RetCode=1 ;;
  348.   esac
  349.   return "$RetCode"
  350. }
  351.  
  352. #################################################################
  353. # To avoid using the "cru l" cmd which calls the "nvram" cmd
  354. # which may hang in some cases.
  355. #################################################################
  356. _GetCronJobList_()
  357. {
  358.   local CronJobListFile  CronJobListStr=""
  359.   local CrobTabsDirPath="/var/spool/cron/crontabs"
  360.  
  361.   if [ ! -d "$CrobTabsDirPath" ] ; then echo "" ; return 1 ; fi
  362.  
  363.   CronJobListFile="$(ls -1 "$CrobTabsDirPath" | grep -vE "cron.[*]*|.*.new$")"
  364.   if [ -n "$CronJobListFile" ]
  365.   then
  366.      CronJobListStr="$(cat "${CrobTabsDirPath}/$CronJobListFile")"
  367.   fi
  368.  
  369.   echo "$CronJobListStr"
  370.   return 0
  371. }
  372.  
  373. ##################################################################
  374. _CheckForCronJobSetup_()
  375. {
  376.   if [ "$CRON_Set" -eq 0 ] ; then return 1 ; fi
  377.  
  378.   local CRU_CMD="/usr/sbin/cru"
  379.   local TheCronMins="*"
  380.   local CronMin=""  CronTag=""  JobPath=""  JobStr=""
  381.   local CRU_Tag="#${CRON_Tag}#"  SetCRONjob=0
  382.  
  383.    if [ "$CRON_Mins" -gt 1 ]
  384.    then
  385.       if [ "$CRON_Mins" -eq 60 ]
  386.       then TheCronMins="0"
  387.       else TheCronMins="*/$CRON_Mins"
  388.       fi
  389.    fi
  390.  
  391.    JobStr="$(_GetCronJobList_ | grep " $ScriptFPath ")"
  392.  
  393.    if [ -n "$JobStr" ]
  394.    then
  395.       CronMin="$(echo "$JobStr" | awk -F ' ' '{print $1}')"
  396.       JobPath="$(echo "$JobStr" | awk -F ' ' '{print $6}')"
  397.       CronTag="$(echo "$JobStr" | awk -F ' ' '{print $7}')"
  398.  
  399.       if [ "$CronTag" != "$CRU_Tag" ]     || \
  400.          [ "$CronMin" != "$TheCronMins" ] || \
  401.          [ "$JobPath" != "$ScriptFPath" ]
  402.       then
  403.          CronTag="$(echo "$CronTag" | sed "s/#//g")"
  404.          $CRU_CMD d "$CronTag"
  405.          if [ $? -eq 0 ]
  406.          then
  407.             sleep 1
  408.             SetCRONjob=1
  409.             LogMsg="Previous CRON Job [#${CronTag}#] was DELETED."
  410.             _AddDebugLogMsgs_ "INFO: $LogMsg"
  411.          fi
  412.       else
  413.          LogMsg="The CRON Job [#${CronTag}#] is already FOUND."
  414.          _AddDebugLogMsgs_ "INFO: $LogMsg"
  415.          _AddMsgToMyLogNoTime_ "CRON: [$JobStr]"
  416.       fi
  417.    fi
  418.  
  419.    if [ -z "$JobStr" ] || [ "$SetCRONjob" -eq 1 ]
  420.    then
  421.       $CRU_CMD a $CRON_Tag "$TheCronMins  *  *  *  *  $ScriptFPath"
  422.       if [ $? -eq 0 ]
  423.       then
  424.          sleep 1
  425.          JobStr="$(_GetCronJobList_ | grep " $ScriptFPath ")"
  426.  
  427.          LogMsg="New CRON Job [$CRU_Tag] was CREATED."
  428.          _AddDebugLogMsgs_ "INFO: $LogMsg"
  429.          _AddMsgToMyLogNoTime_ "CRON: [$JobStr]"
  430.       else
  431.          LogMsg="CANNOT create new CRON Job [$CRU_Tag]"
  432.          _AddDebugLogMsgs_ "CRON_ERROR: $LogMsg"
  433.       fi
  434.    fi
  435. }
  436.  
  437. ##################################################################
  438. _ParseCronJobParameter()
  439. {
  440.    if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1 ; fi
  441.  
  442.    local ParamVal=""
  443.    local ParamStr="$(echo "$1" | grep "^-setcronjob")"
  444.  
  445.    if [ -z "$ParamStr" ] ; then return 1 ; fi
  446.  
  447.    ParamVal="$(echo "$ParamStr" | grep "=[0-9]\{1,2\}$" | awk -F '=' '{print $2}')"
  448.  
  449.    if [ -n "$ParamVal" ]
  450.    then
  451.       if _ValidCronJobMinutes_ "$ParamVal"
  452.       then CRON_Mins=$ParamVal
  453.       else return 1
  454.       fi
  455.    fi
  456.  
  457.    CRON_Set=1
  458.    _CheckForCronJobSetup_
  459. }
  460.  
  461. _DoInitMyLogFile_
  462.  
  463. if [ $# -gt 0 ] && [ -n "$1" ] && [ -z "${1##*-setcronjob*}" ]
  464. then _ParseCronJobParameter "$1" ; fi
  465.  
  466. ProcCount=0
  467. RecheckStuckCmds=0
  468.  
  469. ProcList=""
  470. ProcEntry1=""
  471. ProcEntryN=""
  472.  
  473. ## Look for 'nvram' or 'wl' commands ##
  474. grepExcept0="grep -w -E nvram|wl"
  475. grepSearch0="grep -w -E 'nvram|wl'"
  476.  
  477. ## Sort PIDs in descending order (from high to low) ##
  478. SortPIDs="sort -n -r -t ' ' -k 1"
  479. FindProcs="top -b -n 1 | $grepSearch0"
  480.  
  481. ##################################################################
  482. _GetTraceFileIndexNumber_()
  483. {
  484.    local TraceIndex  NextTraceIndex
  485.  
  486.    if [ ! -f "$StuckCmdsNDXfile" ]
  487.    then echo "TraceIndex=1" > "$StuckCmdsNDXfile" ; fi
  488.  
  489.    TraceIndex="$(grep "^TraceIndex=" "$StuckCmdsNDXfile" | awk -F '=' '{print $2}')"
  490.  
  491.    if [ -z "$TraceIndex" ] || [ "$TraceIndex" -lt 1 ]
  492.    then TraceIndex=1 ; fi
  493.  
  494.    NextTraceIndex="$(($TraceIndex + 1))"
  495.    if [ "$NextTraceIndex" -gt "$MaxTraceIndex" ]
  496.    then NextTraceIndex=1 ; fi
  497.  
  498.    echo "## Next Trace File Index ##" > "$StuckCmdsNDXfile"
  499.    echo "TraceIndex=$NextTraceIndex" >> "$StuckCmdsNDXfile"
  500.  
  501.    TraceIndex="$(printf "%05d" "$TraceIndex")"
  502.  
  503.    echo "$TraceIndex"
  504. }
  505.  
  506. ##################################################################
  507. _GetTraceFilePath_()
  508. {
  509.    local TraceFName  TraceIndex
  510.    TraceIndex="$(_GetTraceFileIndexNumber_)"
  511.    TraceFName="${StuckCmdsLOGname}_${TraceIndex}_${thePID}.TRC.txt"
  512.    echo "${TheTRCdir}/${TraceFName}"
  513. }
  514.  
  515. ##################################################################
  516. _ResetStuckProcessCmdsFile_()
  517. {
  518.    if [ -f "$StuckCmdsLOGfile" ]
  519.    then
  520.       local TraceFilePath=""
  521.       TraceFilePath="$(_GetTraceFilePath_)"
  522.       cp -fp "$StuckCmdsLOGfile" "$TraceFilePath"
  523.       rm -f "$StuckCmdsLOGfile"
  524.    fi
  525. }
  526.  
  527. ##################################################################
  528. _ShowParentProcEntry_()
  529. {
  530.    local ProcEntry  ProcCPID  ProcPPID
  531.    local CPID_List=""  PPID_List=""  PPIDfind
  532.  
  533.    while read -r ProcEntry
  534.    do
  535.       ProcCPID="$(echo $ProcEntry | awk -F ' ' '{print $1}')"
  536.       ProcPPID="$(echo $ProcEntry | awk -F ' ' '{print $2}')"
  537.  
  538.       if [ -z "$CPID_List"  ]
  539.       then CPID_List="$ProcCPID"
  540.       else CPID_List="$CPID_List $ProcCPID"
  541.       fi
  542.  
  543.       if [ -z "$PPID_List"  ]
  544.       then PPID_List="$ProcPPID"
  545.       else
  546.          PPIDfind="$(echo "$PPID_List" | grep -cw "$ProcPPID")"
  547.          if [ $PPIDfind -eq 0 ]
  548.          then PPID_List="$PPID_List $ProcPPID" ; fi
  549.       fi
  550.    done <<EOT
  551. $(echo "$1")
  552. EOT
  553.  
  554.    local NumCnt=1  ProcEntryX=""  MaxCnt=0
  555.    MaxCnt="$(echo "$PPID_List" | wc -w)"
  556.  
  557.    while [ "$NumCnt" -le "$MaxCnt" ]
  558.    do
  559.       ProcPPID="$(echo "$PPID_List" | cut -d ' ' -f $NumCnt)"
  560.       PPIDfind="$(echo "$CPID_List" | grep -cw "$ProcPPID")"
  561.  
  562.       if [ "$ProcPPID" -gt 1 ] && [ "$PPIDfind" -eq 0 ]
  563.       then
  564.          ProcEntry="$(top -b -n 1 | grep -w "^[ ]*$ProcPPID")"
  565.  
  566.          if [ -n "$ProcEntry" ]
  567.          then
  568.             _AddMsgToMyLogNoTime_ "$ProcEntry"
  569.  
  570.             if [ -z "$ProcEntryX" ]
  571.             then ProcEntryX="$ProcEntry"
  572.             else ProcEntryX="$(printf "%s\n%s\n" "$ProcEntryX" "$ProcEntry")"
  573.             fi
  574.          fi
  575.       fi
  576.  
  577.       NumCnt=$(($NumCnt + 1))
  578.    done
  579.  
  580.    if [ -n "$ProcEntryX" ]
  581.    then
  582.       ProcList="$(printf "%s\n%s\n" "$ProcList" "$ProcEntryX")"
  583.       _ShowParentProcEntry_ "$ProcEntryX"
  584.    fi
  585. }
  586.  
  587. ##################################################################
  588. _InsertListOfPIDs_()
  589. {
  590.    local ProcEntry  NumCnt=1
  591.    while IFS= read -r ProcEntry
  592.    do
  593.       sed -i "$NumCnt i $1 $ProcEntry" "$StuckCmdsLOGfile"
  594.       NumCnt=$(($NumCnt + 1))
  595.    done <<EOT
  596. $(echo "$2")
  597. EOT
  598. }
  599.  
  600. ##################################################################
  601. _StuckProcessCmdsRunning_()
  602. {
  603.    ProcCount="$(eval $FindProcs | grep -cv "$grepExcept0")"
  604.  
  605.    if [ "$ProcCount" -gt 0 ] && [ $# -eq 0 ]
  606.    then
  607.       sleep 3   ## Let's wait some time to double check ##
  608.       ProcCount="$(eval $FindProcs | grep -cv "$grepExcept0")"
  609.    fi
  610.  
  611.    if [ "$ProcCount" -eq 0 ]
  612.    then LogMsg="FOUND: [$ProcCount]"
  613.    else LogMsg="FOUND_${thePID}: [$ProcCount]"
  614.    fi
  615.    _ShowDebugMsg_ "$LogMsg"
  616.  
  617.    if [ $# -eq 1 ] && [ "$1" = "-ShowMsg" ]
  618.    then
  619.        _AddMsgsToMyLog_ "_ADDnoMARK_" "$LogMsg"
  620.    elif \
  621.       [ "$ProcCount" -eq 0 ]
  622.    then
  623.        _AddMsgsToMyLog_ "_ADDwithMARK_" "$LogMsg"
  624.    fi
  625.  
  626.    if [ "$ProcCount" -gt 0 ] ; then return 0 ; fi
  627.    return 1
  628. }
  629.  
  630. ##################################################################
  631. _GetStuckProcessCmds_()
  632. {
  633.    local ProcState="?"
  634.    ProcEntry1=""  ProcEntryN=""  ProcList=""
  635.    ProcCount="$(eval $FindProcs | grep -cv "$grepExcept0")"
  636.  
  637.    if [ "$ProcCount" -gt 0 ]
  638.    then
  639.       ProcEntry1="$(eval $FindProcs | eval $SortPIDs | \
  640.                    grep -m 1 -v "$grepExcept0")"
  641.  
  642.       ProcEntryN="$(eval $FindProcs | eval $SortPIDs | \
  643.                    grep -m $ProcCount -v "$grepExcept0")"
  644.  
  645.       ProcState="$(echo "$ProcEntry1" | awk -F ' ' '{print $4}')"
  646.  
  647.       if [ "$ProcState" != "S" ] && [ "$ProcState" != "Z" ]
  648.       then ProcEntry1="" ; fi
  649.    fi
  650.  
  651.    if [ "$ProcCount" -eq 0 ] || [ -z "$ProcEntry1" ]
  652.    then
  653.       LogMsg="FOUND_${thePID}: [$ProcCount][$ProcState]"
  654.       _AddMsgsToMyLog_ "_ADDnoMARK_" "$LogMsg"
  655.    fi
  656. }
  657.  
  658. ##################################################################
  659. _SaveStuckProcessCmds_()
  660. {
  661.    local ProcXPID  ProcPPID  KillEntryLog
  662.    local NowTimeSecs  LastTimeSecs  TimeDiffSecs
  663.    local ProcFound  ProcStrX  ProcStrN  LastTime  CmdState
  664.  
  665.    _GetStuckProcessCmds_
  666.  
  667.    if [ -n "$ProcEntry1" ] && [ -n "$ProcEntryN" ]
  668.    then
  669.       ProcList="$ProcEntryN"
  670.       NowTime="$(date +"$SysLogTimeFormat")"
  671.  
  672.       _AddMsgToMyLogNoTime_ "$ProcEntryN"
  673.       _ShowParentProcEntry_ "$ProcEntryN"
  674.  
  675.       if [ ! -f "$StuckCmdsLOGfile" ]
  676.       then echo -n " " > "$StuckCmdsLOGfile" ; fi
  677.  
  678.       ProcStrX="$(_EscapeChars_ "$ProcEntry1")"
  679.       ProcFound="$(grep -c "${ProcStrX}$" "$StuckCmdsLOGfile")"
  680.  
  681.       LogMsg="FOUND_${thePID}: [$ProcFound][$ProcEntry1]"
  682.       _AddDebugLogMsgs_ "$LogMsg"
  683.  
  684.       if [ "$ProcFound" -eq 0 ]
  685.       then
  686.          _InsertListOfPIDs_ "$NowTime" "$ProcList"
  687.          RecheckStuckCmds=0
  688.       fi
  689.  
  690.       if [ "$ProcFound" -gt 0 ] && [ "$UseKillCmd" -eq 1 ]
  691.       then
  692.          ProcStrN="$(grep -m 1 "${ProcStrX}$" "$StuckCmdsLOGfile")"
  693.  
  694.          if [ -n "$ProcStrN" ]
  695.          then
  696.             LastTime="$(echo "$ProcStrN" | awk -F ' ' '{print $1,$2}')"
  697.             ProcXPID="$(echo "$ProcStrN" | awk -F ' ' '{print $3}')"
  698.             ProcPPID="$(echo "$ProcStrN" | awk -F ' ' '{print $4}')"
  699.             CmdState="$(echo "$ProcStrN" | awk -F ' ' '{print $6}')"
  700.  
  701.             NowTimeSecs=$(date +%s -d "${NowTime}")
  702.             LastTimeSecs=$(date +%s -d "${LastTime}")
  703.             TimeDiffSecs=$(($NowTimeSecs - $LastTimeSecs))
  704.             KillEntryLog="$NowTime ${ProcEntry1} [KILLED]"
  705.  
  706.             if [ "$TimeDiffSecs" -ge "$MaxDiffSecs" ]
  707.             then
  708.                LogMsg="PID_${thePID}: [$ProcXPID][$ProcPPID], [$TimeDiffSecs >= $MaxDiffSecs] secs."
  709.                _AddDebugLogMsgs_ "$LogMsg"
  710.  
  711.                if [ -n "$ProcXPID" ] && [ -n "$ProcPPID" ] && \
  712.                   { [ "$CmdState" = "S" ] || [ "$CmdState" = "Z" ] ; }
  713.                then
  714.                   if [ "$CmdState" = "Z" ]
  715.                   then
  716.                      kill -9 $ProcPPID
  717.                      LogMsg="[kill -9 $ProcPPID][$?]"
  718.                   fi
  719.                   if [ "$CmdState" = "S" ]
  720.                   then
  721.                      kill -9 $ProcXPID
  722.                      LogMsg="[kill -9 $ProcXPID][$?]"
  723.                   fi
  724.                   _AddDebugLogMsgs_ "CMD_${thePID}: $LogMsg"
  725.                   sed -i "1 i $KillEntryLog" "$StuckCmdsLOGfile"
  726.                   sleep 2
  727.                   RecheckStuckCmds=1
  728.                fi
  729.             else
  730.                LogMsg="PID_${thePID}: [$ProcXPID], [$TimeDiffSecs < $MaxDiffSecs] secs."
  731.                _AddDebugLogMsgs_ "$LogMsg"
  732.             fi
  733.          fi
  734.       fi
  735.       return 0
  736.    fi
  737.    return 1
  738. }
  739.  
  740. #################################
  741. # Initial Quick Check & Exit.
  742. #-------------------------------#
  743. if ! _StuckProcessCmdsRunning_
  744. then
  745.    _ResetStuckProcessCmdsFile_
  746.    exit 0
  747. fi
  748.  
  749. if ! _LastLogFileLineEmpty_
  750. then echo "" >> "$TheLogFile" ; fi
  751.  
  752. _AddDebugLogMsgs_ "START_$thePID" "[$0]"
  753.  
  754. if [ -n "$*" ]
  755. then _AddDebugLogMsgs_ "ARGs_${thePID}: [$*]" ; fi
  756.  
  757. ############################################
  758. if _StuckProcessCmdsRunning_ "-ShowMsg"
  759. then
  760.    _SaveStuckProcessCmds_
  761.  
  762.    if _StuckProcessCmdsRunning_ "-ShowMsg" && \
  763.       { [ "$ProcCount" -lt 4 ] || \
  764.         [ "$(pidof "$ScriptFName1" | wc -w)" -lt 3 ] ; }
  765.    then $ScriptFPath -setdelay &
  766.    fi
  767.  
  768.    if [ "$RecheckStuckCmds" -eq 1 ] && \
  769.       ! _StuckProcessCmdsRunning_ "-ShowMsg"
  770.    then _ResetStuckProcessCmdsFile_ ; fi
  771. else
  772.    _ResetStuckProcessCmdsFile_
  773. fi
  774.  
  775. _AddDebugLogMsgs_ "EXIT_$thePID" "OK."
  776. _AddDebugLogMsgs_
  777.  
  778. exit 0
  779.  
  780. #EOF#
  781.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement