Skip to content

Commit 767770f

Browse files
Merge pull request #577 from ExtremeFiretop/Gnuton-Mount-Point
Fix Multiple GNUton Mount Points
2 parents 5f9e593 + a42d4ac commit 767770f

3 files changed

Lines changed: 161 additions & 30 deletions

File tree

MerlinAU.sh

Lines changed: 158 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
set -u
1010

1111
## Set version for each Production Release ##
12-
readonly SCRIPT_VERSION=1.6.3
13-
readonly SCRIPT_VERSTAG="26052123"
12+
readonly SCRIPT_VERSION=1.6.4
13+
readonly SCRIPT_VERSTAG="26061019"
1414
readonly SCRIPT_NAME="MerlinAU"
1515
## Set to "master" for Production Releases ##
1616
SCRIPT_BRANCH="master"
@@ -546,6 +546,12 @@ fwupMutexFLock_FD=576
546546
fwupMutexFLock_FN="/tmp/var/${ScriptFNameTag}_FW_Update.FLock"
547547
fwupMutexFLock_OK=false #DO NOT have FLock#
548548

549+
##-------------------------------------##
550+
## Added for initialization operations ##
551+
##-------------------------------------##
552+
initMutexFLock_FD=577
553+
initMutexFLock_FN="/tmp/var/${ScriptFNameTag}_Initialization.FLock"
554+
549555
_ReleaseMutexFLock_()
550556
{
551557
if [ $# -gt 0 ] && \
@@ -2217,30 +2223,45 @@ readonly POST_REBOOT_SCRIPT_HOOK="[ -x $ScriptFilePath ] && $POST_REBOOT_SCRIPT_
22172223
readonly POST_UPDATE_EMAIL_SCRIPT_JOB="$ScriptFilePath postUpdateEmail &"
22182224
readonly POST_UPDATE_EMAIL_SCRIPT_HOOK="[ -x $ScriptFilePath ] && $POST_UPDATE_EMAIL_SCRIPT_JOB $hookScriptTagStr"
22192225

2220-
##-------------------------------------##
2221-
## Added by Martinski W. [2026-Feb-07] ##
2222-
##-------------------------------------##
2226+
##------------------------------------------##
2227+
## Modified by ExtremeFiretop [2026-Jun-10] ##
2228+
##------------------------------------------##
22232229
_CleanUpOldLogFiles_()
22242230
{
22252231
[ ! -d "$FW_LOG_DIR" ] && return 1
2226-
local numLogFiles topLogFile
2232+
local numLogFiles topFile savedTopFile
22272233

22282234
numLogFiles="$(ls -1lt "$FW_LOG_DIR"/*.log 2>/dev/null | wc -l)"
22292235
# Leave one log file (if any available) #
22302236
[ "$numLogFiles" -lt 2 ] && return 0
22312237

22322238
# Save the most recent log file #
22332239
topFile="$(ls -1t "$FW_LOG_DIR"/*.log 2>/dev/null | head -n1)"
2234-
[ -n "$topFile" ] && mv -f "$topFile" "${topFile}.SAVED.TEMP.LOG"
2240+
2241+
if [ -n "$topFile" ]
2242+
then
2243+
savedTopFile="${topFile}.SAVED.$$.TEMP.LOG"
2244+
2245+
if ! mv -f "$topFile" "$savedTopFile"
2246+
then
2247+
return 1
2248+
fi
2249+
fi
22352250

22362251
# Delete logs older than 30 days #
22372252
/usr/bin/find -L "$FW_LOG_DIR" -name '*.log' -mtime +30 -exec rm {} \;
22382253

22392254
# Restore the most recent log file #
2240-
[ -n "$topFile" ] && mv -f "${topFile}.SAVED.TEMP.LOG" "$topFile"
2241-
}
2255+
if [ -n "$topFile" ] && [ -f "$savedTopFile" ]
2256+
then
2257+
if ! mv -f "$savedTopFile" "$topFile"
2258+
then
2259+
return 1
2260+
fi
2261+
fi
22422262

2243-
_CleanUpOldLogFiles_
2263+
return 0
2264+
}
22442265

22452266
##----------------------------------------##
22462267
## Modified by Martinski W. [2024-Jan-27] ##
@@ -2860,7 +2881,7 @@ _CurlFileDownload_()
28602881
then return 1
28612882
fi
28622883
local retCode=1
2863-
local tempFilePathDL="${2}.DL.TMP"
2884+
local tempFilePathDL="${2}.DL.$$.TMP"
28642885
local srceFilePathDL="${SCRIPT_URL_REPO}/$1"
28652886

28662887
curl -LSs --retry 4 --retry-delay 5 --retry-connrefused \
@@ -2877,7 +2898,11 @@ _CurlFileDownload_()
28772898
then updatedWebUIPage=true
28782899
else updatedWebUIPage=false
28792900
fi
2880-
mv -f "$tempFilePathDL" "$2"
2901+
if ! mv -f "$tempFilePathDL" "$2"
2902+
then
2903+
rm -f "$tempFilePathDL"
2904+
return 1
2905+
fi
28812906
retCode=0
28822907
fi
28832908

@@ -12032,9 +12057,9 @@ _DoInitializationStartup_()
1203212057
_SetDefaultBuildType_
1203312058
}
1203412059

