44#
55# Original Creation Date: 2023-Oct-01 by @ExtremeFiretop.
66# Official Co-Author: @Martinski W. - Date: 2023-Nov-01
7- # Last Modified: 2026-Mar-17
7+ # Last Modified: 2026-Mar-18
88# ##################################################################
99set -u
1010
1111# # Set version for each Production Release ##
1212readonly SCRIPT_VERSION=1.6.0
13- readonly SCRIPT_VERSTAG=" 26031700 "
13+ readonly SCRIPT_VERSTAG=" 26031823 "
1414readonly SCRIPT_NAME=" MerlinAU"
1515# # Set to "master" for Production Releases ##
1616SCRIPT_BRANCH=" dev"
@@ -409,7 +409,7 @@ readonly LockTypeRegEx="(cliMenuLock|cliOptsLock|cliFileLock)"
409409_FindLockFileTypes_ ()
410410{ grep -woE " $LockTypeRegEx " " $LockFilePath " | tr ' \n' ' ' | sed ' s/[ ]*$//' ; }
411411
412- _ReleaseLock_ ()
412+ _ReleaseLock_ ()
413413{
414414 local lockType
415415 if [ $# -eq 0 ] || [ -z " $1 " ]
@@ -421,7 +421,7 @@ _ReleaseLock_()
421421 then
422422 if [ -z " $lockType " ]
423423 then sed -i " /^$$ |/d" " $LockFilePath "
424- else sed -i " /.* |${1} $/d" " $LockFilePath "
424+ else sed -i " /^ $$ |${1} $/d" " $LockFilePath "
425425 fi
426426 [ -s " $LockFilePath " ] && return 0
427427 fi
@@ -476,8 +476,7 @@ _AcquireLock_()
476476 retCode=1
477477 lockTypeFound=" "
478478 waitTimeoutSecs=0
479- savedVerbose=" $isVerbose "
480- isVerbose=true
479+ savedVerbose=" $isVerbose " ; isVerbose=true
481480
482481 while true
483482 do
@@ -531,6 +530,78 @@ _AcquireLock_()
531530 return " $retCode "
532531}
533532
533+ # #-------------------------------------##
534+ # # Added by Martinski W. [2026-Mar-18] ##
535+ # #-------------------------------------##
536+ fwupMutexFLock_FD=576
537+ fwupMutexFLock_FN=" /tmp/var/${ScriptFNameTag} _FW_Update.FLock"
538+ fwupMutexFLock_OK=false # DO NOT have FLock#
539+
540+ _ReleaseMutexFLock_ ()
541+ {
542+ if [ $# -gt 0 ] && \
543+ [ " $1 " = " checkLockOK" ] && \
544+ [ " $fwupMutexFLock_OK " != " true" ]
545+ then return 0
546+ fi
547+
548+ printf ' ' > " $fwupMutexFLock_FN "
549+ flock -u " $fwupMutexFLock_FD " 2> /dev/null
550+ fwupMutexFLock_OK=false
551+ }
552+
553+ # #-------------------------------------##
554+ # # Added by Martinski W. [2026-Mar-18] ##
555+ # #-------------------------------------##
556+ # --------------------------------------------------------------#
557+ # This is a mutually exclusive, non-blocking FLOCK mechanism
558+ # to be used when MerlinAU is perforning a F/W Update so that
559+ # AMTM can check and prevent running automatic script updates
560+ # while the F/W Update is in progress.
561+ # --------------------------------------------------------------#
562+ _AcquireMutexFLock_ ()
563+ {
564+ local retCode savedVerbose
565+ local procInfo procName procIDno procIDof=" "
566+
567+ savedVerbose=" $isVerbose " ; isVerbose=true
568+
569+ if [ -s " $fwupMutexFLock_FN " ]
570+ then
571+ procInfo=" $( head -n1 " $fwupMutexFLock_FN " ) "
572+ procName=" $( echo " $procInfo " | cut -d' |' -f1) "
573+ procIDno=" $( echo " $procInfo " | cut -d' |' -f2) "
574+ if [ -n " $procName " ] && [ -n " $procIDno " ]
575+ then procIDof=" $( pidof " $procName " ) "
576+ fi
577+ if [ -z " $procIDof " ] || \
578+ ! echo " $procIDof " | grep -qow " $procIDno "
579+ then
580+ Say " Stale F/W Update Lock Found. Resetting lock file..."
581+ _ReleaseMutexFLock_
582+ fi
583+ fi
584+
585+ [ ! -s " $fwupMutexFLock_FN " ] && \
586+ eval exec " $fwupMutexFLock_FD >$fwupMutexFLock_FN "
587+
588+ if flock -x -n " $fwupMutexFLock_FD " 2> /dev/null
589+ then
590+ printf " $( basename " $0 " ) |$$ \n" > " $fwupMutexFLock_FN "
591+ retCode=0 ; fwupMutexFLock_OK=true
592+ else
593+ procInfo=" $( head -n1 " $fwupMutexFLock_FN " ) "
594+ if [ -n " $procInfo " ]
595+ then procInfo=" $( echo " $procInfo " | sed ' s/|/, PID=/' ) "
596+ fi
597+ Say " ${REDct} **ERROR**${NOct} : Another process [$procInfo ] has the F/W Update Lock file."
598+ retCode=1 ; fwupMutexFLock_OK=false
599+ fi
600+
601+ isVerbose=" $savedVerbose "
602+ return " $retCode "
603+ }
604+
534605# #-------------------------------------##
535606# # Added by Martinski W. [2025-Sep-01] ##
536607# #-------------------------------------##
@@ -544,7 +615,9 @@ _DoExit_()
544615{
545616 local exitCode=0
546617 [ $# -gt 0 ] && [ -n " $1 " ] && exitCode=" $1 "
547- _ReleaseLock_ ; exit " $exitCode "
618+ _ReleaseLock_
619+ _ReleaseMutexFLock_ checkLockOK
620+ exit " $exitCode "
548621}
549622
550623# #-------------------------------------##
@@ -9126,11 +9199,15 @@ _RunOfflineUpdateNow_()
91269199 FW_DL_FPATH=" ${FW_ZIP_DIR} /${FW_FileName} .${extension} "
91279200 _GnutonBuildSelection_
91289201 fi
9129- if _AcquireLock_ cliFileLock
9202+ if _AcquireLock_ cliFileLock && \
9203+ _AcquireMutexFLock_
91309204 then
91319205 _RunFirmwareUpdateNow_
9132- _ReleaseLock_ cliFileLock
9206+ else
9207+ _WaitForEnterKey_
91339208 fi
9209+ _ReleaseLock_ cliFileLock
9210+ _ReleaseMutexFLock_ checkLockOK
91349211 _ClearOfflineUpdateState_
91359212 else
91369213 _ClearOfflineUpdateState_ 1
@@ -9953,10 +10030,12 @@ _PostRebootRunNow_()
995310030
995410031 Say " END of $logMsg [$curWaitDelaySecs sec.]"
995510032 sleep 30 # # Let's wait a bit & proceed ##
9956- if _AcquireLock_ cliFileLock
10033+ if _AcquireLock_ cliFileLock && \
10034+ _AcquireMutexFLock_
995710035 then
995810036 _RunFirmwareUpdateNow_
995910037 _ReleaseLock_ cliFileLock
10038+ _ReleaseMutexFLock_
996010039 fi
996110040}
996210041
@@ -11615,12 +11694,16 @@ _MainMenu_()
1161511694 HIDE_ROUTER_SECTION=true
1161611695 fi
1161711696 ;;
11618- 1) if _AcquireLock_ cliFileLock
11697+ 1) if _AcquireLock_ cliFileLock && \
11698+ _AcquireMutexFLock_
1161911699 then
1162011700 _RunFirmwareUpdateNow_
11621- _ReleaseLock_ cliFileLock
1162211701 FlashStarted=false
11702+ else
11703+ _WaitForEnterKey_
1162311704 fi
11705+ _ReleaseLock_ cliFileLock
11706+ _ReleaseMutexFLock_ checkLockOK
1162411707 ;;
1162511708 2) _GetLoginCredentials_
1162611709 ;;
@@ -11822,10 +11905,12 @@ then
1182211905
1182311906 case " $1 " in
1182411907 run_now)
11825- if _AcquireLock_ cliFileLock
11908+ if _AcquireLock_ cliFileLock && \
11909+ _AcquireMutexFLock_
1182611910 then
1182711911 _RunFirmwareUpdateNow_
1182811912 _ReleaseLock_ cliFileLock
11913+ _ReleaseMutexFLock_
1182911914 fi
1183011915 ;;
1183111916 processNodes) _ProcessMeshNodes_ false
@@ -11914,7 +11999,8 @@ then
1191411999 ;;
1191512000 " ${SCRIPT_NAME} checkfwupdate" | \
1191612001 " ${SCRIPT_NAME} checkfwupdate_bypassDays" )
11917- if _AcquireLock_ cliFileLock
12002+ if _AcquireLock_ cliFileLock && \
12003+ _AcquireMutexFLock_
1191812004 then
1191912005 if [ " $3 " = " ${SCRIPT_NAME} checkfwupdate_bypassDays" ]
1192012006 then bypassPostponedDays=true
@@ -11923,6 +12009,7 @@ then
1192312009 webguiMode=true
1192412010 _RunFirmwareUpdateNow_
1192512011 _ReleaseLock_ cliFileLock
12012+ _ReleaseMutexFLock_
1192612013 fi
1192712014 ;;
1192812015 " ${SCRIPT_NAME} scrptupdate" | \
0 commit comments