base-files: board_detect: make resilient against power-cuts
authorAndreas Gnau <[email protected]>
Wed, 8 Oct 2025 21:00:44 +0000 (23:00 +0200)
committerHauke Mehrtens <[email protected]>
Tue, 25 Nov 2025 20:51:25 +0000 (21:51 +0100)
If board_detect is interrupted by cutting power on first boot,
board.json might only be half-way written and the file will not be
written again correctly on subsequent boots.

Write to a temporary file first, then rename. Since a rename on the same
file system is an atomic operation, it ensures that either
/etc/board.json does not exist or that the complete file exists.

Signed-off-by: Andreas Gnau <[email protected]>
Link: https://github.com/openwrt/openwrt/pull/20831
Signed-off-by: Hauke Mehrtens <[email protected]>
package/base-files/files/bin/board_detect

index 4c50a6057d475cf2eb26bc0524d099659360b5e6..c4910cb47c44a0df88b5e41a77c8ac3097b2027d 100755 (executable)
@@ -1,14 +1,22 @@
 #!/bin/sh
 
-CFG=$1
+REAL_CFG=$1
 
-[ -n "$CFG" ] || CFG=/etc/board.json
+[ -n "$REAL_CFG" ] || REAL_CFG=/etc/board.json
 
-if [ -d "/etc/board.d/" ] && [ ! -s "$CFG" ]; then
+if [ -d "/etc/board.d/" ] && [ ! -s "$REAL_CFG" ]; then
+       # Use temp file to prevent incomplete file on power-cut, CFG is used by the sourced script to read/write the file
+       CFG="$(dirname "$REAL_CFG")/.$(basename "$REAL_CFG").tmp"
+       rm -f "$CFG" || exit
        for a in $(ls /etc/board.d/*); do
                [ -s "$a" ] || continue
                (. "$a")
        done
 fi
 
-[ -s "$CFG" ] || return 1
+if [ -s "$CFG" ]; then
+       mv "$CFG" "$REAL_CFG" || exit
+else
+       rm -f "$CFG"
+       exit 1
+fi