aboutsummaryrefslogtreecommitdiffstats
path: root/package/base-files
diff options
context:
space:
mode:
Diffstat (limited to 'package/base-files')
-rw-r--r--package/base-files/Makefile81
-rwxr-xr-xpackage/base-files/files/bin/config_generate12
-rwxr-xr-xpackage/base-files/files/bin/ipcalc.sh195
-rwxr-xr-xpackage/base-files/files/etc/init.d/boot9
-rwxr-xr-xpackage/base-files/files/etc/init.d/led63
-rwxr-xr-xpackage/base-files/files/etc/init.d/sysfixtime22
-rw-r--r--package/base-files/files/etc/profile2
-rwxr-xr-xpackage/base-files/files/etc/rc.common14
-rw-r--r--package/base-files/files/etc/shadow2
-rw-r--r--package/base-files/files/etc/shinit21
-rw-r--r--package/base-files/files/etc/sysctl.d/10-default.conf1
-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
-rwxr-xr-xpackage/base-files/files/sbin/sysupgrade61
-rwxr-xr-xpackage/base-files/files/sbin/wifi254
-rw-r--r--package/base-files/image-config.in7
31 files changed, 1521 insertions, 669 deletions
diff --git a/package/base-files/Makefile b/package/base-files/Makefile
index 5f816a0d1bd..67fc5d29c1d 100644
--- a/package/base-files/Makefile
+++ b/package/base-files/Makefile
@@ -23,6 +23,8 @@ PKG_LICENSE:=GPL-2.0
PKG_CONFIG_DEPENDS += \
CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE \
CONFIG_NAND_SUPPORT \
+ CONFIG_LEGACY_SDCARD_SUPPORT \
+ CONFIG_EMMC_SUPPORT \
CONFIG_CLEAN_IPKG \
CONFIG_PER_FEED_REPO \
$(foreach feed,$(FEEDS_AVAILABLE),CONFIG_FEED_$(feed))
@@ -87,12 +89,28 @@ define ImageConfigOptions
echo 'pi_preinit_net_messages="$(CONFIG_TARGET_PREINIT_SHOW_NETMSG)"' >>$(1)/lib/preinit/00_preinit.conf
echo 'pi_preinit_no_failsafe_netmsg="$(CONFIG_TARGET_PREINIT_SUPPRESS_FAILSAFE_NETMSG)"' >>$(1)/lib/preinit/00_preinit.conf
echo 'pi_preinit_no_failsafe="$(CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE)"' >>$(1)/lib/preinit/00_preinit.conf
+ifeq ($(CONFIG_TARGET_DEFAULT_LAN_IP_FROM_PREINIT),y)
+ mkdir -p $(1)/etc/board.d
+ echo '. /lib/functions/uci-defaults.sh' >$(1)/etc/board.d/99-lan-ip
+ echo 'logger -t 99-lan-ip "setting custom default LAN IP"' >>$(1)/etc/board.d/99-lan-ip
+ echo 'board_config_update' >>$(1)/etc/board.d/99-lan-ip
+ echo 'json_select network' >>$(1)/etc/board.d/99-lan-ip
+ echo 'json_select lan' >>$(1)/etc/board.d/99-lan-ip
+ echo 'json_add_string ipaddr $(if $(CONFIG_TARGET_PREINIT_IP),$(CONFIG_TARGET_PREINIT_IP),"192.168.1.1")' >>$(1)/etc/board.d/99-lan-ip
+ echo 'json_add_string netmask $(if $(CONFIG_TARGET_PREINIT_NETMASK),$(CONFIG_TARGET_PREINIT_NETMASK),"255.255.255.0")' >>$(1)/etc/board.d/99-lan-ip
+ echo 'json_select ..' >>$(1)/etc/board.d/99-lan-ip
+ echo 'json_select ..' >>$(1)/etc/board.d/99-lan-ip
+ echo 'board_config_flush' >>$(1)/etc/board.d/99-lan-ip
+endif
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
+define Build/Quilt
+endef
+
define Build/Compile/Default
endef
@@ -123,10 +141,25 @@ ifeq ($(CONFIG_NAND_SUPPORT),)
endef
endif
+ifeq ($(CONFIG_EMMC_SUPPORT),)
+ define Package/base-files/emmc-support
+ rm -f $(1)/lib/upgrade/emmc.sh
+ endef
+endif
+
+ifeq ($(CONFIG_LEGACY_SDCARD_SUPPORT),)
+ define Package/base-files/legacy-sdcard-support
+ rm -f $(1)/lib/upgrade/legacy-sdcard.sh
+ endef
+endif
+
+
define Package/base-files/install
$(CP) ./files/* $(1)/
$(Package/base-files/install-key)
$(Package/base-files/nand-support)
+ $(Package/base-files/legacy-sdcard-support)
+ $(Package/base-files/emmc-support)
if [ -d $(GENERIC_PLATFORM_DIR)/base-files/. ]; then \
$(CP) $(GENERIC_PLATFORM_DIR)/base-files/* $(1)/; \
fi
@@ -141,40 +174,46 @@ define Package/base-files/install
$(VERSION_SED_SCRIPT) \
$(1)/etc/banner \
+ $(1)/etc/device_info \
+ $(1)/etc/openwrt_release \
$(1)/etc/openwrt_version \
$(1)/usr/lib/os-release
- $(VERSION_SED_SCRIPT) \
- $(1)/etc/openwrt_release \
- $(1)/etc/device_info \
- $(1)/usr/lib/os-release
$(SED) "s#%PATH%#$(TARGET_INIT_PATH)#g" \
$(1)/sbin/hotplug-call \
$(1)/etc/preinit \
$(1)/etc/profile
- mkdir -p $(1)/CONTROL
- mkdir -p $(1)/dev
- mkdir -p $(1)/etc/config
- mkdir -p $(1)/etc/crontabs
- mkdir -p $(1)/etc/rc.d
- mkdir -p $(1)/overlay
- mkdir -p $(1)/lib/firmware
+ mkdir -p \
+ $(1)/CONTROL \
+ $(1)/dev \
+ $(1)/etc/config \
+ $(1)/etc/crontabs \
+ $(1)/etc/rc.d \
+ $(1)/overlay \
+ $(1)/lib/firmware \
+ $(1)/mnt \
+ $(1)/proc \
+ $(1)/tmp \
+ $(1)/usr/lib \
+ $(1)/usr/bin \
+ $(1)/sys \
+ $(1)/www
+ mkdir -p -m 750 \
+ $(1)/root
+
+ $(LN) /proc/mounts $(1)/etc/mtab
$(if $(LIB_SUFFIX),-$(LN) lib $(1)/lib$(LIB_SUFFIX))
- mkdir -p $(1)/mnt
- mkdir -p $(1)/proc
- mkdir -p $(1)/tmp
- mkdir -p $(1)/usr/lib
$(if $(LIB_SUFFIX),-$(LN) lib $(1)/usr/lib$(LIB_SUFFIX))
- mkdir -p $(1)/usr/bin
- mkdir -p $(1)/sys
- mkdir -p $(1)/www
- mkdir -p $(1)/root
- $(LN) /proc/mounts $(1)/etc/mtab
+
+ifneq ($(CONFIG_TARGET_ROOTFS_PERSIST_VAR),y)
rm -f $(1)/var
$(LN) tmp $(1)/var
- mkdir -p $(1)/etc
+else
+ mkdir -p $(1)/var
+ $(LN) /tmp/run $(1)/var/run
+endif
$(LN) /tmp/resolv.conf /tmp/TZ /tmp/localtime $(1)/etc/
chmod 0600 $(1)/etc/shadow
diff --git a/package/base-files/files/bin/config_generate b/package/base-files/files/bin/config_generate
index 596fcf41fad..be21d0079a8 100755
--- a/package/base-files/files/bin/config_generate
+++ b/package/base-files/files/bin/config_generate
@@ -96,7 +96,7 @@ generate_network() {
json_select network
json_select "$1"
- json_get_vars device macaddr protocol ipaddr netmask vlan
+ json_get_vars device macaddr metric protocol ipaddr netmask vlan
json_get_values ports ports
json_select ..
json_select ..
@@ -154,6 +154,7 @@ generate_network() {
set network.$1='interface'
set network.$1.type='$type'
set network.$1.device='$device'
+ set network.$1.metric='$metric'
set network.$1.proto='none'
EOF
@@ -206,6 +207,15 @@ generate_network() {
EOF
}
;;
+
+ ncm|\
+ qmi|\
+ mbim)
+ uci -q batch <<-EOF
+ set network.$1.proto='${protocol}'
+ set network.$1.pdptype='ipv4'
+ EOF
+ ;;
esac
}
diff --git a/package/base-files/files/bin/ipcalc.sh b/package/base-files/files/bin/ipcalc.sh
index 5d5eac3ea80..9e2702c60d2 100755
--- a/package/base-files/files/bin/ipcalc.sh
+++ b/package/base-files/files/bin/ipcalc.sh
@@ -1,71 +1,140 @@
#!/bin/sh
-awk -f - $* <<EOF
-function bitcount(c) {
- c=and(rshift(c, 1),0x55555555)+and(c,0x55555555)
- c=and(rshift(c, 2),0x33333333)+and(c,0x33333333)
- c=and(rshift(c, 4),0x0f0f0f0f)+and(c,0x0f0f0f0f)
- c=and(rshift(c, 8),0x00ff00ff)+and(c,0x00ff00ff)
- c=and(rshift(c,16),0x0000ffff)+and(c,0x0000ffff)
- return c
-}
+. /lib/functions/ipv4.sh
-function ip2int(ip) {
- for (ret=0,n=split(ip,a,"\."),x=1;x<=n;x++) ret=or(lshift(ret,8),a[x])
- return ret
-}
+PROG="$(basename "$0")"
-function int2ip(ip,ret,x) {
- ret=and(ip,255)
- ip=rshift(ip,8)
- for(;x<3;ret=and(ip,255)"."ret,ip=rshift(ip,8),x++);
- return ret
-}
+# wrapper to convert an integer to an address, unless we're using
+# decimal output format.
+# hook for library function
+_ip2str() {
+ local var="$1" n="$2"
+ assert_uint32 "$n" || exit 1
-function compl32(v) {
- ret=xor(v, 0xffffffff)
- return ret
+ if [ "$decimal" -ne 0 ]; then
+ export -- "$var=$n"
+ elif [ "$hexadecimal" -ne 0 ]; then
+ export -- "$var=$(printf "%x" "$n")"
+ else
+ ip2str "$@"
+ fi
}
-BEGIN {
- slpos=index(ARGV[1],"/")
- if (slpos == 0) {
- ipaddr=ip2int(ARGV[1])
- dotpos=index(ARGV[2],".")
- if (dotpos == 0)
- netmask=compl32(2**(32-int(ARGV[2]))-1)
- else
- netmask=ip2int(ARGV[2])
- } else {
- ipaddr=ip2int(substr(ARGV[1],0,slpos-1))
- netmask=compl32(2**(32-int(substr(ARGV[1],slpos+1)))-1)
- ARGV[4]=ARGV[3]
- ARGV[3]=ARGV[2]
- }
-
- network=and(ipaddr,netmask)
- broadcast=or(network,compl32(netmask))
-
- start=or(network,and(ip2int(ARGV[3]),compl32(netmask)))
- limit=network+1
- if (start<limit) start=limit
-
- end=start+ARGV[4]
- limit=or(network,compl32(netmask))-1
- if (end>limit) end=limit
-
- print "IP="int2ip(ipaddr)
- print "NETMASK="int2ip(netmask)
- print "BROADCAST="int2ip(broadcast)
- print "NETWORK="int2ip(network)
- print "PREFIX="32-bitcount(compl32(netmask))
-
- # range calculations:
- # ipcalc <ip> <netmask> <start> <num>
-
- if (ARGC > 3) {
- print "START="int2ip(start)
- print "END="int2ip(end)
- }
+usage() {
+ echo "Usage: $PROG [ -d | -x ] address/prefix [ start limit ]" >&2
+ exit 1
}
-EOF
+
+decimal=0
+hexadecimal=0
+if [ "$1" = "-d" ]; then
+ decimal=1
+ shift
+elif [ "$1" = "-x" ]; then
+ hexadecimal=1
+ shift
+fi
+
+if [ $# -eq 0 ]; then
+ usage
+fi
+
+case "$1" in
+*/*.*)
+ # data is n.n.n.n/m.m.m.m format, like on a Cisco router
+ str2ip ipaddr "${1%/*}" || exit 1
+ str2ip netmask "${1#*/}" || exit 1
+ netmask2prefix prefix "$netmask" || exit 1
+ shift
+ ;;
+*/*)
+ # more modern prefix notation of n.n.n.n/p
+ str2ip ipaddr "${1%/*}" || exit 1
+ prefix="${1#*/}"
+ assert_uint32 "$prefix" || exit 1
+ if [ "$prefix" -gt 32 ]; then
+ printf "Prefix out of range (%s)\n" "$prefix" >&2
+ exit 1
+ fi
+ prefix2netmask netmask "$prefix" || exit 1
+ shift
+ ;;
+*)
+ # address and netmask as two separate arguments
+ str2ip ipaddr "$1" || exit 1
+ str2ip netmask "$2" || exit 1
+ netmask2prefix prefix "$netmask" || exit 1
+ shift 2
+ ;;
+esac
+
+# we either have no arguments left, or we have a range start and length
+if [ $# -ne 0 ] && [ $# -ne 2 ]; then
+ usage
+fi
+
+# complement of the netmask, i.e. the hostmask
+hostmask=$((netmask ^ 0xffffffff))
+network=$((ipaddr & netmask))
+broadcast=$((network | hostmask))
+count=$((hostmask + 1))
+
+_ip2str IP "$ipaddr"
+_ip2str NETMASK "$netmask"
+_ip2str NETWORK "$network"
+
+echo "IP=$IP"
+echo "NETMASK=$NETMASK"
+# don't include this-network or broadcast addresses
+if [ "$prefix" -le 30 ]; then
+ _ip2str BROADCAST "$broadcast"
+ echo "BROADCAST=$BROADCAST"
+fi
+echo "NETWORK=$NETWORK"
+echo "PREFIX=$prefix"
+echo "COUNT=$count"
+
+# if there's no range, we're done
+[ $# -eq 0 ] && exit 0
+
+if [ "$prefix" -le 30 ]; then
+ lower=$((network + 1))
+else
+ lower="$network"
+fi
+
+start="$1"
+assert_uint32 "$start" || exit 1
+start=$((network | (start & hostmask)))
+[ "$start" -lt "$lower" ] && start="$lower"
+[ "$start" -eq "$ipaddr" ] && start=$((start + 1))
+
+if [ "$prefix" -le 30 ]; then
+ upper=$(((network | hostmask) - 1))
+else
+ upper="$network"
+fi
+
+range="$2"
+assert_uint32 "$range" || exit 1
+end=$((start + range - 1))
+[ "$end" -gt "$upper" ] && end="$upper"
+[ "$end" -eq "$ipaddr" ] && end=$((end - 1))
+
+if [ "$start" -gt "$end" ]; then
+ echo "network ($NETWORK/$prefix) too small" >&2
+ exit 1
+fi
+
+_ip2str START "$start"
+_ip2str END "$end"
+
+if [ "$start" -le "$ipaddr" ] && [ "$ipaddr" -le "$end" ]; then
+ echo "error: address $IP inside range $START..$END" >&2
+ exit 1
+fi
+
+echo "START=$START"
+echo "END=$END"
+
+exit 0
diff --git a/package/base-files/files/etc/init.d/boot b/package/base-files/files/etc/init.d/boot
index a1e8e828dd2..d17754d0879 100755
--- a/package/base-files/files/etc/init.d/boot
+++ b/package/base-files/files/etc/init.d/boot
@@ -21,9 +21,10 @@ boot() {
[ -f /proc/mounts ] || /sbin/mount_root
[ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc
- mkdir -p /var/run
- mkdir -p /var/log
mkdir -p /var/lock
+ chmod 1777 /var/lock
+ mkdir -p /var/log
+ mkdir -p /var/run
mkdir -p /var/state
mkdir -p /var/tmp
mkdir -p /tmp/.uci
@@ -38,6 +39,7 @@ boot() {
grep -q pstore /proc/filesystems && /bin/mount -o noatime -t pstore pstore /sys/fs/pstore
[ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe
+ touch /tmp/.config_pending
/sbin/kmodloader
[ ! -f /etc/config/wireless ] && {
@@ -46,7 +48,10 @@ boot() {
}
/bin/config_generate
+ rm -f /tmp/.config_pending
+ /sbin/wifi config
uci_apply_defaults
+ sync
# temporary hack until configd exists
/sbin/reload_config
diff --git a/package/base-files/files/etc/init.d/led b/package/base-files/files/etc/init.d/led
index 51cb8b51784..ea2688cab29 100755
--- a/package/base-files/files/etc/init.d/led
+++ b/package/base-files/files/etc/init.d/led
@@ -3,6 +3,39 @@
START=96
+led_color_set() {
+ local cfg="$1"
+ local sysfs="$2"
+
+ local max_b
+ local colors
+ local color
+ local multi_intensity
+ local value
+ local write
+
+ [ -e /sys/class/leds/${sysfs}/multi_intensity ] || return
+ [ -e /sys/class/leds/${sysfs}/multi_index ] || return
+
+ max_b="$(cat /sys/class/leds/${sysfs}/max_brightness)"
+ colors="$(cat /sys/class/leds/${sysfs}/multi_index | tr " " "\n")"
+ multi_intensity=""
+ for color in $colors; do
+ config_get value $1 "color_${color}" "0"
+ [ "$value" -gt 0 ] && write=1
+ [ "$value" -gt "$max_b" ] && value="$max_b"
+ multi_intensity="${multi_intensity}${value} "
+ done
+
+ # Check if any color is configured
+ [ "$write" = 1 ] || return
+ # Remove last whitespace
+ multi_intensity="${multi_intensity:0:-1}"
+
+ echo "setting '${name}' led color to '${multi_intensity}'"
+ echo "${multi_intensity}" > /sys/class/leds/${sysfs}/multi_intensity
+}
+
load_led() {
local name
local sysfs
@@ -29,7 +62,7 @@ load_led() {
config_get delay $1 delay "150"
config_get message $1 message ""
config_get gpio $1 gpio "0"
- config_get inverted $1 inverted "0"
+ config_get_bool inverted $1 inverted "0"
# execute application led trigger
[ -f "/usr/libexec/led-trigger/${trigger}" ] && {
@@ -49,26 +82,38 @@ load_led() {
[ -e /sys/class/leds/${sysfs}/brightness ] && {
echo "setting up led ${name}"
- printf "%s %s %d\n" \
+ printf "%s %s %d" \
"$sysfs" \
"$(sed -ne 's/^.*\[\(.*\)\].*$/\1/p' /sys/class/leds/${sysfs}/trigger)" \
"$(cat /sys/class/leds/${sysfs}/brightness)" \
>> /var/run/led.state
+ # Save default color if supported
+ [ -e /sys/class/leds/${sysfs}/multi_intensity ] && {
+ printf " %s" \
+ "$(sed 's/\ /:/g' /sys/class/leds/${sysfs}/multi_intensity)" \
+ >> /var/run/led.state
+ }
+ printf "\n" >> /var/run/led.state
[ "$default" = 0 ] &&
echo 0 >/sys/class/leds/${sysfs}/brightness
- echo $trigger > /sys/class/leds/${sysfs}/trigger 2> /dev/null
- ret="$?"
-
[ $default = 1 ] &&
cat /sys/class/leds/${sysfs}/max_brightness > /sys/class/leds/${sysfs}/brightness
+ led_color_set "$1" "$sysfs"
+
+ echo $trigger > /sys/class/leds/${sysfs}/trigger 2> /dev/null
+ ret="$?"
[ $ret = 0 ] || {
echo >&2 "Skipping trigger '$trigger' for led '$name' due to missing kernel module"
return 1
}
case "$trigger" in
+ "heartbeat")
+ echo "${inverted}" > "/sys/class/leds/${sysfs}/invert"
+ ;;
+
"netdev")
[ -n "$dev" ] && {
echo $dev > /sys/class/leds/${sysfs}/device_name
@@ -124,13 +169,17 @@ load_led() {
start() {
[ -e /sys/class/leds/ ] && {
[ -s /var/run/led.state ] && {
- local led trigger brightness
- while read led trigger brightness; do
+ local led trigger brightness color
+ while read led trigger brightness color; do
[ -e "/sys/class/leds/$led/trigger" ] && \
echo "$trigger" > "/sys/class/leds/$led/trigger"
[ -e "/sys/class/leds/$led/brightness" ] && \
echo "$brightness" > "/sys/class/leds/$led/brightness"
+
+ [ -e "/sys/class/leds/$led/multi_intensity" ] && \
+ echo "$color" | sed 's/:/\ /g' > \
+ "/sys/class/leds/$led/multi_intensity"
done < /var/run/led.state
rm /var/run/led.state
}
diff --git a/package/base-files/files/etc/init.d/sysfixtime b/package/base-files/files/etc/init.d/sysfixtime
index aab5b153d07..93f792266aa 100755
--- a/package/base-files/files/etc/init.d/sysfixtime
+++ b/package/base-files/files/etc/init.d/sysfixtime
@@ -8,23 +8,33 @@ RTC_DEV=/dev/rtc0
HWCLOCK=/sbin/hwclock
boot() {
- start && exit 0
-
- local maxtime="$(maxtime)"
+ hwclock_load
+ local maxtime="$(find_max_time)"
local curtime="$(date +%s)"
- [ $curtime -lt $maxtime ] && date -s @$maxtime
+ if [ $curtime -lt $maxtime ]; then
+ date -s @$maxtime
+ hwclock_save
+ fi
}
start() {
- [ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -u -f $RTC_DEV
+ hwclock_load
}
stop() {
+ hwclock_save
+}
+
+hwclock_load() {
+ [ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -u -f $RTC_DEV
+}
+
+hwclock_save(){
[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -w -u -f $RTC_DEV && \
logger -t sysfixtime "saved '$(date)' to $RTC_DEV"
}
-maxtime() {
+find_max_time() {
local file newest
for file in $( find /etc -type f ) ; do
diff --git a/package/base-files/files/etc/profile b/package/base-files/files/etc/profile
index 0beff1608f6..76b149b9fae 100644
--- a/package/base-files/files/etc/profile
+++ b/package/base-files/files/etc/profile
@@ -3,7 +3,7 @@
[ -f /etc/banner ] && cat /etc/banner
[ -n "$FAILSAFE" ] && cat /etc/banner.failsafe
-fgrep -sq '/ overlay ro,' /proc/mounts && {
+grep -Fsq '/ overlay ro,' /proc/mounts && {
echo 'Your JFFS2-partition seems full and overlayfs is mounted read-only.'
echo 'Please try to remove files from /overlay/upper/... and reboot!'
}
diff --git a/package/base-files/files/etc/rc.common b/package/base-files/files/etc/rc.common
index 5dcbf5138d5..d7473038444 100755
--- a/package/base-files/files/etc/rc.common
+++ b/package/base-files/files/etc/rc.common
@@ -105,9 +105,9 @@ service_data() {
}
service_running() {
- local service="${1:-$(basename $initscript)}"
- local instance="${2:-*}"
- procd_running "$service" "$instance" "$@"
+ local instance="${1:-*}"
+
+ procd_running "$(basename $initscript)" "$instance"
}
${INIT_TRACE:+set -x}
@@ -126,6 +126,7 @@ extra_command "enabled" "Check if service is started on boot"
extra_command "running" "Check if service is running"
extra_command "status" "Service status"
extra_command "trace" "Start with syscall trace"
+ extra_command "info" "Dump procd service info"
. $IPKG_INSTROOT/lib/functions/procd.sh
basescript=$(readlink "$initscript")
@@ -149,6 +150,13 @@ extra_command "enabled" "Check if service is started on boot"
start "$@"
}
+ info() {
+ json_init
+ json_add_string name "$(basename ${basescript:-$initscript})"
+ json_add_boolean verbose "1"
+ _procd_ubus_call list
+ }
+
stop() {
procd_lock
stop_service "$@"
diff --git a/package/base-files/files/etc/shadow b/package/base-files/files/etc/shadow
index 4b4154f21f4..39bdb9c90a3 100644
--- a/package/base-files/files/etc/shadow
+++ b/package/base-files/files/etc/shadow
@@ -1,4 +1,4 @@
-root::0:0:99999:7:::
+root:::0:99999:7:::
daemon:*:0:0:99999:7:::
ftp:*:0:0:99999:7:::
network:*:0:0:99999:7:::
diff --git a/package/base-files/files/etc/shinit b/package/base-files/files/etc/shinit
index 6b682d8769d..8df9771e656 100644
--- a/package/base-files/files/etc/shinit
+++ b/package/base-files/files/etc/shinit
@@ -8,26 +8,5 @@ alias ll='ls -alF --color=auto'
[ -x /usr/bin/arp -o -x /sbin/arp ] || arp() { cat /proc/net/arp; }
[ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; }
-service() {
- if [ -f "/etc/init.d/$1" ]; then
- /etc/init.d/$@
- else
- echo "Usage: service <service> [command]"
- if [ -n "$1" ]; then
- echo "Service "'"'"$1"'"'" not found, the following services are available:"
- else
- echo "The following services are available:"
- fi
- for F in /etc/init.d/* ; do
- printf "%-30s\t%10s\t%10s\n" "$F" \
- $( $($F enabled) && echo "enabled" || echo "disabled" ) \
- $( [ "$(ubus call service list "{ 'verbose': true, 'name': '$(basename $F)' }" \
- | jsonfilter -q -e "@['$(basename $F)'].instances[*].running" | uniq)" = "true" ] \
- && echo "running" || echo "stopped" )
- done;
- return 1
- fi
-}
-
[ -n "$KSH_VERSION" -o \! -s "$HOME/.shinit" ] || . "$HOME/.shinit"
[ -z "$KSH_VERSION" -o \! -s "$HOME/.mkshrc" ] || . "$HOME/.mkshrc"
diff --git a/package/base-files/files/etc/sysctl.d/10-default.conf b/package/base-files/files/etc/sysctl.d/10-default.conf
index bc8c5796951..ee7df2bfa61 100644
--- a/package/base-files/files/etc/sysctl.d/10-default.conf
+++ b/package/base-files/files/etc/sysctl.d/10-default.conf
@@ -9,6 +9,7 @@ fs.protected_hardlinks=1
fs.protected_symlinks=1
net.core.bpf_jit_enable=1
+net.core.bpf_jit_kallsyms=1
net.ipv4.conf.default.arp_ignore=1
net.ipv4.conf.all.arp_ignore=1
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--
diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
index 7e0a00e13b8..4bac1041d96 100755
--- a/package/base-files/files/sbin/sysupgrade
+++ b/package/base-files/files/sbin/sysupgrade
@@ -19,11 +19,11 @@ export CONF_IMAGE=
export CONF_BACKUP_LIST=0
export CONF_BACKUP=
export CONF_RESTORE=
+export IGNORE_MINOR_COMPAT=0
export NEED_IMAGE=
export HELP=0
export FORCE=0
export TEST=0
-export UMOUNT_ETCBACKUP_DIR=0
# parse options
while [ -n "$1" ]; do
@@ -44,6 +44,7 @@ while [ -n "$1" ]; do
-F|--force) export FORCE=1;;
-T|--test) export TEST=1;;
-h|--help) export HELP=1; break;;
+ --ignore-minor-compat-version) export IGNORE_MINOR_COMPAT=1;;
-*)
echo "Invalid option: $1" >&2
exit 1
@@ -80,6 +81,8 @@ upgrade-option:
Verify image and config .tar.gz but do not actually flash.
-F | --force
Flash image even if image checks fail, this is dangerous!
+ --ignore-minor-compat-version
+ Flash image even if the minor compat version is incompatible.
-q less verbose
-v more verbose
-h | --help display this help
@@ -220,6 +223,8 @@ include /lib/upgrade
do_save_conffiles() {
local conf_tar="$1"
+ local tmp
+ local dir
[ "$(rootfs_type)" = "tmpfs" ] && {
echo "Cannot save config while running from ramdisk." >&2
@@ -230,17 +235,21 @@ do_save_conffiles() {
run_hooks "$CONFFILES" $sysupgrade_init_conffiles
ask_bool 0 "Edit config file list" && vi "$CONFFILES"
+ # Mount root directory with temporary overlay on top of it.
+ # This allows including extra (temporary) files in backup archive
+ # without messing actual rootfs.
+ tmp="$(mktemp -d -t overlay.XXXXXX)"
+ mkdir -p "$tmp/upper" "$tmp/work" "$tmp/backup"
+ dir="$tmp/backup"
+ if ! mount -t overlay overlay -o lowerdir=/,upperdir="$tmp/upper",workdir="$tmp/work" "$dir"; then
+ echo "Cannot mount backup overlay to $dir." >&2
+ ask_bool 0 "Abort" && exit
+ dir=""
+ fi
+
if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
- mkdir -p "$ETCBACKUP_DIR"
- # Avoid touching filesystem on each backup
- RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)"
- mkdir -p "$RAMFS/upper" "$RAMFS/work"
- mount -t overlay overlay -o lowerdir=$ETCBACKUP_DIR,upperdir=$RAMFS/upper,workdir=$RAMFS/work $ETCBACKUP_DIR &&
- UMOUNT_ETCBACKUP_DIR=1 || {
- echo "Cannot mount '$ETCBACKUP_DIR' as tmpfs to avoid touching disk while saving the list of installed packages." >&2
- ask_bool 0 "Abort" && exit
- }
+ mkdir -p "$dir/$ETCBACKUP_DIR"
# Format: pkg-name<TAB>{rom,overlay,unkown}
# rom is used for pkgs in /rom, even if updated later
@@ -248,23 +257,35 @@ do_save_conffiles() {
\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
\( -exec echo {} unknown \; \) \
- \) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
+ \) | sed -e 's,.*/,,;s/\.control /\t/' > "$dir/${INSTALLED_PACKAGES}"
fi
+ mkdir -p $dir/etc/uci-defaults/
+ touch $dir/etc/uci-defaults/10_disable_services
+ for service in /etc/init.d/*; do
+ if ! $service enabled; then
+ echo "$service disable" >> $dir/etc/uci-defaults/10_disable_services
+ fi
+ done
+ echo "exit 0" >> $dir/etc/uci-defaults/10_disable_services
+ echo "/etc/uci-defaults/10_disable_services" >> "$CONFFILES"
+
v "Saving config files..."
[ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V=""
- tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES" 2>/dev/null
- if [ "$?" -ne 0 ]; then
+ sed -i -e 's,^/,,' "$CONFFILES"
+ tar c${TAR_V}zf "$conf_tar" -C "${dir:-/}" -T "$CONFFILES"
+ local err=$?
+ if [ "$err" -ne 0 ]; then
echo "Failed to create the configuration backup."
rm -f "$conf_tar"
- exit 1
fi
- [ "$UMOUNT_ETCBACKUP_DIR" -eq 1 ] && {
- umount "$ETCBACKUP_DIR"
- rm -rf "$RAMFS"
- }
+ umount "$dir"
+ rm -rf "$tmp"
+
rm -f "$CONFFILES"
+
+ return "$err"
}
if [ $CONF_BACKUP_LIST -eq 1 ]; then
@@ -277,7 +298,7 @@ fi
if [ -n "$CONF_BACKUP" ]; then
do_save_conffiles "$CONF_BACKUP"
- exit $?
+ exit
fi
if [ -n "$CONF_RESTORE" ]; then
@@ -346,7 +367,7 @@ if [ -n "$CONF_IMAGE" ]; then
get_image "$CONF_IMAGE" "cat" > "$CONF_TAR"
export SAVE_CONFIG=1
elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then
- [ $TEST -eq 1 ] || do_save_conffiles "$CONF_TAR"
+ [ $TEST -eq 1 ] || do_save_conffiles "$CONF_TAR" || exit
export SAVE_CONFIG=1
else
[ $TEST -eq 1 ] || rm -f "$CONF_TAR"
diff --git a/package/base-files/files/sbin/wifi b/package/base-files/files/sbin/wifi
deleted file mode 100755
index 6b9662fe930..00000000000
--- a/package/base-files/files/sbin/wifi
+++ /dev/null
@@ -1,254 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2006 OpenWrt.org
-
-. /lib/functions.sh
-. /usr/share/libubox/jshn.sh
-
-usage() {
- cat <<EOF
-Usage: $0 [config|up|down|reconf|reload|status]
-enables (default), disables or configures devices not yet configured.
-EOF
- exit 1
-}
-
-ubus_wifi_cmd() {
- local cmd="$1"
- local dev="$2"
-
- json_init
- [ -n "$2" ] && json_add_string device "$2"
- ubus call network.wireless "$1" "$(json_dump)"
-}
-
-find_net_config() {(
- local vif="$1"
- local cfg
- local ifname
-
- config_get cfg "$vif" network
-
- [ -z "$cfg" ] && {
- include /lib/network
- scan_interfaces
-
- config_get ifname "$vif" ifname
-
- cfg="$(find_config "$ifname")"
- }
- [ -z "$cfg" ] && return 0
- echo "$cfg"
-)}
-
-
-bridge_interface() {(
- local cfg="$1"
- [ -z "$cfg" ] && return 0
-
- include /lib/network
- scan_interfaces
-
- for cfg in $cfg; do
- config_get iftype "$cfg" type
- [ "$iftype" = bridge ] && config_get "$cfg" ifname
- prepare_interface_bridge "$cfg"
- return $?
- done
-)}
-
-prepare_key_wep() {
- local key="$1"
- local hex=1
-
- echo -n "$key" | grep -qE "[^a-fA-F0-9]" && hex=0
- [ "${#key}" -eq 10 -a $hex -eq 1 ] || \
- [ "${#key}" -eq 26 -a $hex -eq 1 ] || {
- [ "${key:0:2}" = "s:" ] && key="${key#s:}"
- key="$(echo -n "$key" | hexdump -ve '1/1 "%02x" ""')"
- }
- echo "$key"
-}
-
-wifi_fixup_hwmode() {
- local device="$1"
- local default="$2"
- local hwmode hwmode_11n
-
- config_get channel "$device" channel
- config_get hwmode "$device" hwmode
- case "$hwmode" in
- 11bg) hwmode=bg;;
- 11a) hwmode=a;;
- 11ad) hwmode=ad;;
- 11b) hwmode=b;;
- 11g) hwmode=g;;
- 11n*)
- hwmode_11n="${hwmode##11n}"
- case "$hwmode_11n" in
- a|g) ;;
- default) hwmode_11n="$default"
- esac
- config_set "$device" hwmode_11n "$hwmode_11n"
- ;;
- *)
- hwmode=
- if [ "${channel:-0}" -gt 0 ]; then
- if [ "${channel:-0}" -gt 14 ]; then
- hwmode=a
- else
- hwmode=g
- fi
- else
- hwmode="$default"
- fi
- ;;
- esac
- config_set "$device" hwmode "$hwmode"
-}
-
-_wifi_updown() {
- for device in ${2:-$DEVICES}; do (
- config_get disabled "$device" disabled
- [ "$disabled" = "1" ] && {
- echo "'$device' is disabled"
- set disable
- }
- config_get iftype "$device" type
- if eval "type ${1}_$iftype" 2>/dev/null >/dev/null; then
- eval "scan_$iftype '$device'"
- eval "${1}_$iftype '$device'" || echo "$device($iftype): ${1} failed"
- elif [ ! -f /lib/netifd/wireless/$iftype.sh ]; then
- echo "$device($iftype): Interface type not supported"
- fi
- ); done
-}
-
-wifi_updown() {
- cmd=down
- [ enable = "$1" ] && {
- _wifi_updown disable "$2"
- ubus_wifi_cmd "$cmd" "$2"
- scan_wifi
- cmd=up
- ubus call network reload
- }
- [ reconf = "$1" ] && {
- scan_wifi
- cmd=reconf
- ubus call network reload
- }
- ubus_wifi_cmd "$cmd" "$2"
- _wifi_updown "$@"
-}
-
-wifi_reload_legacy() {
- _wifi_updown "disable" "$1"
- scan_wifi
- _wifi_updown "enable" "$1"
-}
-
-wifi_reload() {
- ubus call network reload
- wifi_reload_legacy
-}
-
-wifi_detect_notice() {
- >&2 echo "WARNING: Wifi detect is deprecated. Use wifi config instead"
- >&2 echo "For more information, see commit 5f8f8a366136a07df661e31decce2458357c167a"
- exit 1
-}
-
-wifi_config() {
- [ ! -f /etc/config/wireless ] && touch /etc/config/wireless
-
- for driver in $DRIVERS; do (
- if eval "type detect_$driver" 2>/dev/null >/dev/null; then
- eval "detect_$driver" || echo "$driver: Detect failed" >&2
- else
- echo "$driver: Hardware detection not supported" >&2
- fi
- ); done
-}
-
-start_net() {(
- local iface="$1"
- local config="$2"
- local vifmac="$3"
-
- [ -f "/var/run/$iface.pid" ] && kill "$(cat /var/run/${iface}.pid)" 2>/dev/null
- [ -z "$config" ] || {
- include /lib/network
- scan_interfaces
- for config in $config; do
- setup_interface "$iface" "$config" "" "$vifmac"
- done
- }
-)}
-
-set_wifi_up() {
- local cfg="$1"
- local ifname="$2"
- uci_set_state wireless "$cfg" up 1
- uci_set_state wireless "$cfg" ifname "$ifname"
-}
-
-set_wifi_down() {
- local cfg="$1"
- local vifs vif vifstr
-
- [ -f "/var/run/wifi-${cfg}.pid" ] &&
- kill "$(cat "/var/run/wifi-${cfg}.pid")" 2>/dev/null
- uci_revert_state wireless "$cfg"
- config_get vifs "$cfg" vifs
- for vif in $vifs; do
- uci_revert_state wireless "$vif"
- done
-}
-
-scan_wifi() {
- local cfgfile="$1"
- DEVICES=
- config_cb() {
- local type="$1"
- local section="$2"
-
- # section start
- case "$type" in
- wifi-device)
- append DEVICES "$section"
- config_set "$section" vifs ""
- config_set "$section" ht_capab ""
- ;;
- esac
-
- # section end
- config_get TYPE "$CONFIG_SECTION" TYPE
- case "$TYPE" in
- wifi-iface)
- config_get device "$CONFIG_SECTION" device
- config_get vifs "$device" vifs
- append vifs "$CONFIG_SECTION"
- config_set "$device" vifs "$vifs"
- ;;
- esac
- }
- config_load "${cfgfile:-wireless}"
-}
-
-DEVICES=
-DRIVERS=
-include /lib/wifi
-scan_wifi
-
-case "$1" in
- down) wifi_updown "disable" "$2";;
- detect) wifi_detect_notice ;;
- config) wifi_config ;;
- status) ubus_wifi_cmd "status" "$2";;
- reload) wifi_reload "$2";;
- reload_legacy) wifi_reload_legacy "$2";;
- --help|help) usage;;
- reconf) wifi_updown "reconf" "$2";;
- ''|up) wifi_updown "enable" "$2";;
- *) usage; exit 1;;
-esac
diff --git a/package/base-files/image-config.in b/package/base-files/image-config.in
index ac406bc456b..2de2130b849 100644
--- a/package/base-files/image-config.in
+++ b/package/base-files/image-config.in
@@ -5,6 +5,13 @@
# See /LICENSE for more information.
#
+config TARGET_DEFAULT_LAN_IP_FROM_PREINIT
+ bool "Use preinit IP configuration as default LAN IP" if IMAGEOPT
+ default n
+ help
+ Enabling this will set the default LAN IP address and netmask
+ to the preinit values set in the image config.
+
menuconfig PREINITOPT
bool "Preinit configuration options" if IMAGEOPT
default n