aboutsummaryrefslogtreecommitdiffstats
path: root/package/base-files/files/lib
diff options
context:
space:
mode:
Diffstat (limited to 'package/base-files/files/lib')
-rw-r--r--package/base-files/files/lib/functions.sh68
-rw-r--r--package/base-files/files/lib/functions/caldata.sh13
-rw-r--r--package/base-files/files/lib/functions/ipv4.sh268
-rw-r--r--package/base-files/files/lib/functions/leds.sh31
-rw-r--r--package/base-files/files/lib/functions/network.sh14
-rw-r--r--package/base-files/files/lib/functions/system.sh122
-rw-r--r--package/base-files/files/lib/functions/uci-defaults.sh59
-rw-r--r--package/base-files/files/lib/preinit/10_indicate_preinit41
-rw-r--r--package/base-files/files/lib/preinit/30_failsafe_wait60
-rw-r--r--package/base-files/files/lib/preinit/80_mount_root21
-rw-r--r--package/base-files/files/lib/preinit/99_10_failsafe_login15
-rw-r--r--package/base-files/files/lib/upgrade/common.sh44
-rw-r--r--package/base-files/files/lib/upgrade/emmc.sh67
-rw-r--r--package/base-files/files/lib/upgrade/fwtool.sh1
-rw-r--r--package/base-files/files/lib/upgrade/legacy-sdcard.sh91
-rw-r--r--package/base-files/files/lib/upgrade/nand.sh504
-rwxr-xr-xpackage/base-files/files/lib/upgrade/stage227
17 files changed, 1177 insertions, 269 deletions
diff --git a/package/base-files/files/lib/functions.sh b/package/base-files/files/lib/functions.sh
index d8604415cc8..d23a56e0cf0 100644
--- a/package/base-files/files/lib/functions.sh
+++ b/package/base-files/files/lib/functions.sh
@@ -40,6 +40,14 @@ append() {
eval "export ${NO_EXPORT:+-n} -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\""
}
+prepend() {
+ local var="$1"
+ local value="$2"
+ local sep="${3:- }"
+
+ eval "export ${NO_EXPORT:+-n} -- \"$var=\$value\${$var:+\${sep}\${$var}}\""
+}
+
list_contains() {
local var="$1"
local str="$2"
@@ -209,10 +217,10 @@ add_group_and_user() {
if [ -n "$rusers" ]; then
local tuple oIFS="$IFS"
for tuple in $rusers; do
- local uid gid uname gname
+ local uid gid uname gname addngroups addngroup addngname addngid
IFS=":"
- set -- $tuple; uname="$1"; gname="$2"
+ set -- $tuple; uname="$1"; gname="$2"; addngroups="$3"
IFS="="
set -- $uname; uname="$1"; uid="$2"
set -- $gname; gname="$1"; gid="$2"
@@ -232,7 +240,24 @@ add_group_and_user() {
group_add_user "$gname" "$uname"
fi
- unset uid gid uname gname
+ if [ -n "$uname" ] && [ -n "$addngroups" ]; then
+ oIFS="$IFS"
+ IFS=","
+ for addngroup in $addngroups ; do
+ IFS="="
+ set -- $addngroup; addngname="$1"; addngid="$2"
+ if [ -n "$addngid" ]; then
+ group_exists "$addngname" || group_add "$addngname" "$addngid"
+ else
+ group_add_next "$addngname"
+ fi
+
+ group_add_user "$addngname" "$uname"
+ done
+ IFS="$oIFS"
+ fi
+
+ unset uid gid uname gname addngroups addngroup addngname addngid
done
fi
}
@@ -245,11 +270,6 @@ default_postinst() {
add_group_and_user "${pkgname}"
- if [ -f "$root/usr/lib/opkg/info/${pkgname}.postinst-pkg" ]; then
- ( . "$root/usr/lib/opkg/info/${pkgname}.postinst-pkg" )
- ret=$?
- fi
-
if [ -d "$root/rootfs-overlay" ]; then
cp -R $root/rootfs-overlay/. $root/
rm -fR $root/rootfs-overlay/
@@ -275,6 +295,11 @@ default_postinst() {
rm -f /tmp/luci-indexcache
fi
+ if [ -f "$root/usr/lib/opkg/info/${pkgname}.postinst-pkg" ]; then
+ ( . "$root/usr/lib/opkg/info/${pkgname}.postinst-pkg" )
+ ret=$?
+ fi
+
local shell="$(command -v bash)"
for i in $(grep -s "^/etc/init.d/" "$root$filelist"); do
if [ -n "$root" ]; then
@@ -298,6 +323,11 @@ include() {
done
}
+ipcalc() {
+ set -- $(ipcalc.sh "$@")
+ [ $? -eq 0 ] && export -- "$@"
+}
+
find_mtd_index() {
local PART="$(grep "\"$1\"" /proc/mtd | awk -F: '{print $1}')"
local INDEX="${PART##mtd}"
@@ -313,6 +343,25 @@ find_mtd_part() {
echo "${INDEX:+$PREFIX$INDEX}"
}
+find_mmc_part() {
+ local DEVNAME PARTNAME ROOTDEV
+
+ if grep -q "$1" /proc/mtd; then
+ echo "" && return 0
+ fi
+
+ if [ -n "$2" ]; then
+ ROOTDEV="$2"
+ else
+ ROOTDEV="mmcblk*"
+ fi
+
+ for DEVNAME in /sys/block/$ROOTDEV/mmcblk*p*; do
+ PARTNAME="$(grep PARTNAME ${DEVNAME}/uevent | cut -f2 -d'=')"
+ [ "$PARTNAME" = "$1" ] && echo "/dev/$(basename $DEVNAME)" && return 0
+ done
+}
+
group_add() {
local name="$1"
local gid="$2"
@@ -350,6 +399,9 @@ group_add_user() {
echo "$grp" | grep -q ":$" && delim=""
[ -n "$IPKG_INSTROOT" ] || lock /var/lock/passwd
sed -i "s/$grp/$grp$delim$2/g" ${IPKG_INSTROOT}/etc/group
+ if [ -z "$IPKG_INSTROOT" ] && [ -x /usr/sbin/selinuxenabled ] && selinuxenabled; then
+ restorecon /etc/group
+ fi
[ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/passwd
}
diff --git a/package/base-files/files/lib/functions/caldata.sh b/package/base-files/files/lib/functions/caldata.sh
index 2177cf84153..d7b88c7dcef 100644
--- a/package/base-files/files/lib/functions/caldata.sh
+++ b/package/base-files/files/lib/functions/caldata.sh
@@ -48,6 +48,19 @@ caldata_extract_ubi() {
caldata_die "failed to extract calibration data from $ubi"
}
+caldata_extract_mmc() {
+ local part=$1
+ local offset=$(($2))
+ local count=$(($3))
+ local mmc_part
+
+ mmc_part=$(find_mmc_part $part)
+ [ -n "$mmc_part" ] || caldata_die "no mmc partition found for partition $part"
+
+ caldata_dd $mmc_part /lib/firmware/$FIRMWARE $count $offset || \
+ caldata_die "failed to extract calibration data from $mmc_part"
+}
+
caldata_extract_reverse() {
local part=$1
local offset=$2
diff --git a/package/base-files/files/lib/functions/ipv4.sh b/package/base-files/files/lib/functions/ipv4.sh
new file mode 100644
index 00000000000..d0b93dbcb9b
--- /dev/null
+++ b/package/base-files/files/lib/functions/ipv4.sh
@@ -0,0 +1,268 @@
+uint_max=4294967295
+
+d_10_0_0_0=167772160
+d_10_255_255_255=184549375
+
+d_172_16_0_0=2886729728
+d_172_31_255_255=2887778303
+
+d_192_168_0_0=3232235520
+d_192_168_255_255=3232301055
+
+d_169_254_0_0=2851995648
+d_169_254_255_255=2852061183
+
+d_127_0_0_0=2130706432
+d_127_255_255_255=2147483647
+
+d_224_0_0_0=3758096384
+d_239_255_255_255=4026531839
+
+# check that $1 is only base 10 digits, and that it doesn't
+# exceed 2^32-1
+assert_uint32() {
+ local __n="$1"
+
+ if [ -z "$__n" -o -n "${__n//[0-9]/}" ]; then
+ printf "Not a decimal integer (%s)\n" "$__n ">&2
+ return 1
+ fi
+
+ if [ "$__n" -gt $uint_max ]; then
+ printf "Out of range (%s)\n" "$__n" >&2
+ return 1
+ fi
+
+ if [ "$((__n + 0))" != "$__n" ]; then
+ printf "Not normalized notation (%s)\n" "$__n" >&2
+ return 1
+ fi
+
+ return 0
+}
+
+# return a count of the number of bits set in $1
+bitcount() {
+ local __var="$1" __c="$2"
+ assert_uint32 "$__c" || return 1
+
+ __c=$((((__c >> 1) & 0x55555555) + (__c & 0x55555555)))
+ __c=$((((__c >> 2) & 0x33333333) + (__c & 0x33333333)))
+ __c=$((((__c >> 4) & 0x0f0f0f0f) + (__c & 0x0f0f0f0f)))
+ __c=$((((__c >> 8) & 0x00ff00ff) + (__c & 0x00ff00ff)))
+ __c=$((((__c >> 16) & 0x0000ffff) + (__c & 0x0000ffff)))
+
+ export -- "$__var=$__c"
+}
+
+# tedious but portable with busybox's limited shell
+# we check each octet to be in the range of 0..255,
+# and also make sure there's no extaneous characters.
+str2ip() {
+ local __var="$1" __ip="$2" __n __val=0
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__n << 24))
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + (__n << 16)))
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + (__n << 8)))
+
+ case "$__ip" in
+ [0-9])
+ __n="${__ip:0:1}"
+ __ip="${__ip:1}"
+ ;;
+ [1-9][0-9])
+ __n="${__ip:0:2}"
+ __ip="${__ip:2}"
+ ;;
+ 1[0-9][0-9]|2[0-4][0-9]|25[0-5])
+ __n="${__ip:0:3}"
+ __ip="${__ip:3}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + __n))
+
+ if [ -n "$__ip" ]; then
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ fi
+
+ export -- "$__var=$__val"
+ return 0
+}
+
+# convert back from an integer to dotted-quad.
+ip2str() {
+ local __var="$1" __n="$2"
+ assert_uint32 "$__n" || return 1
+
+ export -- "$__var=$((__n >> 24)).$(((__n >> 16) & 255)).$(((__n >> 8) & 255)).$((__n & 255))"
+}
+
+# convert prefix into an integer bitmask
+prefix2netmask() {
+ local __var="$1" __n="$2"
+ assert_uint32 "$__n" || return 1
+
+ if [ "$__n" -gt 32 ]; then
+ printf "Prefix out-of-range (%s)" "$__n" >&2
+ return 1
+ fi
+
+ export -- "$__var=$(((~(uint_max >> __n)) & uint_max))"
+}
+
+_is_contiguous() {
+ local __x="$1" # no checking done
+ local __y=$((~__x & uint_max))
+ local __z=$(((__y + 1) & uint_max))
+
+ [ $((__z & __y)) -eq 0 ]
+}
+
+# check argument as being contiguous upper bits (and yes,
+# 0 doesn't have any discontiguous bits).
+is_contiguous() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ local __y=$((~__x & uint_max))
+ local __z=$(((__y + 1) & uint_max))
+
+ [ $((__z & __y)) -eq 0 ] && __val=1
+
+ export -- "$__var=$__val"
+}
+
+# convert mask to prefix, validating that it's a conventional
+# (contiguous) netmask.
+netmask2prefix() {
+ local __var="$1" __n="$2" __cont __bits
+ assert_uint32 "$__n" || return 1
+
+ is_contiguous __cont "$__n" || return 1
+ if [ $__cont -eq 0 ]; then
+ printf "Not a contiguous netmask (%08x)\n" "$__n" >&2
+ return 1
+ fi
+
+ bitcount __bits "$__n" # already checked
+
+ export -- "$__var=$__bits"
+}
+
+# check the argument as being an rfc-1918 address
+is_rfc1918() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_10_0_0_0 -le $__x ] && [ $__x -le $d_10_255_255_255 ]; then
+ __val=1
+ elif [ $d_172_16_0_0 -le $__x ] && [ $__x -le $d_172_31_255_255 ]; then
+ __val=1
+ elif [ $d_192_168_0_0 -le $__x ] && [ $__x -le $d_192_168_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
+# check the argument as being an rfc-3927 address
+is_rfc3927() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_169_254_0_0 -le $__x ] && [ $__x -le $d_169_254_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
+# check the argument as being an rfc-1122 loopback address
+is_loopback() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_127_0_0_0 -le $__x ] && [ $__x -le $d_127_255_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
+# check the argument as being a multicast address
+is_multicast() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_224_0_0_0 -le $__x ] && [ $__x -le $d_239_255_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
diff --git a/package/base-files/files/lib/functions/leds.sh b/package/base-files/files/lib/functions/leds.sh
index a7532faa2fd..333d900df0c 100644
--- a/package/base-files/files/lib/functions/leds.sh
+++ b/package/base-files/files/lib/functions/leds.sh
@@ -11,6 +11,36 @@ get_dt_led_path() {
echo "$ledpath"
}
+get_dt_led_color_func() {
+ local enum
+ local func
+ local idx
+ local label
+
+ [ -e "$1/function" ] && func=$(cat "$1/function")
+ [ -e "$1/color" ] && idx=$((0x$(hexdump -n 4 -e '4/1 "%02x"' "$1/color")))
+ [ -e "$1/function-enumerator" ] && \
+ enum=$((0x$(hexdump -n 4 -e '4/1 "%02x"' "$1/function-enumerator")))
+
+ [ -z "$idx" ] && [ -z "$func" ] && return 2
+
+ if [ -n "$idx" ]; then
+ for color in "white" "red" "green" "blue" "amber" \
+ "violet" "yellow" "ir" "multicolor" "rgb" \
+ "purple" "orange" "pink" "cyan" "lime"
+ do
+ [ $idx -eq 0 ] && label="$color" && break
+ idx=$((idx-1))
+ done
+ fi
+
+ label="$label:$func"
+ [ -n "$enum" ] && label="$label-$enum"
+ echo "$label"
+
+ return 0
+}
+
get_dt_led() {
local label
local ledpath=$(get_dt_led_path $1)
@@ -18,6 +48,7 @@ get_dt_led() {
[ -n "$ledpath" ] && \
label=$(cat "$ledpath/label" 2>/dev/null) || \
label=$(cat "$ledpath/chan-name" 2>/dev/null) || \
+ label=$(get_dt_led_color_func "$ledpath") || \
label=$(basename "$ledpath")
echo "$label"
diff --git a/package/base-files/files/lib/functions/network.sh b/package/base-files/files/lib/functions/network.sh
index 055f18c11e0..4851a5817ad 100644
--- a/package/base-files/files/lib/functions/network.sh
+++ b/package/base-files/files/lib/functions/network.sh
@@ -90,6 +90,13 @@ network_get_prefix6() {
__network_ifstatus "$1" "$2" "['ipv6-prefix'][0]['address','mask']" "/"
}
+# determine first IPv6 prefix assignment of given logical interface
+# 1: destination variable
+# 2: interface
+network_get_prefix_assignment6() {
+ __network_ifstatus "$1" "$2" "['ipv6-prefix-assignment'][0]['address','mask']" "/"
+}
+
# determine all IPv4 addresses of given logical interface
# 1: destination variable
# 2: interface
@@ -187,6 +194,13 @@ network_get_prefixes6() {
__network_ifstatus "$1" "$2" "['ipv6-prefix'][*]['address','mask']" "/ "
}
+# determine all IPv6 prefix assignments of given logical interface
+# 1: destination variable
+# 2: interface
+network_get_prefix_assignments6() {
+ __network_ifstatus "$1" "$2" "['ipv6-prefix-assignment'][*]['address','mask']" "/ "
+}
+
# determine IPv4 gateway of given logical interface
# 1: destination variable
# 2: interface
diff --git a/package/base-files/files/lib/functions/system.sh b/package/base-files/files/lib/functions/system.sh
index 80e417182a2..107e67835a2 100644
--- a/package/base-files/files/lib/functions/system.sh
+++ b/package/base-files/files/lib/functions/system.sh
@@ -61,11 +61,21 @@ find_mtd_chardev() {
echo "${INDEX:+$PREFIX$INDEX}"
}
+get_mac_ascii() {
+ local part="$1"
+ local key="$2"
+ local mac_dirty
+
+ mac_dirty=$(strings "$part" | sed -n 's/^'"$key"'=//p')
+
+ # "canonicalize" mac
+ [ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
+}
+
mtd_get_mac_ascii() {
local mtdname="$1"
local key="$2"
local part
- local mac_dirty
part=$(find_mtd_part "$mtdname")
if [ -z "$part" ]; then
@@ -73,17 +83,75 @@ mtd_get_mac_ascii() {
return
fi
- mac_dirty=$(strings "$part" | sed -n 's/^'"$key"'=//p')
+ get_mac_ascii "$part" "$key"
+}
+
+mtd_get_mac_encrypted_arcadyan() {
+ local iv="00000000000000000000000000000000"
+ local key="2A4B303D7644395C3B2B7053553C5200"
+ local mac_dirty
+ local mtdname="$1"
+ local part
+ local size
+
+ part=$(find_mtd_part "$mtdname")
+ if [ -z "$part" ]; then
+ echo "mtd_get_mac_encrypted_arcadyan: partition $mtdname not found!" >&2
+ return
+ fi
+
+ # Config decryption and getting mac. Trying uencrypt and openssl utils.
+ size=$((0x$(dd if=$part skip=9 bs=1 count=4 2>/dev/null | hexdump -v -e '1/4 "%08x"')))
+ if [[ -f "/usr/bin/uencrypt" ]]; then
+ mac_dirty=$(dd if=$part bs=1 count=$size skip=$((0x100)) 2>/dev/null | \
+ uencrypt -d -n -k $key -i $iv | grep mac | cut -c 5-)
+ elif [[ -f "/usr/bin/openssl" ]]; then
+ mac_dirty=$(dd if=$part bs=1 count=$size skip=$((0x100)) 2>/dev/null | \
+ openssl aes-128-cbc -d -nopad -K $key -iv $iv | grep mac | cut -c 5-)
+ else
+ echo "mtd_get_mac_encrypted_arcadyan: Neither uencrypt nor openssl was found!" >&2
+ return
+ fi
# "canonicalize" mac
[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
}
+mtd_get_mac_encrypted_deco() {
+ local mtdname="$1"
+
+ if ! [ -e "$mtdname" ]; then
+ echo "mtd_get_mac_encrypted_deco: file $mtdname not found!" >&2
+ return
+ fi
+
+ tplink_key="3336303032384339"
+
+ key=$(dd if=$mtdname bs=1 skip=16 count=8 2>/dev/null | \
+ uencrypt -n -d -k $tplink_key -c des-ecb | hexdump -v -n 8 -e '1/1 "%02x"')
+
+ macaddr=$(dd if=$mtdname bs=1 skip=32 count=8 2>/dev/null | \
+ uencrypt -n -d -k $key -c des-ecb | hexdump -v -n 6 -e '5/1 "%02x:" 1/1 "%02x"')
+
+ echo $macaddr
+}
+
+mtd_get_mac_uci_config_ubi() {
+ local volumename="$1"
+
+ . /lib/upgrade/nand.sh
+
+ local ubidev=$(nand_attach_ubi $CI_UBIPART)
+ local part=$(nand_find_volume $ubidev $volumename)
+
+ cat "/dev/$part" | sed -n 's/^\s*option macaddr\s*'"'"'\?\([0-9A-F:]\+\)'"'"'\?/\1/Ip'
+}
+
mtd_get_mac_text() {
- local mtdname=$1
- local offset=$(($2))
+ local mtdname="$1"
+ local offset=$((${2:-0}))
+ local length="${3:-17}"
local part
- local mac_dirty
part=$(find_mtd_part "$mtdname")
if [ -z "$part" ]; then
@@ -91,15 +159,9 @@ mtd_get_mac_text() {
return
fi
- if [ -z "$offset" ]; then
- echo "mtd_get_mac_text: offset missing!" >&2
- return
- fi
+ [ $((offset + length)) -le $(mtd_get_part_size "$mtdname") ] || return
- mac_dirty=$(dd if="$part" bs=1 skip="$offset" count=17 2>/dev/null)
-
- # "canonicalize" mac
- [ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
+ macaddr_canonicalize $(dd bs=1 if="$part" skip="$offset" count="$length" 2>/dev/null)
}
mtd_get_mac_binary() {
@@ -135,6 +197,28 @@ mtd_get_part_size() {
done < /proc/mtd
}
+mmc_get_mac_ascii() {
+ local part_name="$1"
+ local key="$2"
+ local part
+
+ part=$(find_mmc_part "$part_name")
+ if [ -z "$part" ]; then
+ echo "mmc_get_mac_ascii: partition $part_name not found!" >&2
+ fi
+
+ get_mac_ascii "$part" "$key"
+}
+
+mmc_get_mac_binary() {
+ local part_name="$1"
+ local offset="$2"
+ local part
+
+ part=$(find_mmc_part "$part_name")
+ get_mac_binary "$part" "$offset"
+}
+
macaddr_add() {
local mac=$1
local val=$2
@@ -145,6 +229,14 @@ macaddr_add() {
echo $oui:$nic
}
+macaddr_generate_from_mmc_cid() {
+ local mmc_dev=$1
+
+ local sd_hash=$(sha256sum /sys/class/block/$mmc_dev/device/cid)
+ local mac_base=$(macaddr_canonicalize "$(echo "${sd_hash}" | dd bs=1 count=12 2>/dev/null)")
+ echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${mac_base}")")"
+}
+
macaddr_geteui() {
local mac=$1
local sep=$2
@@ -224,3 +316,7 @@ macaddr_canonicalize() {
printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${canon// / 0x} 2>/dev/null
}
+
+dt_is_enabled() {
+ grep -q okay "/proc/device-tree/$1/status"
+}
diff --git a/package/base-files/files/lib/functions/uci-defaults.sh b/package/base-files/files/lib/functions/uci-defaults.sh
index 02882f43ca4..b89cc8e9e30 100644
--- a/package/base-files/files/lib/functions/uci-defaults.sh
+++ b/package/base-files/files/lib/functions/uci-defaults.sh
@@ -96,7 +96,7 @@ ucidef_set_interfaces_lan_wan() {
ucidef_set_bridge_device() {
json_select_object bridge
- json_add_string name "${1:switch0}"
+ json_add_string name "${1:-switch0}"
json_select ..
}
@@ -106,14 +106,30 @@ ucidef_set_bridge_mac() {
json_select ..
}
-ucidef_set_network_device_mac() {
- json_select_object "network-device"
+_ucidef_set_network_device_common() {
+ json_select_object "network_device"
json_select_object "${1}"
- json_add_string macaddr "${2}"
+ json_add_string "${2}" "${3}"
json_select ..
json_select ..
}
+ucidef_set_network_device_mac() {
+ _ucidef_set_network_device_common $1 macaddr $2
+}
+
+ucidef_set_network_device_path() {
+ _ucidef_set_network_device_common $1 path $2
+}
+
+ucidef_set_network_device_gro() {
+ _ucidef_set_network_device_common $1 gro $2
+}
+
+ucidef_set_network_device_conduit() {
+ _ucidef_set_network_device_common $1 conduit $2
+}
+
_ucidef_add_switch_port() {
# inherited: $num $device $need_tag $want_untag $role $index $prev_role
# inherited: $n_cpu $n_ports $n_vlan $cpu0 $cpu1 $cpu2 $cpu3 $cpu4 $cpu5
@@ -418,6 +434,15 @@ ucidef_set_led_default() {
json_select ..
}
+ucidef_set_led_heartbeat() {
+ _ucidef_set_led_common "$1" "$2" "$3"
+
+ json_add_string trigger heartbeat
+ json_select ..
+
+ json_select ..
+}
+
ucidef_set_led_gpio() {
local gpio="$4"
local inverted="$5"
@@ -629,6 +654,32 @@ ucidef_set_ntpserver() {
json_select ..
}
+ucidef_set_poe() {
+ json_select_object poe
+ json_add_string "budget" "$1"
+ json_select_array ports
+ for port in $2; do
+ json_add_string "" "$port"
+ done
+ json_select ..
+ json_select ..
+}
+
+ucidef_add_wlan() {
+ local path="$1"; shift
+
+ ucidef_wlan_idx=${ucidef_wlan_idx:-0}
+
+ json_select_object wlan
+ json_select_object "wl$ucidef_wlan_idx"
+ json_add_string path "$path"
+ json_add_fields "$@"
+ json_select ..
+ json_select ..
+
+ ucidef_wlan_idx="$((ucidef_wlan_idx + 1))"
+}
+
board_config_update() {
json_init
[ -f ${CFG} ] && json_load "$(cat ${CFG})"
diff --git a/package/base-files/files/lib/preinit/10_indicate_preinit b/package/base-files/files/lib/preinit/10_indicate_preinit
index debb3d44808..a8f7758c841 100644
--- a/package/base-files/files/lib/preinit/10_indicate_preinit
+++ b/package/base-files/files/lib/preinit/10_indicate_preinit
@@ -63,6 +63,20 @@ preinit_config_switch() {
json_select ..
}
+preinit_config_port() {
+ local original
+
+ local netdev="$1"
+ local path="$2"
+
+ [ -d "/sys/devices/$path/net" ] || return
+ original="$(ls "/sys/devices/$path/net" | head -1)"
+
+ [ "$netdev" = "$original" ] && return
+
+ ip link set "$original" name "$netdev"
+}
+
preinit_config_board() {
/bin/board_detect /tmp/board.json
@@ -73,6 +87,33 @@ preinit_config_board() {
json_init
json_load "$(cat /tmp/board.json)"
+ # Find the current highest eth*
+ max_eth=$(grep -o '^ *eth[0-9]*:' /proc/net/dev | tr -dc '[0-9]\n' | sort -n | tail -1)
+ # Find and move netdevs using eth*s we are configuring
+ json_get_keys keys "network_device"
+ for netdev in $keys; do
+ json_select "network_device"
+ json_select "$netdev"
+ json_get_vars path path
+ if [ -n "$path" -a -h "/sys/class/net/$netdev" ]; then
+ ip link set "$netdev" down
+ ip link set "$netdev" name eth$((++max_eth))
+ fi
+ json_select ..
+ json_select ..
+ done
+
+ # Move interfaces by path to their netdev name
+ json_get_keys keys "network_device"
+ for netdev in $keys; do
+ json_select "network_device"
+ json_select "$netdev"
+ json_get_vars path path
+ [ -n "$path" ] && preinit_config_port "$netdev" "$path"
+ json_select ..
+ json_select ..
+ done
+
json_select network
json_select "lan"
json_get_vars device
diff --git a/package/base-files/files/lib/preinit/30_failsafe_wait b/package/base-files/files/lib/preinit/30_failsafe_wait
index f90de71d40f..9ab2e8bd4d8 100644
--- a/package/base-files/files/lib/preinit/30_failsafe_wait
+++ b/package/base-files/files/lib/preinit/30_failsafe_wait
@@ -40,35 +40,39 @@ fs_wait_for_key () {
rm -f $keypress_wait
} &
- [ "$pi_preinit_no_failsafe" != "y" ] && echo "Press the [$1] key and hit [enter] $2"
- echo "Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level"
- # if we're on the console we wait for input
- {
- while [ -r $keypress_wait ]; do
- timer="$(cat $keypress_sec)"
+ local consoles="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | sed -e 's/^console=//' -e 's/,.*//')"
+ [ -n "$consoles" ] || consoles=console
+ for console in $consoles; do
+ [ -c "/dev/$console" ] || continue
+ [ "$pi_preinit_no_failsafe" != "y" ] && echo "Press the [$1] key and hit [enter] $2" > "/dev/$console"
+ echo "Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level" > "/dev/$console"
+ {
+ while [ -r $keypress_wait ]; do
+ timer="$(cat $keypress_sec)"
- [ -n "$timer" ] || timer=1
- timer="${timer%%\ *}"
- [ $timer -ge 1 ] || timer=1
- do_keypress=""
- {
- read -t "$timer" do_keypress
- case "$do_keypress" in
- $1)
- echo "true" >$keypress_true
- ;;
- 1 | 2 | 3 | 4)
- echo "$do_keypress" >/tmp/debug_level
- ;;
- *)
- continue;
- ;;
- esac
- lock -u $keypress_wait
- rm -f $keypress_wait
- }
- done
- }
+ [ -n "$timer" ] || timer=1
+ timer="${timer%%\ *}"
+ [ $timer -ge 1 ] || timer=1
+ do_keypress=""
+ {
+ read -t "$timer" do_keypress < "/dev/$console"
+ case "$do_keypress" in
+ $1)
+ echo "true" >$keypress_true
+ ;;
+ 1 | 2 | 3 | 4)
+ echo "$do_keypress" >/tmp/debug_level
+ ;;
+ *)
+ continue;
+ ;;
+ esac
+ lock -u $keypress_wait
+ rm -f $keypress_wait
+ }
+ done
+ } &
+ done
lock -w $keypress_wait
keypressed=1
diff --git a/package/base-files/files/lib/preinit/80_mount_root b/package/base-files/files/lib/preinit/80_mount_root
index c3816c2cbfe..fa6abcde57f 100644
--- a/package/base-files/files/lib/preinit/80_mount_root
+++ b/package/base-files/files/lib/preinit/80_mount_root
@@ -14,8 +14,27 @@ missing_lines() {
IFS="$oIFS"
}
+# Rootfs mount options can be passed by declaring in the kernel
+# cmdline as much options as needed prefixed with "rootfs_mount_options."
+#
+# Example:
+# rootfs_mount_options.compress_algorithm=zstd rootfs_mount_options.noinline_data
+#
+compose_rootfs_mount_options() {
+ local mount_options
+ local cmdlinevar
+
+ for cmdlinevar in $(cat /proc/cmdline); do
+ if [ "$cmdlinevar" != "${cmdlinevar#rootfs_mount_options\.}" ]; then
+ append mount_options "${cmdlinevar#rootfs_mount_options\.}"
+ fi
+ done
+
+ echo $mount_options
+}
+
do_mount_root() {
- mount_root
+ mount_root start "$(compose_rootfs_mount_options)"
boot_run_hook preinit_mount_root
[ -f /sysupgrade.tgz -o -f /tmp/sysupgrade.tar ] && {
echo "- config restore -"
diff --git a/package/base-files/files/lib/preinit/99_10_failsafe_login b/package/base-files/files/lib/preinit/99_10_failsafe_login
index 1410c5f0db5..6f4af3f28b5 100644
--- a/package/base-files/files/lib/preinit/99_10_failsafe_login
+++ b/package/base-files/files/lib/preinit/99_10_failsafe_login
@@ -2,13 +2,14 @@
# Copyright (C) 2010 Vertical Communications
failsafe_shell() {
- local console="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | head -1 | sed -e 's/^console=//' -e 's/,.*//')"
- [ -n "$console" ] || console=console
- [ -c "/dev/$console" ] || return 0
- while true; do
- ash --login <"/dev/$console" >"/dev/$console" 2>"/dev/$console"
- sleep 1
- done &
+ local consoles="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | sed -e 's/^console=//' -e 's/,.*//')"
+ [ -n "$consoles" ] || consoles=console
+ for console in $consoles; do
+ [ -c "/dev/$console" ] && while true; do
+ ash --login <"/dev/$console" >"/dev/$console" 2>"/dev/$console"
+ sleep 1
+ done &
+ done
}
boot_hook_add failsafe failsafe_shell
diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh
index 2b152a3dfad..af1182cb16a 100644
--- a/package/base-files/files/lib/upgrade/common.sh
+++ b/package/base-files/files/lib/upgrade/common.sh
@@ -127,6 +127,33 @@ get_magic_fat32() {
(get_image "$@" | dd bs=1 count=5 skip=82) 2>/dev/null
}
+identify_magic_long() {
+ local magic=$1
+ case "$magic" in
+ "55424923")
+ echo "ubi"
+ ;;
+ "31181006")
+ echo "ubifs"
+ ;;
+ "68737173")
+ echo "squashfs"
+ ;;
+ "d00dfeed")
+ echo "fit"
+ ;;
+ "4349"*)
+ echo "combined"
+ ;;
+ "1f8b"*)
+ echo "gzip"
+ ;;
+ *)
+ echo "unknown $magic"
+ ;;
+ esac
+}
+
part_magic_efi() {
local magic=$(get_magic_gpt "$@")
[ "$magic" = "EFI PART" ]
@@ -155,9 +182,11 @@ export_bootdevice() {
fi
done
;;
+ PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=1 | \
PARTUUID=????????-????-????-????-??????????02)
uuid="${rootpart#PARTUUID=}"
- uuid="${uuid%02}00"
+ uuid="${uuid%/PARTNROFF=1}"
+ uuid="${uuid%0?}00"
for disk in $(find /dev -type b); do
set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then
@@ -203,7 +232,7 @@ export_partdevice() {
while read line; do
export -n "$line"
done < "$uevent"
- if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then
+ if [ "$BOOTDEV_MAJOR" = "$MAJOR" -a $(($BOOTDEV_MINOR + $offset)) = "$MINOR" -a -b "/dev/$DEVNAME" ]; then
export "$var=$DEVNAME"
return 0
fi
@@ -220,15 +249,6 @@ hex_le32_to_cpu() {
echo "$@"
}
-get_partition_by_name() {
- for partname in /sys/class/block/$1/*/name; do
- [ "$(cat ${partname})" = "$2" ] && {
- basename ${partname%%/name}
- break
- }
- done
-}
-
get_partitions() { # <device> <filename>
local disk="$1"
local filename="$2"
@@ -254,7 +274,7 @@ get_partitions() { # <device> <filename>
local type="$1"
local lba="$(( $(hex_le32_to_cpu $4) * 0x100000000 + $(hex_le32_to_cpu $3) ))"
local end="$(( $(hex_le32_to_cpu $6) * 0x100000000 + $(hex_le32_to_cpu $5) ))"
- local num="$(( $end - $lba ))"
+ local num="$(( $end - $lba + 1 ))"
[ "$type" = "00000000000000000000000000000000" ] && continue
diff --git a/package/base-files/files/lib/upgrade/emmc.sh b/package/base-files/files/lib/upgrade/emmc.sh
new file mode 100644
index 00000000000..49cffe1c658
--- /dev/null
+++ b/package/base-files/files/lib/upgrade/emmc.sh
@@ -0,0 +1,67 @@
+# Copyright (C) 2021 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+emmc_upgrade_tar() {
+ local tar_file="$1"
+ [ "$CI_KERNPART" -a -z "$EMMC_KERN_DEV" ] && export EMMC_KERN_DEV="$(find_mmc_part $CI_KERNPART $CI_ROOTDEV)"
+ [ "$CI_ROOTPART" -a -z "$EMMC_ROOT_DEV" ] && export EMMC_ROOT_DEV="$(find_mmc_part $CI_ROOTPART $CI_ROOTDEV)"
+ [ "$CI_DATAPART" -a -z "$EMMC_DATA_DEV" ] && export EMMC_DATA_DEV="$(find_mmc_part $CI_DATAPART $CI_ROOTDEV)"
+ local has_kernel
+ local has_rootfs
+ local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$')
+ board_dir=${board_dir%/}
+
+ tar tf "$tar_file" ${board_dir}/kernel 1>/dev/null 2>/dev/null && has_kernel=1
+ tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1
+
+ [ "$has_kernel" = 1 -a "$EMMC_KERN_DEV" ] &&
+ export EMMC_KERNEL_BLOCKS=$(($(tar xf "$tar_file" ${board_dir}/kernel -O | dd of="$EMMC_KERN_DEV" bs=512 2>&1 | grep "records out" | cut -d' ' -f1)))
+
+ [ "$has_rootfs" = 1 -a "$EMMC_ROOT_DEV" ] && {
+ export EMMC_ROOTFS_BLOCKS=$(($(tar xf "$tar_file" ${board_dir}/root -O | dd of="$EMMC_ROOT_DEV" bs=512 2>&1 | grep "records out" | cut -d' ' -f1)))
+ # Account for 64KiB ROOTDEV_OVERLAY_ALIGN in libfstools
+ EMMC_ROOTFS_BLOCKS=$(((EMMC_ROOTFS_BLOCKS + 127) & ~127))
+ }
+
+ if [ -z "$UPGRADE_BACKUP" ]; then
+ if [ "$EMMC_DATA_DEV" ]; then
+ dd if=/dev/zero of="$EMMC_DATA_DEV" bs=512 count=8
+ elif [ "$EMMC_ROOTFS_BLOCKS" ]; then
+ dd if=/dev/zero of="$EMMC_ROOT_DEV" bs=512 seek=$EMMC_ROOTFS_BLOCKS count=8
+ elif [ "$EMMC_KERNEL_BLOCKS" ]; then
+ dd if=/dev/zero of="$EMMC_KERN_DEV" bs=512 seek=$EMMC_KERNEL_BLOCKS count=8
+ fi
+ fi
+}
+
+emmc_upgrade_fit() {
+ local fit_file="$1"
+ [ "$CI_KERNPART" -a -z "$EMMC_KERN_DEV" ] && export EMMC_KERN_DEV="$(find_mmc_part $CI_KERNPART $CI_ROOTDEV)"
+
+ if [ "$EMMC_KERN_DEV" ]; then
+ export EMMC_KERNEL_BLOCKS=$(($(get_image "$fit_file" | fwtool -i /dev/null -T - | dd of="$EMMC_KERN_DEV" bs=512 2>&1 | grep "records out" | cut -d' ' -f1)))
+
+ [ -z "$UPGRADE_BACKUP" ] && dd if=/dev/zero of="$EMMC_KERN_DEV" bs=512 seek=$EMMC_KERNEL_BLOCKS count=8
+ fi
+}
+
+emmc_copy_config() {
+ if [ "$EMMC_DATA_DEV" ]; then
+ dd if="$UPGRADE_BACKUP" of="$EMMC_DATA_DEV" bs=512
+ elif [ "$EMMC_ROOTFS_BLOCKS" ]; then
+ dd if="$UPGRADE_BACKUP" of="$EMMC_ROOT_DEV" bs=512 seek=$EMMC_ROOTFS_BLOCKS
+ elif [ "$EMMC_KERNEL_BLOCKS" ]; then
+ dd if="$UPGRADE_BACKUP" of="$EMMC_KERN_DEV" bs=512 seek=$EMMC_KERNEL_BLOCKS
+ fi
+}
+
+emmc_do_upgrade() {
+ local file_type=$(identify_magic_long "$(get_magic_long "$1")")
+
+ case "$file_type" in
+ "fit") emmc_upgrade_fit $1;;
+ *) emmc_upgrade_tar $1;;
+ esac
+}
diff --git a/package/base-files/files/lib/upgrade/fwtool.sh b/package/base-files/files/lib/upgrade/fwtool.sh
index a45f3bbc731..8bd00a33328 100644
--- a/package/base-files/files/lib/upgrade/fwtool.sh
+++ b/package/base-files/files/lib/upgrade/fwtool.sh
@@ -71,6 +71,7 @@ fwtool_check_image() {
# minor compat version -> sysupgrade with -n required
if [ "${devicecompat#.*}" != "${imagecompat#.*}" ] && [ "$SAVE_CONFIG" = "1" ]; then
+ [ "$IGNORE_MINOR_COMPAT" = 1 ] && return 0
v "The device is supported, but the config is incompatible to the new image ($devicecompat->$imagecompat). Please upgrade without keeping config (sysupgrade -n)."
[ -n "$compatmessage" ] && v "$compatmessage"
return 1
diff --git a/package/base-files/files/lib/upgrade/legacy-sdcard.sh b/package/base-files/files/lib/upgrade/legacy-sdcard.sh
new file mode 100644
index 00000000000..d2ae53b7291
--- /dev/null
+++ b/package/base-files/files/lib/upgrade/legacy-sdcard.sh
@@ -0,0 +1,91 @@
+legacy_sdcard_check_image() {
+ local file="$1"
+ local diskdev partdev diff
+
+ export_bootdevice && export_partdevice diskdev 0 || {
+ v "Unable to determine upgrade device"
+ return 1
+ }
+
+ get_partitions "/dev/$diskdev" bootdisk
+
+ v "Extract boot sector from the image"
+ get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
+
+ get_partitions /tmp/image.bs image
+
+ #compare tables
+ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+
+ rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
+
+ if [ -n "$diff" ]; then
+ v "Partition layout has changed. Full image will be written."
+ ask_bool 0 "Abort" && exit 1
+ return 0
+ fi
+}
+
+legacy_sdcard_do_upgrade() {
+ local board=$(board_name)
+ local diskdev partdev diff
+
+ export_bootdevice && export_partdevice diskdev 0 || {
+ v "Unable to determine upgrade device"
+ return 1
+ }
+
+ sync
+
+ if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
+ get_partitions "/dev/$diskdev" bootdisk
+
+ v "Extract boot sector from the image"
+ get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
+
+ get_partitions /tmp/image.bs image
+
+ #compare tables
+ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+ else
+ diff=1
+ fi
+
+ if [ -n "$diff" ]; then
+ get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
+
+ # Separate removal and addtion is necessary; otherwise, partition 1
+ # will be missing if it overlaps with the old partition 2
+ partx -d - "/dev/$diskdev"
+ partx -a - "/dev/$diskdev"
+ else
+ v "Writing bootloader to /dev/$diskdev"
+ get_image_dd "$1" of="$diskdev" bs=512 skip=1 seek=1 count=2048 conv=fsync
+ #iterate over each partition from the image and write it to the boot disk
+ while read part start size; do
+ if export_partdevice partdev $part; then
+ v "Writing image to /dev/$partdev..."
+ get_image_dd "$1" of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
+ else
+ v "Unable to find partition $part device, skipped."
+ fi
+ done < /tmp/partmap.image
+
+ v "Writing new UUID to /dev/$diskdev..."
+ get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
+ fi
+
+ sleep 1
+}
+
+legacy_sdcard_copy_config() {
+ local partdev
+
+ if export_partdevice partdev 1; then
+ mkdir -p /boot
+ [ -f /boot/kernel.img ] || mount -o rw,noatime /dev/$partdev /boot
+ cp -af "$UPGRADE_BACKUP" "/boot/$BACKUP_FILE"
+ sync
+ umount /boot
+ fi
+}
diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh
index faeb3d6fc1d..0a6fd8432d4 100644
--- a/package/base-files/files/lib/upgrade/nand.sh
+++ b/package/base-files/files/lib/upgrade/nand.sh
@@ -7,6 +7,8 @@
CI_KERNPART="${CI_KERNPART:-kernel}"
# 'ubi' partition on NAND contains UBI
+# There are also CI_KERN_UBIPART and CI_ROOT_UBIPART if kernel
+# and rootfs are on separated UBIs.
CI_UBIPART="${CI_UBIPART:-ubi}"
# 'rootfs' UBI volume on NAND contains the rootfs
@@ -26,7 +28,7 @@ ubi_mknod() {
nand_find_volume() {
local ubidevdir ubivoldir
- ubidevdir="/sys/devices/virtual/ubi/$1"
+ ubidevdir="/sys/class/ubi/"
[ ! -d "$ubidevdir" ] && return 1
for ubivoldir in $ubidevdir/${1}_*; do
[ ! -d "$ubivoldir" ] && continue
@@ -39,13 +41,12 @@ nand_find_volume() {
}
nand_find_ubi() {
- local ubidevdir ubidev mtdnum
+ local ubidevdir ubidev mtdnum cmtdnum
mtdnum="$( find_mtd_index $1 )"
[ ! "$mtdnum" ] && return 1
- for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
- [ ! -d "$ubidevdir" ] && continue
+ for ubidevdir in /sys/class/ubi/ubi*; do
+ [ ! -e "$ubidevdir/mtd_num" ] && continue
cmtdnum="$( cat $ubidevdir/mtd_num )"
- [ ! "$mtdnum" ] && continue
if [ "$mtdnum" = "$cmtdnum" ]; then
ubidev=$( basename $ubidevdir )
ubi_mknod "$ubidevdir"
@@ -56,128 +57,175 @@ nand_find_ubi() {
}
nand_get_magic_long() {
- dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
+ (${3}cat "$1" | dd bs=4 "skip=${2:-0}" count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
}
get_magic_long_tar() {
- ( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
+ (tar xO${3}f "$1" "$2" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
}
-identify_magic() {
- local magic=$1
- case "$magic" in
- "55424923")
- echo "ubi"
- ;;
- "31181006")
- echo "ubifs"
- ;;
- "68737173")
- echo "squashfs"
- ;;
- "d00dfeed")
- echo "fit"
- ;;
- "4349"*)
- echo "combined"
- ;;
- *)
- echo "unknown $magic"
- ;;
- esac
-}
-
-
identify() {
- identify_magic $(nand_get_magic_long "$1" "${2:-0}")
+ identify_magic_long $(nand_get_magic_long "$@")
}
identify_tar() {
- identify_magic $(get_magic_long_tar "$1" "$2")
+ identify_magic_long $(get_magic_long_tar "$@")
+}
+
+identify_if_gzip() {
+ if [ "$(identify "$1")" = gzip ]; then echo -n z; fi
}
nand_restore_config() {
- sync
- local ubidev=$( nand_find_ubi $CI_UBIPART )
+ local ubidev=$( nand_find_ubi "${CI_ROOT_UBIPART:-$CI_UBIPART}" )
local ubivol="$( nand_find_volume $ubidev rootfs_data )"
- [ ! "$ubivol" ] &&
- ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
+ if [ ! "$ubivol" ]; then
+ ubivol="$( nand_find_volume $ubidev "$CI_ROOTPART" )"
+ if [ ! "$ubivol" ]; then
+ echo "cannot find ubifs data volume"
+ return 1
+ fi
+ fi
mkdir /tmp/new_root
if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
- echo "mounting ubifs $ubivol failed"
+ echo "cannot mount ubifs volume $ubivol"
rmdir /tmp/new_root
return 1
fi
- mv "$1" "/tmp/new_root/$BACKUP_FILE"
- umount /tmp/new_root
- sync
+ if mv "$1" "/tmp/new_root/$BACKUP_FILE"; then
+ if umount /tmp/new_root; then
+ echo "configuration saved"
+ rmdir /tmp/new_root
+ return 0
+ fi
+ else
+ umount /tmp/new_root
+ fi
+ echo "could not save configuration to ubifs volume $ubivol"
rmdir /tmp/new_root
+ return 1
}
-nand_upgrade_prepare_ubi() {
- local rootfs_length="$1"
- local rootfs_type="$2"
- local rootfs_data_max="$(fw_printenv -n rootfs_data_max 2>/dev/null)"
- [ -n "$rootfs_data_max" ] && rootfs_data_max=$((rootfs_data_max))
+nand_remove_ubiblock() {
+ local ubivol="$1"
- local kernel_length="$3"
- local has_env="${4:-0}"
+ local ubiblk="ubiblock${ubivol:3}"
+ if [ -e "/dev/$ubiblk" ]; then
+ umount "/dev/$ubiblk" 2>/dev/null && echo "unmounted /dev/$ubiblk" || :
+ if ! ubiblock -r "/dev/$ubivol"; then
+ echo "cannot remove $ubiblk"
+ return 1
+ fi
+ fi
+}
- [ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1
+nand_attach_ubi() {
+ local ubipart="$1"
+ local has_env="${2:-0}"
- local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
+ local mtdnum="$( find_mtd_index "$ubipart" )"
if [ ! "$mtdnum" ]; then
- echo "cannot find ubi mtd partition $CI_UBIPART"
+ >&2 echo "cannot find ubi mtd partition $ubipart"
return 1
fi
- local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+ local ubidev="$( nand_find_ubi "$ubipart" )"
if [ ! "$ubidev" ]; then
- ubiattach -m "$mtdnum"
- sync
- ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+ >&2 ubiattach -m "$mtdnum"
+ ubidev="$( nand_find_ubi "$ubipart" )"
+
+ if [ ! "$ubidev" ]; then
+ >&2 ubiformat /dev/mtd$mtdnum -y
+ >&2 ubiattach -m "$mtdnum"
+ ubidev="$( nand_find_ubi "$ubipart" )"
+
+ if [ ! "$ubidev" ]; then
+ >&2 echo "cannot attach ubi mtd partition $ubipart"
+ return 1
+ fi
+
+ if [ "$has_env" -gt 0 ]; then
+ >&2 ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
+ >&2 ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
+ fi
+ fi
fi
- if [ ! "$ubidev" ]; then
- ubiformat /dev/mtd$mtdnum -y
- ubiattach -m "$mtdnum"
- sync
- ubidev="$( nand_find_ubi "$CI_UBIPART" )"
- [ "$has_env" -gt 0 ] && {
- ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
- ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
- }
- fi
+ echo "$ubidev"
+ return 0
+}
- local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
- local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
- local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
+nand_detach_ubi() {
+ local ubipart="$1"
- local ubiblk ubiblkvol
- for ubiblk in /dev/ubiblock*_? ; do
- [ -e "$ubiblk" ] || continue
- echo "removing ubiblock${ubiblk:13}"
- ubiblkvol=ubi${ubiblk:13}
- if ! ubiblock -r /dev/$ubiblkvol; then
- echo "cannot remove $ubiblk"
+ local mtdnum="$( find_mtd_index "$ubipart" )"
+ if [ ! "$mtdnum" ]; then
+ echo "cannot find ubi mtd partition $ubipart"
+ return 1
+ fi
+
+ local ubidev="$( nand_find_ubi "$ubipart" )"
+ if [ "$ubidev" ]; then
+ for ubivol in $(find /dev -name "${ubidev}_*" -maxdepth 1 | sort); do
+ ubivol="${ubivol:5}"
+ nand_remove_ubiblock "$ubivol" || :
+ umount "/dev/$ubivol" && echo "unmounted /dev/$ubivol" || :
+ done
+ if ! ubidetach -m "$mtdnum"; then
+ echo "cannot detach ubi mtd partition $ubipart"
return 1
fi
- done
+ fi
+}
+
+nand_upgrade_prepare_ubi() {
+ local rootfs_length="$1"
+ local rootfs_type="$2"
+ local rootfs_data_max="$(fw_printenv -n rootfs_data_max 2> /dev/null)"
+ [ -n "$rootfs_data_max" ] && rootfs_data_max=$((rootfs_data_max))
+
+ local kernel_length="$3"
+ local has_env="${4:-0}"
+ local kern_ubidev
+ local root_ubidev
+
+ [ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1
+
+ if [ -n "$CI_KERN_UBIPART" -a -n "$CI_ROOT_UBIPART" ]; then
+ kern_ubidev="$( nand_attach_ubi "$CI_KERN_UBIPART" "$has_env" )"
+ [ -n "$kern_ubidev" ] || return 1
+ root_ubidev="$( nand_attach_ubi "$CI_ROOT_UBIPART" )"
+ [ -n "$root_ubidev" ] || return 1
+ else
+ kern_ubidev="$( nand_attach_ubi "$CI_UBIPART" "$has_env" )"
+ [ -n "$kern_ubidev" ] || return 1
+ root_ubidev="$kern_ubidev"
+ fi
+
+ local kern_ubivol="$( nand_find_volume $kern_ubidev "$CI_KERNPART" )"
+ local root_ubivol="$( nand_find_volume $root_ubidev "$CI_ROOTPART" )"
+ local data_ubivol="$( nand_find_volume $root_ubidev rootfs_data )"
+ [ "$root_ubivol" = "$kern_ubivol" ] && root_ubivol=
+
+ # remove ubiblocks
+ [ "$kern_ubivol" ] && { nand_remove_ubiblock $kern_ubivol || return 1; }
+ [ "$root_ubivol" ] && { nand_remove_ubiblock $root_ubivol || return 1; }
+ [ "$data_ubivol" ] && { nand_remove_ubiblock $data_ubivol || return 1; }
# kill volumes
- [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
- [ "$root_ubivol" -a "$root_ubivol" != "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
- [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
+ [ "$kern_ubivol" ] && ubirmvol /dev/$kern_ubidev -N "$CI_KERNPART" || :
+ [ "$root_ubivol" ] && ubirmvol /dev/$root_ubidev -N "$CI_ROOTPART" || :
+ [ "$data_ubivol" ] && ubirmvol /dev/$root_ubidev -N rootfs_data || :
- # update kernel
+ # create kernel vol
if [ -n "$kernel_length" ]; then
- if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
+ if ! ubimkvol /dev/$kern_ubidev -N "$CI_KERNPART" -s $kernel_length; then
echo "cannot create kernel volume"
return 1;
fi
fi
- # update rootfs
+ # create rootfs vol
if [ -n "$rootfs_length" ]; then
local rootfs_size_param
if [ "$rootfs_type" = "ubifs" ]; then
@@ -185,157 +233,224 @@ nand_upgrade_prepare_ubi() {
else
rootfs_size_param="-s $rootfs_length"
fi
- if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then
+ if ! ubimkvol /dev/$root_ubidev -N "$CI_ROOTPART" $rootfs_size_param; then
echo "cannot create rootfs volume"
return 1;
fi
fi
- # create rootfs_data for non-ubifs rootfs
+ # create rootfs_data vol for non-ubifs rootfs
if [ "$rootfs_type" != "ubifs" ]; then
- local availeb=$(cat /sys/devices/virtual/ubi/$ubidev/avail_eraseblocks)
- local ebsize=$(cat /sys/devices/virtual/ubi/$ubidev/eraseblock_size)
- local avail_size=$((availeb * ebsize))
local rootfs_data_size_param="-m"
- if [ -n "$rootfs_data_max" ] &&
- [ "$rootfs_data_max" != "0" ] &&
- [ "$rootfs_data_max" -le "$avail_size" ]; then
+ if [ -n "$rootfs_data_max" ]; then
rootfs_data_size_param="-s $rootfs_data_max"
fi
- if ! ubimkvol /dev/$ubidev -N rootfs_data $rootfs_data_size_param; then
- echo "cannot initialize rootfs_data volume"
- return 1
+ if ! ubimkvol /dev/$root_ubidev -N rootfs_data $rootfs_data_size_param; then
+ if ! ubimkvol /dev/$root_ubidev -N rootfs_data -m; then
+ echo "cannot initialize rootfs_data volume"
+ return 1
+ fi
fi
fi
- sync
- return 0
-}
-nand_do_upgrade_success() {
- local conf_tar="/tmp/sysupgrade.tgz"
-
- sync
- [ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
- echo "sysupgrade successful"
- umount -a
- reboot -f
+ return 0
}
-# Flash the UBI image to MTD partition
+# Write the UBI image to MTD ubi partition
nand_upgrade_ubinized() {
local ubi_file="$1"
- local mtdnum="$(find_mtd_index "$CI_UBIPART")"
+ local gz="$2"
- [ ! "$mtdnum" ] && {
- CI_UBIPART="rootfs"
- mtdnum="$(find_mtd_index "$CI_UBIPART")"
- }
+ local ubi_length=$( (${gz}cat "$ubi_file" | wc -c) 2> /dev/null)
- if [ ! "$mtdnum" ]; then
- echo "cannot find mtd device $CI_UBIPART"
- umount -a
- reboot -f
- fi
+ nand_detach_ubi "$CI_UBIPART" || return 1
- local mtddev="/dev/mtd${mtdnum}"
- ubidetach -p "${mtddev}" || true
- sync
- ubiformat "${mtddev}" -y -f "${ubi_file}"
- ubiattach -p "${mtddev}"
- nand_do_upgrade_success
+ local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
+ ${gz}cat "$ubi_file" | ubiformat "/dev/mtd$mtdnum" -S "$ubi_length" -y -f - && ubiattach -m "$mtdnum"
}
-# Write the UBIFS image to UBI volume
+# Write the UBIFS image to UBI rootfs volume
nand_upgrade_ubifs() {
- local rootfs_length=$( (cat $1 | wc -c) 2> /dev/null)
+ local ubifs_file="$1"
+ local gz="$2"
- nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "" ""
+ local ubifs_length=$( (${gz}cat "$ubifs_file" | wc -c) 2> /dev/null)
- local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
- local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
- ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
+ nand_upgrade_prepare_ubi "$ubifs_length" "ubifs" "" "" || return 1
- nand_do_upgrade_success
+ local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+ local root_ubivol="$(nand_find_volume $ubidev "$CI_ROOTPART")"
+ ${gz}cat "$ubifs_file" | ubiupdatevol /dev/$root_ubivol -s "$ubifs_length" -
}
+# Write the FIT image to UBI kernel volume
nand_upgrade_fit() {
local fit_file="$1"
- local fit_length="$(wc -c < "$fit_file")"
+ local gz="$2"
+
+ local fit_length=$( (${gz}cat "$fit_file" | wc -c) 2> /dev/null)
- nand_upgrade_prepare_ubi "" "" "$fit_length" "1"
+ nand_upgrade_prepare_ubi "" "" "$fit_length" "1" || return 1
local fit_ubidev="$(nand_find_ubi "$CI_UBIPART")"
local fit_ubivol="$(nand_find_volume $fit_ubidev "$CI_KERNPART")"
- ubiupdatevol /dev/$fit_ubivol -s $fit_length $fit_file
-
- nand_do_upgrade_success
+ ${gz}cat "$fit_file" | ubiupdatevol /dev/$fit_ubivol -s "$fit_length" -
}
+# Write images in the TAR file to MTD partitions and/or UBI volumes as required
nand_upgrade_tar() {
local tar_file="$1"
- local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
+ local gz="$2"
+ local jffs2_markers="${CI_JFFS2_CLEAN_MARKERS:-0}"
+
+ # WARNING: This fails if tar contains more than one 'sysupgrade-*' directory.
+ local board_dir="$(tar t${gz}f "$tar_file" | grep -m 1 '^sysupgrade-.*/$')"
+ board_dir="${board_dir%/}"
+
+ local kernel_mtd kernel_length
+ if [ "$CI_KERNPART" != "none" ]; then
+ kernel_mtd="$(find_mtd_index "$CI_KERNPART")"
+ kernel_length=$( (tar xO${gz}f "$tar_file" "$board_dir/kernel" | wc -c) 2> /dev/null)
+ [ "$kernel_length" = 0 ] && kernel_length=
+ fi
+ local rootfs_length=$( (tar xO${gz}f "$tar_file" "$board_dir/root" | wc -c) 2> /dev/null)
+ [ "$rootfs_length" = 0 ] && rootfs_length=
+ local rootfs_type
+ [ "$rootfs_length" ] && rootfs_type="$(identify_tar "$tar_file" "$board_dir/root" "$gz")"
+
+ local ubi_kernel_length
+ if [ "$kernel_length" ]; then
+ if [ "$kernel_mtd" ]; then
+ # On some devices, the raw kernel and ubi partitions overlap.
+ # These devices brick if the kernel partition is erased.
+ # Hence only invalidate kernel for now.
+ dd if=/dev/zero bs=4096 count=1 2> /dev/null | \
+ mtd write - "$CI_KERNPART"
+ else
+ ubi_kernel_length="$kernel_length"
+ fi
+ fi
- local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$')
- board_dir=${board_dir%/}
+ local has_env=0
+ nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$ubi_kernel_length" "$has_env" || return 1
- kernel_length=$( (tar xf "$tar_file" ${board_dir}/kernel -O | wc -c) 2> /dev/null)
- local has_rootfs=0
- local rootfs_length
- local rootfs_type
+ if [ "$rootfs_length" ]; then
+ local ubidev="$( nand_find_ubi "${CI_ROOT_UBIPART:-$CI_UBIPART}" )"
+ local root_ubivol="$( nand_find_volume $ubidev "$CI_ROOTPART" )"
+ tar xO${gz}f "$tar_file" "$board_dir/root" | \
+ ubiupdatevol /dev/$root_ubivol -s "$rootfs_length" -
+ fi
+ if [ "$kernel_length" ]; then
+ if [ "$kernel_mtd" ]; then
+ if [ "$jffs2_markers" = 1 ]; then
+ flash_erase -j "/dev/mtd${kernel_mtd}" 0 0
+ tar xO${gz}f "$tar_file" "$board_dir/kernel" | \
+ nandwrite "/dev/mtd${kernel_mtd}" -
+ else
+ tar xO${gz}f "$tar_file" "$board_dir/kernel" | \
+ mtd write - "$CI_KERNPART"
+ fi
+ else
+ local ubidev="$( nand_find_ubi "${CI_KERN_UBIPART:-$CI_UBIPART}" )"
+ local kern_ubivol="$( nand_find_volume $ubidev "$CI_KERNPART" )"
+ tar xO${gz}f "$tar_file" "$board_dir/kernel" | \
+ ubiupdatevol /dev/$kern_ubivol -s "$kernel_length" -
+ fi
+ fi
- tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1
- [ "$has_rootfs" = "1" ] && {
- rootfs_length=$( (tar xf "$tar_file" ${board_dir}/root -O | wc -c) 2> /dev/null)
- rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
- }
+ return 0
+}
- local has_kernel=1
- local has_env=0
+nand_verify_if_gzip_file() {
+ local file="$1"
+ local gz="$2"
- [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
- tar xf "$tar_file" ${board_dir}/kernel -O | mtd write - $CI_KERNPART
- }
- [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=
+ if [ "$gz" = z ]; then
+ echo "verifying compressed sysupgrade file integrity"
+ if ! gzip -t "$file"; then
+ echo "corrupted compressed sysupgrade file"
+ return 1
+ fi
+ fi
+}
- nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "${has_kernel:+$kernel_length}" "$has_env"
+nand_verify_tar_file() {
+ local file="$1"
+ local gz="$2"
- local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
- [ "$has_kernel" = "1" ] && {
- local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
- tar xf "$tar_file" ${board_dir}/kernel -O | \
- ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
- }
-
- [ "$has_rootfs" = "1" ] && {
- local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
- tar xf "$tar_file" ${board_dir}/root -O | \
- ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
- }
- nand_do_upgrade_success
+ echo "verifying sysupgrade tar file integrity"
+ if ! tar xO${gz}f "$file" > /dev/null; then
+ echo "corrupted sysupgrade tar file"
+ return 1
+ fi
}
-# Recognize type of passed file and start the upgrade process
-nand_do_upgrade() {
- local file_type=$(identify $1)
+nand_do_flash_file() {
+ local file="$1"
+
+ local gz="$(identify_if_gzip "$file")"
+ local file_type="$(identify "$file" "" "$gz")"
- [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
+ [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART=rootfs
case "$file_type" in
- "fit") nand_upgrade_fit $1;;
- "ubi") nand_upgrade_ubinized $1;;
- "ubifs") nand_upgrade_ubifs $1;;
- *) nand_upgrade_tar $1;;
+ "fit")
+ nand_verify_if_gzip_file "$file" "$gz" || return 1
+ nand_upgrade_fit "$file" "$gz"
+ ;;
+ "ubi")
+ nand_verify_if_gzip_file "$file" "$gz" || return 1
+ nand_upgrade_ubinized "$file" "$gz"
+ ;;
+ "ubifs")
+ nand_verify_if_gzip_file "$file" "$gz" || return 1
+ nand_upgrade_ubifs "$file" "$gz"
+ ;;
+ *)
+ nand_verify_tar_file "$file" "$gz" || return 1
+ nand_upgrade_tar "$file" "$gz"
+ ;;
esac
}
-# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts
-# 3 types of files:
-# 1) UBI - should contain an ubinized image, header is checked for the proper
-# MAGIC
-# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume,
-# header is checked for the proper MAGIC
-# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty
-# "CONTROL" file (at this point its content isn't verified)
+nand_do_restore_config() {
+ local conf_tar="/tmp/sysupgrade.tgz"
+ [ ! -f "$conf_tar" ] || nand_restore_config "$conf_tar"
+}
+
+# Recognize type of passed file and start the upgrade process
+nand_do_upgrade() {
+ local file="$1"
+
+ sync
+ nand_do_flash_file "$file" && nand_do_upgrade_success
+ nand_do_upgrade_failed
+}
+
+nand_do_upgrade_success() {
+ if nand_do_restore_config && sync; then
+ echo "sysupgrade successful"
+ umount -a
+ reboot -f
+ fi
+ nand_do_upgrade_failed
+}
+
+nand_do_upgrade_failed() {
+ sync
+ echo "sysupgrade failed"
+ # Should we reboot or bring up some failsafe mode instead?
+ umount -a
+ reboot -f
+}
+
+# Check if passed file is a valid one for NAND sysupgrade.
+# Currently it accepts 4 types of files:
+# 1) UBI: a ubinized image containing required UBI volumes.
+# 2) UBIFS: a UBIFS rootfs volume image.
+# 3) FIT: a FIT image containing kernel and rootfs.
+# 4) TAR: an archive that includes directory "sysupgrade-${BOARD_NAME}" containing
+# a non-empty "CONTROL" file and required partition and/or volume images.
#
# You usually want to call this function in platform_check_image.
#
@@ -343,14 +458,25 @@ nand_do_upgrade() {
# $(2): file to be checked
nand_do_platform_check() {
local board_name="$1"
- local tar_file="$2"
- local control_length=$( (tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null)
- local file_type="$(identify $2)"
+ local file="$2"
- [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" -a "$file_type" != "fit" ] && {
- echo "Invalid sysupgrade file."
- return 1
- }
+ local gz="$(identify_if_gzip "$file")"
+ local file_type="$(identify "$file" "" "$gz")"
+ local control_length=$( (tar xO${gz}f "$file" "sysupgrade-${board_name//,/_}/CONTROL" | wc -c) 2> /dev/null)
+
+ if [ "$control_length" = 0 ]; then
+ control_length=$( (tar xO${gz}f "$file" "sysupgrade-${board_name//_/,}/CONTROL" | wc -c) 2> /dev/null)
+ fi
+
+ if [ "$control_length" != 0 ]; then
+ nand_verify_tar_file "$file" "$gz" || return 1
+ else
+ nand_verify_if_gzip_file "$file" "$gz" || return 1
+ if [ "$file_type" != "fit" -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ]; then
+ echo "invalid sysupgrade file"
+ return 1
+ fi
+ fi
return 0
}
diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2
index 13c3622f382..5ce0b3549cf 100755
--- a/package/base-files/files/lib/upgrade/stage2
+++ b/package/base-files/files/lib/upgrade/stage2
@@ -33,26 +33,32 @@ supivot() { # <new_root> <old_root>
}
switch_to_ramfs() {
- RAMFS_COPY_LOSETUP="$(command -v losetup)"
+ RAMFS_COPY_LOSETUP="$(command -v /usr/sbin/losetup)"
RAMFS_COPY_LVM="$(command -v lvm)"
for binary in \
/bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \
pivot_root mount_root reboot sync kill sleep \
- md5sum hexdump cat zcat dd tar \
+ md5sum hexdump cat zcat dd tar gzip \
ls basename find cp mv rm mkdir rmdir mknod touch chmod \
- '[' printf wc grep awk sed cut \
+ '[' printf wc grep awk sed cut sort tail \
mtd partx losetup mkfs.ext4 nandwrite flash_erase \
ubiupdatevol ubiattach ubiblock ubiformat \
ubidetach ubirsvol ubirmvol ubimkvol \
snapshot snapshot_tool date logger \
+ /usr/sbin/fw_printenv /usr/bin/fwtool \
$RAMFS_COPY_LOSETUP $RAMFS_COPY_LVM \
$RAMFS_COPY_BIN
do
local file="$(command -v "$binary" 2>/dev/null)"
[ -n "$file" ] && install_bin "$file"
done
- install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh /lib/upgrade/do_stage2 /usr/share/libubox/jshn.sh $RAMFS_COPY_DATA
+ install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh \
+ /lib/upgrade/*.sh /lib/upgrade/do_stage2 \
+ /usr/share/libubox/jshn.sh /usr/sbin/fw_setenv \
+ /etc/fw_env.config $RAMFS_COPY_DATA
+
+ mkdir -p $RAM_ROOT/var/lock
[ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
@@ -64,6 +70,10 @@ switch_to_ramfs() {
/bin/mount -o remount,ro /mnt
/bin/umount -l /mnt
+ grep -e "^/dev/dm-.*" -e "^/dev/loop.*" /proc/mounts | while read bdev mp _r; do
+ umount $mp
+ done
+
[ "$RAMFS_COPY_LOSETUP" ] && losetup -D
[ "$RAMFS_COPY_LVM" ] && {
mkdir -p /tmp/lvm/cache
@@ -93,12 +103,15 @@ kill_remaining() { # [ <signal> [ <loop> ] ]
[ -f "$stat" ] || continue
local pid name state ppid rest
- read pid name state ppid rest < $stat
- name="${name#(}"; name="${name%)}"
+ read pid rest < $stat
+ name="${rest#\(}" ; rest="${name##*\) }" ; name="${name%\)*}"
+ set -- $rest ; state="$1" ; ppid="$2"
# Skip PID1, our parent, ourself and our children
[ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue
+ [ -f "/proc/$pid/cmdline" ] || continue
+
local cmdline
read cmdline < /proc/$pid/cmdline
@@ -108,7 +121,7 @@ kill_remaining() { # [ <signal> [ <loop> ] ]
v "Sending signal $sig to $name ($pid)"
kill -$sig $pid 2>/dev/null
- [ $loop -eq 1 ] && run=true
+ [ $loop -eq 1 ] && sleep 2 && run=true
done
let loop_limit--