12035-
##----------------------------------------##
12036-
## Modified by Martinski W. [2025-Jul-29] ##
12037-
##----------------------------------------##
12060+
##------------------------------------------##
12061+
## Modified by ExtremeFiretop [2026-Jun-10] ##
12062+
##------------------------------------------##
1203812063
#######################################################################
1203912064
# TEMPORARY hack to check if the Gnuton F/W built-in 'webs_update.sh'
1204012065
# script is the most recent version that includes required fixes.
@@ -12054,8 +12079,8 @@ _Gnuton_Check_Webs_Update_Script_()
1205412079

1205512080
local theWebsUpdateFile="webs_update.sh"
1205612081
local fixedGnutonWebsUpdateFilePath="${SETTINGS_DIR}/$theWebsUpdateFile"
12057-
local dwnldGnutonWebsUpdateFilePath="${SETTINGS_DIR}/${theWebsUpdateFile}.GNUTON"
12058-
local localVersTag remoteVersTag
12082+
local dwnldGnutonWebsUpdateFilePath="${SETTINGS_DIR}/${theWebsUpdateFile}.GNUTON.$$"
12083+
local localVersTag remoteVersTag diffRC
1205912084

1206012085
# Get local VERSTAG (if any) #
1206112086
localVersTag="$(_Get_GnutonWebUpdate_ScriptVersTag_ "$FW_UpdateCheckScript")"
@@ -12064,35 +12089,137 @@ _Gnuton_Check_Webs_Update_Script_()
1206412089
# Get the fixed version of the script targeted for Gnuton F/W #
1206512090
if _CurlFileDownload_ "gnuton_webs_update.sh" "$dwnldGnutonWebsUpdateFilePath"
1206612091
then
12067-
chmod 755 "$dwnldGnutonWebsUpdateFilePath"
12092+
if ! chmod 755 "$dwnldGnutonWebsUpdateFilePath"
12093+
then
12094+
Say "${REDct}**ERROR**${NOct}: Unable to set permissions on the downloaded GNUton webs_update.sh file."
12095+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12096+
return 1
12097+
fi
12098+
1206812099
remoteVersTag="$(_Get_GnutonWebUpdate_ScriptVersTag_ "$dwnldGnutonWebsUpdateFilePath")"
1206912100
[ -z "$remoteVersTag" ] && remoteVersTag=0
1207012101
else
12071-
return 1 #NOT available so do nothing#
12102+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12103+
return 1
12104+
fi
12105+
12106+
# Distinguish files that differ from an actual comparison error.
12107+
diff -q "$FW_UpdateCheckScript" "$dwnldGnutonWebsUpdateFilePath" >/dev/null 2>&1
12108+
12109+
diffRC=$?
12110+
12111+
if [ "$diffRC" -gt 1 ]
12112+
then
12113+
Say "${REDct}**ERROR**${NOct}: Unable to compare the GNUton webs_update.sh files."
12114+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12115+
return 1
1207212116
fi
1207312117

1207412118
# (Re)bind/mount only if remote is newer version OR files differ #
1207512119
if [ "$remoteVersTag" -gt "$localVersTag" ] || \
12076-
! diff -q "$FW_UpdateCheckScript" "$dwnldGnutonWebsUpdateFilePath" >/dev/null 2>&1
12120+
[ "$diffRC" -eq 1 ]
1207712121
then
12078-
umount "$FW_UpdateCheckScript" 2>/dev/null
12079-
mv -f "$dwnldGnutonWebsUpdateFilePath" "$fixedGnutonWebsUpdateFilePath"
12080-
mount -o bind "$fixedGnutonWebsUpdateFilePath" "$FW_UpdateCheckScript"
12122+
# Remove all existing bind-mount layers, including duplicates.
12123+
while awk -v target="$FW_UpdateCheckScript" '
12124+
$2 == target { found=1 }
12125+
END { exit !found }
12126+
' /proc/mounts
12127+
do
12128+
if ! umount "$FW_UpdateCheckScript"
12129+
then
12130+
Say "${REDct}**ERROR**${NOct}: Unable to unmount \"$FW_UpdateCheckScript\"."
12131+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12132+
return 1
12133+
fi
12134+
done
12135+
12136+
if ! mv -f "$dwnldGnutonWebsUpdateFilePath" "$fixedGnutonWebsUpdateFilePath"
12137+
then
12138+
Say "${REDct}**ERROR**${NOct}: Unable to install the fixed GNUton webs_update.sh file."
12139+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12140+
return 1
12141+
fi
12142+
12143+
if [ ! -f "$fixedGnutonWebsUpdateFilePath" ]
12144+
then
12145+
Say "${REDct}**ERROR**${NOct}: GNUton webs_update.sh source file is missing before bind mount."
12146+
return 1
12147+
fi
12148+
12149+
if [ ! -e "$FW_UpdateCheckScript" ]
12150+
then
12151+
Say "${REDct}**ERROR**${NOct}: Bind-mount target \"$FW_UpdateCheckScript\" does not exist."
12152+
return 1
12153+
fi
12154+
12155+
if ! mount -o bind \
12156+
"$fixedGnutonWebsUpdateFilePath" \
12157+
"$FW_UpdateCheckScript"
12158+
then
12159+
Say "${REDct}**ERROR**${NOct}: Unable to bind-mount the fixed GNUton webs_update.sh file."
12160+
return 1
12161+
fi
12162+
1208112163
Say "${YLWct}Set up a fixed version of the \"${theWebsUpdateFile}\" script file.${NOct}"
1208212164
else
1208312165
rm -f "$dwnldGnutonWebsUpdateFilePath"
1208412166
fi
12167+
12168+
return 0
1208512169
}
1208612170

