From edd6936903652a6f16eaa5710e3312c686e977af Mon Sep 17 00:00:00 2001 From: Xiaoyi Date: Sat, 11 Jul 2026 15:41:46 +0800 Subject: [PATCH 1/3] core: store naked core on compressed rom instead of unpacking to tmpfs On OpenWrt $TMPDIR is tmpfs (RAM) and $BINDIR sits on a transparently-compressed fs (squashfs/ubifs). Unpacking the core to $TMPDIR pins the whole ~40MB binary in unreclaimable Shmem, and a compressed copy is still kept on rom - paying twice. When $TMPDIR is tmpfs and $BINDIR is squashfs/ubifs/overlay, store the verified naked binary as $BINDIR/CrashCore.raw and symlink $TMPDIR/CrashCore to it, dropping the downloaded archive. The binary is transparently compressed on rom (~2.2:1, comparable to keeping .gz) and its text/rodata become file-backed and reclaimable at runtime (RssShmem 0). Other filesystems keep the existing behavior. The upx branch's symlink target is also corrected from $TMPDIR to $BINDIR (same dangling-symlink issue as #1295). For #1304 --- scripts/libs/core_tools.sh | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/scripts/libs/core_tools.sh b/scripts/libs/core_tools.sh index e2ed523b5..bc553f8e4 100644 --- a/scripts/libs/core_tools.sh +++ b/scripts/libs/core_tools.sh @@ -14,6 +14,8 @@ core_unzip() { #$1:需要解压的文件 $2:目标文件名 rm -rf "$TMPDIR"/core_tmp elif echo "$1" |grep -q '.gz$' ;then gunzip -c "$1" > "$TMPDIR"/"$2" + elif echo "$1" |grep -q '.raw$' ;then + ln -sf "$1" "$TMPDIR"/"$2" elif echo "$1" |grep -q '.upx$' ;then ln -sf "$1" "$TMPDIR"/"$2" else @@ -45,16 +47,27 @@ core_check(){ rm -rf "$1" "$TMPDIR"/core_new return 2 else - rm -f "$BINDIR"/CrashCore.tar.gz "$BINDIR"/CrashCore.gz "$BINDIR"/CrashCore.upx - if [ -z "$zip_type" ];then + rm -f "$BINDIR"/CrashCore.tar.gz "$BINDIR"/CrashCore.gz "$BINDIR"/CrashCore.upx "$BINDIR"/CrashCore.raw + #$TMPDIR为内存(tmpfs)且$BINDIR为透明压缩文件系统(squashfs/ubifs)时,直接以裸二进制存于$BINDIR并软链,省内存 + store_raw=0 + tmp_fs=$(df -T "$TMPDIR" 2>/dev/null | awk 'END{print $2}') + rom_fs=$(df -T "$BINDIR" 2>/dev/null | awk 'END{print $2}') + case "$tmp_fs" in tmpfs|ramfs) + case "$rom_fs" in squashfs|ubifs|overlay|overlayfs) store_raw=1 ;; esac ;; + esac + if [ "$zip_type" = 'upx' ];then + mv -f "$1" "$BINDIR/CrashCore.upx" + rm -f "$TMPDIR"/core_new + ln -sf "$BINDIR/CrashCore.upx" "$TMPDIR/CrashCore" + elif [ "$store_raw" = 1 ];then + rm -f "$1" + mv -f "$TMPDIR/core_new" "$BINDIR/CrashCore.raw" + ln -sf "$BINDIR/CrashCore.raw" "$TMPDIR/CrashCore" + elif [ -z "$zip_type" ];then gzip -c "$TMPDIR/core_new" > "$BINDIR/CrashCore.gz" + mv -f "$TMPDIR/core_new" "$TMPDIR/CrashCore" else mv -f "$1" "$BINDIR/CrashCore.$zip_type" - fi - if [ "$zip_type" = 'upx' ];then - rm -f "$1" "$TMPDIR"/core_new - ln -sf "$TMPDIR/CrashCore.upx" "$TMPDIR/CrashCore" - else mv -f "$TMPDIR/core_new" "$TMPDIR/CrashCore" fi core_v="$v" From 55cfa65875e39a84ca6c2d81903ba98781f52676 Mon Sep 17 00:00:00 2001 From: Xiaoyi Date: Sat, 11 Jul 2026 15:59:42 +0800 Subject: [PATCH 2/3] core: prefer raw binary on compressed rom, avoid upx on tmpfs devices Adds store_on_rom() helper (tmpfs $TMPDIR + squashfs/ubifs/overlay $BINDIR). On such devices core_webget no longer downloads the upx core (its stub decompresses into a memfd = RAM at runtime); it fetches the tar.gz instead and core_check stores the naked binary as $BINDIR/CrashCore.raw, symlinked from $TMPDIR. The binary is transparently compressed on rom and file-backed/reclaimable at runtime (RssShmem 0). Other filesystems and explicit upx keep prior behavior. Also corrects the upx branch symlink target $TMPDIR -> $BINDIR (same dangling-symlink issue as #1295). For #1304 --- scripts/libs/core_tools.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/scripts/libs/core_tools.sh b/scripts/libs/core_tools.sh index bc553f8e4..6519ae85e 100644 --- a/scripts/libs/core_tools.sh +++ b/scripts/libs/core_tools.sh @@ -2,6 +2,14 @@ [ -n "$(find --help 2>&1 | grep -o size)" ] && find_para=' -size +2000' #find命令兼容 +#$TMPDIR为内存(tmpfs)且$BINDIR在透明压缩文件系统(squashfs/ubifs/overlay)上时返回0 +#此类设备应把裸二进制存于$BINDIR(rom透明压缩)并软链,而非解压/memfd占用内存 +store_on_rom(){ + case "$(df -T "$TMPDIR" 2>/dev/null | awk 'END{print $2}')" in tmpfs|ramfs) ;; *) return 1 ;; esac + case "$(df -T "$BINDIR" 2>/dev/null | awk 'END{print $2}')" in squashfs|ubifs|overlay|overlayfs) return 0 ;; esac + return 1 +} + core_unzip() { #$1:需要解压的文件 $2:目标文件名 if echo "$1" |grep -q 'tar.gz$' ;then [ "$BINDIR" = "$TMPDIR" ] && rm -rf "$TMPDIR"/CrashCore #小闪存模式防止空间不足 @@ -48,18 +56,11 @@ core_check(){ return 2 else rm -f "$BINDIR"/CrashCore.tar.gz "$BINDIR"/CrashCore.gz "$BINDIR"/CrashCore.upx "$BINDIR"/CrashCore.raw - #$TMPDIR为内存(tmpfs)且$BINDIR为透明压缩文件系统(squashfs/ubifs)时,直接以裸二进制存于$BINDIR并软链,省内存 - store_raw=0 - tmp_fs=$(df -T "$TMPDIR" 2>/dev/null | awk 'END{print $2}') - rom_fs=$(df -T "$BINDIR" 2>/dev/null | awk 'END{print $2}') - case "$tmp_fs" in tmpfs|ramfs) - case "$rom_fs" in squashfs|ubifs|overlay|overlayfs) store_raw=1 ;; esac ;; - esac if [ "$zip_type" = 'upx' ];then mv -f "$1" "$BINDIR/CrashCore.upx" rm -f "$TMPDIR"/core_new ln -sf "$BINDIR/CrashCore.upx" "$TMPDIR/CrashCore" - elif [ "$store_raw" = 1 ];then + elif store_on_rom ;then rm -f "$1" mv -f "$TMPDIR/core_new" "$BINDIR/CrashCore.raw" ln -sf "$BINDIR/CrashCore.raw" "$TMPDIR/CrashCore" @@ -83,6 +84,8 @@ core_webget(){ . "$CRASHDIR"/libs/check_target.sh if [ -z "$custcorelink" ];then [ -z "$zip_type" ] && zip_type='tar.gz' + #压缩rom+内存tmp设备避免下载upx(运行时memfd占RAM),改取tar.gz的裸二进制存于rom + [ "$zip_type" = 'upx' ] && store_on_rom && zip_type='tar.gz' get_bin "$TMPDIR/Coretmp.$zip_type" "bin/$crashcore/${target}-linux-${cpucore}.$zip_type" else case "$custcorelink" in From 433774071ad9fba8aa269d94530394348165f74c Mon Sep 17 00:00:00 2001 From: Xiaoyi Date: Sat, 11 Jul 2026 16:38:49 +0800 Subject: [PATCH 3/3] core: choose core storage by weighing rom cost vs ram cost Replaces the binary compressed-rom check with store_raw_worth_it(), which decides per environment: store the naked binary on $BINDIR (0 RAM) only when $TMPDIR is tmpfs AND $BINDIR can hold it with margin (estimated ~2:1 on squashfs/ubifs, full size otherwise). Otherwise keep a compressed copy and decompress to tmp as before. core_webget skips the upx core when raw storage is viable, fetching tar.gz instead. Rationale (rough budgets for a ~40M core): raw on squashfs ~15M rom / 0 RAM; gz 10M rom / ~40M RAM; upx 9M rom / ~40M RAM (memfd). Raw wins when rom has room; compressed wins when rom is the scarce resource. Also corrects the upx branch symlink target $TMPDIR -> $BINDIR (#1295). For #1304 --- scripts/libs/core_tools.sh | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/libs/core_tools.sh b/scripts/libs/core_tools.sh index 6519ae85e..a0ea7e7f2 100644 --- a/scripts/libs/core_tools.sh +++ b/scripts/libs/core_tools.sh @@ -2,12 +2,18 @@ [ -n "$(find --help 2>&1 | grep -o size)" ] && find_para=' -size +2000' #find命令兼容 -#$TMPDIR为内存(tmpfs)且$BINDIR在透明压缩文件系统(squashfs/ubifs/overlay)上时返回0 -#此类设备应把裸二进制存于$BINDIR(rom透明压缩)并软链,而非解压/memfd占用内存 -store_on_rom(){ +#根据环境权衡决定是否把裸二进制存于$BINDIR(rom)——省RAM,前提是rom装得下 +#$1=裸二进制字节数。仅当$TMPDIR在内存(tmpfs)时裸存才省RAM; +#再按$BINDIR文件系统估算裸二进制落盘体积(透明压缩fs约2:1),需留有余量($raw_margin,默认8M) +store_raw_worth_it(){ case "$(df -T "$TMPDIR" 2>/dev/null | awk 'END{print $2}')" in tmpfs|ramfs) ;; *) return 1 ;; esac - case "$(df -T "$BINDIR" 2>/dev/null | awk 'END{print $2}')" in squashfs|ubifs|overlay|overlayfs) return 0 ;; esac - return 1 + rom_free=$(df -k "$BINDIR" 2>/dev/null | awk 'END{print $4}') #KB + [ -z "$rom_free" ] && return 1 + case "$(df -T "$BINDIR" 2>/dev/null | awk 'END{print $2}')" in + squashfs|ubifs|overlay|overlayfs) est=$(( ${1:-0}/1024/2 )) ;; #透明压缩,约2:1 + *) est=$(( ${1:-0}/1024 )) ;; #无压缩,全量 + esac + [ $(( rom_free - est )) -gt "${raw_margin:-8192}" ] && return 0 || return 1 } core_unzip() { #$1:需要解压的文件 $2:目标文件名 @@ -60,7 +66,7 @@ core_check(){ mv -f "$1" "$BINDIR/CrashCore.upx" rm -f "$TMPDIR"/core_new ln -sf "$BINDIR/CrashCore.upx" "$TMPDIR/CrashCore" - elif store_on_rom ;then + elif store_raw_worth_it "$(wc -c < "$TMPDIR/core_new")" ;then rm -f "$1" mv -f "$TMPDIR/core_new" "$BINDIR/CrashCore.raw" ln -sf "$BINDIR/CrashCore.raw" "$TMPDIR/CrashCore" @@ -84,8 +90,8 @@ core_webget(){ . "$CRASHDIR"/libs/check_target.sh if [ -z "$custcorelink" ];then [ -z "$zip_type" ] && zip_type='tar.gz' - #压缩rom+内存tmp设备避免下载upx(运行时memfd占RAM),改取tar.gz的裸二进制存于rom - [ "$zip_type" = 'upx' ] && store_on_rom && zip_type='tar.gz' + #若环境适合裸存(见store_raw_worth_it,按典型核心~45M估算),避免下载upx,改取tar.gz的裸二进制 + [ "$zip_type" = 'upx' ] && store_raw_worth_it 47185920 && zip_type='tar.gz' get_bin "$TMPDIR/Coretmp.$zip_type" "bin/$crashcore/${target}-linux-${cpucore}.$zip_type" else case "$custcorelink" in