From 35a4b9a860b138bcba36d5c67fd256fe8d724139 Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Wed, 18 Mar 2026 01:54:22 -0700 Subject: [PATCH 1/2] Added F/W Update Lock File Added a mutually exclusive, non-blocking FLOCK mechanism in MerlinAU so that whenever AMTM initiates script updates or MerlinAU starts an F/W Update, each one can check the FLOCK mutex to make sure only one of them can perform its intended operation without "stepping on each other's toes" and avoid any possible corruption of a script update. --- MerlinAU.sh | 87 +++++++++++++++++++++++++++++++++++++++++++++++------ README.md | 2 +- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 5ddaf63..85f19b9 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,13 +4,13 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2026-Mar-17 +# Last Modified: 2026-Mar-18 ################################################################### set -u ## Set version for each Production Release ## readonly SCRIPT_VERSION=1.6.0 -readonly SCRIPT_VERSTAG="26031700" +readonly SCRIPT_VERSTAG="26031800" readonly SCRIPT_NAME="MerlinAU" ## Set to "master" for Production Releases ## SCRIPT_BRANCH="dev" @@ -476,8 +476,7 @@ _AcquireLock_() retCode=1 lockTypeFound="" waitTimeoutSecs=0 - savedVerbose="$isVerbose" - isVerbose=true + savedVerbose="$isVerbose" ; isVerbose=true while true do @@ -531,6 +530,66 @@ _AcquireLock_() return "$retCode" } +##-------------------------------------## +## Added by Martinski W. [2026-Mar-18] ## +##-------------------------------------## +fwupMutexFLock_FD=576 +fwupMutexFLock_FN="/tmp/var/${ScriptFNameTag}_FW_Update.FLock" + +_ReleaseMutexFLock_() +{ + printf '' > "$fwupMutexFLock_FN" + flock -u "$fwupMutexFLock_FD" 2>/dev/null +} + +##-------------------------------------## +## Added by Martinski W. [2026-Mar-18] ## +##-------------------------------------## +#--------------------------------------------------------------# +# This is a mutually exclusive, non-blocking FLOCK mechanism +# to be used when MerlinAU is perforning a F/W Update so that +# AMTM can check and prevent running automatic script updates +# while the F/W Update is in progress. +#--------------------------------------------------------------# +_AcquireMutexFLock_() +{ + local retCode savedVerbose + local procInfo procName="" procIDno="" procIDof="" + + savedVerbose="$isVerbose" ; isVerbose=true + + if [ -s "$fwupMutexFLock_FN" ] + then + procInfo="$(head -n1 "$fwupMutexFLock_FN")" + procName="$(echo "$procInfo" | cut -d'|' -f1)" + procIDno="$(echo "$procInfo" | cut -d'|' -f2)" + if [ -n "$procName" ] && [ -n "$procIDno" ] + then procIDof="$(pidof "$procName")" + fi + if [ -z "$procIDof" ] || ! echo "$procIDof" | grep -qow "$procIDno" + then + Say "Stale F/W Update Lock Found. Resetting lock file..." + _ReleaseMutexFLock_ + fi + fi + + [ ! -s "$fwupMutexFLock_FN" ] && \ + eval exec "$fwupMutexFLock_FD>$fwupMutexFLock_FN" + + if flock -x -n "$fwupMutexFLock_FD" 2>/dev/null + then + printf "$(basename "$0")|$$\n" > "$fwupMutexFLock_FN" + retCode=0 + else + procInfo="$(head -n1 "$fwupMutexFLock_FN")" + Say "${REDct}**ERROR**${NOct}: Another process [$procInfo] has the F/W Update Lock file." + retCode=1 + fi + + isVerbose="$savedVerbose" + return "$retCode" +} + ##-------------------------------------## ## Added by Martinski W. [2025-Sep-01] ## ##-------------------------------------## @@ -9126,10 +9185,12 @@ _RunOfflineUpdateNow_() FW_DL_FPATH="${FW_ZIP_DIR}/${FW_FileName}.${extension}" _GnutonBuildSelection_ fi - if _AcquireLock_ cliFileLock + if _AcquireLock_ cliFileLock && \ + _AcquireMutexFLock_ then _RunFirmwareUpdateNow_ _ReleaseLock_ cliFileLock + _ReleaseMutexFLock_ fi _ClearOfflineUpdateState_ else @@ -9953,10 +10014,12 @@ _PostRebootRunNow_() Say "END of $logMsg [$curWaitDelaySecs sec.]" sleep 30 ## Let's wait a bit & proceed ## - if _AcquireLock_ cliFileLock + if _AcquireLock_ cliFileLock && \ + _AcquireMutexFLock_ then _RunFirmwareUpdateNow_ _ReleaseLock_ cliFileLock + _ReleaseMutexFLock_ fi } @@ -11615,10 +11678,12 @@ _MainMenu_() HIDE_ROUTER_SECTION=true fi ;; - 1) if _AcquireLock_ cliFileLock + 1) if _AcquireLock_ cliFileLock && \ + _AcquireMutexFLock_ then _RunFirmwareUpdateNow_ _ReleaseLock_ cliFileLock + _ReleaseMutexFLock_ FlashStarted=false fi ;; @@ -11822,10 +11887,12 @@ then case "$1" in run_now) - if _AcquireLock_ cliFileLock + if _AcquireLock_ cliFileLock && \ + _AcquireMutexFLock_ then _RunFirmwareUpdateNow_ _ReleaseLock_ cliFileLock + _ReleaseMutexFLock_ fi ;; processNodes) _ProcessMeshNodes_ false @@ -11914,7 +11981,8 @@ then ;; "${SCRIPT_NAME}checkfwupdate" | \ "${SCRIPT_NAME}checkfwupdate_bypassDays") - if _AcquireLock_ cliFileLock + if _AcquireLock_ cliFileLock && \ + _AcquireMutexFLock_ then if [ "$3" = "${SCRIPT_NAME}checkfwupdate_bypassDays" ] then bypassPostponedDays=true @@ -11923,6 +11991,7 @@ then webguiMode=true _RunFirmwareUpdateNow_ _ReleaseLock_ cliFileLock + _ReleaseMutexFLock_ fi ;; "${SCRIPT_NAME}scrptupdate" | \ diff --git a/README.md b/README.md index c1eb7be..133867b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MerlinAU - AsusWRT-Merlin Firmware Auto Updater ## v1.6.0 -## 2026-Mar-17 +## 2026-Mar-18 ## WebUI: ![image](https://github.com/user-attachments/assets/9c1dff99-9c13-491b-a7fa-aff924d5f02e) From 4bb2e9996f0056aa9b9f94e29f8c28d906dc837e Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Wed, 18 Mar 2026 23:48:04 -0700 Subject: [PATCH 2/2] Fine-Tuning & Improvements WRT the FLock Just some code improvements and fine-tuning WRT the FLock mechanism. --- MerlinAU.sh | 42 ++++++++++++++++++++++++++++++------------ README.md | 2 +- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 85f19b9..e5bd398 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -10,7 +10,7 @@ set -u ## Set version for each Production Release ## readonly SCRIPT_VERSION=1.6.0 -readonly SCRIPT_VERSTAG="26031800" +readonly SCRIPT_VERSTAG="26031823" readonly SCRIPT_NAME="MerlinAU" ## Set to "master" for Production Releases ## SCRIPT_BRANCH="dev" @@ -409,7 +409,7 @@ readonly LockTypeRegEx="(cliMenuLock|cliOptsLock|cliFileLock)" _FindLockFileTypes_() { grep -woE "$LockTypeRegEx" "$LockFilePath" | tr '\n' ' ' | sed 's/[ ]*$//' ; } -_ReleaseLock_() +_ReleaseLock_() { local lockType if [ $# -eq 0 ] || [ -z "$1" ] @@ -421,7 +421,7 @@ _ReleaseLock_() then if [ -z "$lockType" ] then sed -i "/^$$|/d" "$LockFilePath" - else sed -i "/.*|${1}$/d" "$LockFilePath" + else sed -i "/^$$|${1}$/d" "$LockFilePath" fi [ -s "$LockFilePath" ] && return 0 fi @@ -535,11 +535,19 @@ _AcquireLock_() ##-------------------------------------## fwupMutexFLock_FD=576 fwupMutexFLock_FN="/tmp/var/${ScriptFNameTag}_FW_Update.FLock" +fwupMutexFLock_OK=false #DO NOT have FLock# _ReleaseMutexFLock_() { + if [ $# -gt 0 ] && \ + [ "$1" = "checkLockOK" ] && \ + [ "$fwupMutexFLock_OK" != "true" ] + then return 0 + fi + printf '' > "$fwupMutexFLock_FN" flock -u "$fwupMutexFLock_FD" 2>/dev/null + fwupMutexFLock_OK=false } ##-------------------------------------## @@ -554,7 +562,7 @@ _ReleaseMutexFLock_() _AcquireMutexFLock_() { local retCode savedVerbose - local procInfo procName="" procIDno="" procIDof="" + local procInfo procName procIDno procIDof="" savedVerbose="$isVerbose" ; isVerbose=true @@ -566,7 +574,8 @@ _AcquireMutexFLock_() if [ -n "$procName" ] && [ -n "$procIDno" ] then procIDof="$(pidof "$procName")" fi - if [ -z "$procIDof" ] || ! echo "$procIDof" | grep -qow "$procIDno" + if [ -z "$procIDof" ] || \ + ! echo "$procIDof" | grep -qow "$procIDno" then Say "Stale F/W Update Lock Found. Resetting lock file..." _ReleaseMutexFLock_ @@ -579,11 +588,14 @@ _AcquireMutexFLock_() if flock -x -n "$fwupMutexFLock_FD" 2>/dev/null then printf "$(basename "$0")|$$\n" > "$fwupMutexFLock_FN" - retCode=0 + retCode=0 ; fwupMutexFLock_OK=true else procInfo="$(head -n1 "$fwupMutexFLock_FN")" + if [ -n "$procInfo" ] + then procInfo="$(echo "$procInfo" | sed 's/|/, PID=/')" + fi Say "${REDct}**ERROR**${NOct}: Another process [$procInfo] has the F/W Update Lock file." - retCode=1 + retCode=1 ; fwupMutexFLock_OK=false fi isVerbose="$savedVerbose" @@ -603,7 +615,9 @@ _DoExit_() { local exitCode=0 [ $# -gt 0 ] && [ -n "$1" ] && exitCode="$1" - _ReleaseLock_ ; exit "$exitCode" + _ReleaseLock_ + _ReleaseMutexFLock_ checkLockOK + exit "$exitCode" } ##-------------------------------------## @@ -9189,9 +9203,11 @@ _RunOfflineUpdateNow_() _AcquireMutexFLock_ then _RunFirmwareUpdateNow_ - _ReleaseLock_ cliFileLock - _ReleaseMutexFLock_ + else + _WaitForEnterKey_ fi + _ReleaseLock_ cliFileLock + _ReleaseMutexFLock_ checkLockOK _ClearOfflineUpdateState_ else _ClearOfflineUpdateState_ 1 @@ -11682,10 +11698,12 @@ _MainMenu_() _AcquireMutexFLock_ then _RunFirmwareUpdateNow_ - _ReleaseLock_ cliFileLock - _ReleaseMutexFLock_ FlashStarted=false + else + _WaitForEnterKey_ fi + _ReleaseLock_ cliFileLock + _ReleaseMutexFLock_ checkLockOK ;; 2) _GetLoginCredentials_ ;; diff --git a/README.md b/README.md index 133867b..6aa619f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MerlinAU - AsusWRT-Merlin Firmware Auto Updater ## v1.6.0 -## 2026-Mar-18 +## 2026-Mar-19 ## WebUI: ![image](https://github.com/user-attachments/assets/9c1dff99-9c13-491b-a7fa-aff924d5f02e)