12171+
##---------------------------------------##
12172+
## Added by ExtremeFiretop [2026-Jun-10] ##
12173+
##---------------------------------------##
12174+
# Serialize startup-time operations that use shared log and GNUton files.
12175+
_RunLockedInitializationChecks_()
12176+
{
12177+
local retCode=0
12178+
12179+
[ ! -d /tmp/var ] && mkdir -p /tmp/var
12180+
12181+
# Open the dedicated lock file on its own file descriptor.
12182+
if ! eval "exec ${initMutexFLock_FD}>\"${initMutexFLock_FN}\""
12183+
then
12184+
Say "${REDct}**ERROR**${NOct}: Unable to open the initialization lock file."
12185+
return 1
12186+
fi
12187+
12188+
# Use a blocking exclusive lock so concurrent MerlinAU processes wait.
12189+
if ! flock -x "$initMutexFLock_FD" 2>/dev/null
12190+
then
12191+
Say "${REDct}**ERROR**${NOct}: Unable to acquire the initialization lock."
12192+
eval "exec ${initMutexFLock_FD}>&-"
12193+
return 1
12194+
fi
12195+
12196+
# These operations access shared paths and must not overlap.
12197+
if [ -d "$FW_LOG_DIR" ] && \
12198+
! _CleanUpOldLogFiles_
12199+
then
12200+
Say "${YLWct}WARNING:${NOct} Unable to clean up old firmware-update log files."
12201+
retCode=1
12202+
fi
12203+
12204+
checkWebsUpdateScriptForGnuton="$isGNUtonFW"
12205+
if ! _Gnuton_Check_Webs_Update_Script_
12206+
then
12207+
Say "${YLWct}WARNING:${NOct} Unable to check or install the GNUton webs_update.sh patch."
12208+
retCode=1
12209+
fi
12210+
12211+
flock -u "$initMutexFLock_FD" 2>/dev/null
12212+
eval "exec ${initMutexFLock_FD}>&-"
12213+
12214+
return "$retCode"
12215+
}
12216+
12217+
1208712218
if [ "$SCRIPT_BRANCH" = "master" ]
1208812219
then SCRIPT_VERS_INFO=""
1208912220
else SCRIPT_VERS_INFO="[$versionDev_TAG]"
1209012221
fi
1209112222

12092-
## Set variable to 'false' to stop the check ##
12093-
checkWebsUpdateScriptForGnuton="$isGNUtonFW"
12094-
_Gnuton_Check_Webs_Update_Script_
12095-
1209612223
FW_InstalledVersion="$(_GetCurrentFWInstalledLongVersion_)"
1209712224
FW_InstalledVerStr="${GRNct}${FW_InstalledVersion}${NOct}"
1209812225
FW_NewUpdateVerInit=TBD
@@ -12107,6 +12234,8 @@ then
1210712234
then Say "Exiting..." ; exit 1
1210812235
fi
1210912236

12237+
_RunLockedInitializationChecks_
12238+
1211012239
inMenuMode=true
1211112240
_DoInitializationStartup_
1211212241
_CheckFor_VersionFile_
@@ -12134,6 +12263,8 @@ then
1213412263
if ! _AcquireLock_ cliOptsLock
1213512264
then Say "Exiting..." ; exit 1 ; fi
1213612265

12266+
_RunLockedInitializationChecks_
12267+
1213712268
[ "$1" = "amtmupdate" ] && isVerbose=false
1213812269

1213912270
inMenuMode=false

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# MerlinAU - AsusWRT-Merlin Firmware Auto Updater
22

3-
## v1.6.3
4-
## 2026-May-22
3+
## v1.6.4
4+
## 2026-June-10
55

66
## WebUI:
77
<img width="775" height="1640" alt="image" src="https://github.com/user-attachments/assets/846f889b-b39f-4ffe-a37a-8892ad9b2f7f" />

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.6.3
1+
1.6.4

0 commit comments

Comments
 (0)