Backport staged sysupgrade patches

The staged sysupgrade allows to properly unmount the rootfs before writing
the new partitions. This will fix upgrades losing configuration when
parition sizes change on x86 and similar image types.
This commit is contained in:
Matthias Schiffer 2017-06-02 01:56:39 +02:00
parent 97f44c208b
commit d4a69c0004
No known key found for this signature in database
GPG Key ID: 16EF3F64CB201D9C
13 changed files with 3185 additions and 0 deletions

View File

@ -0,0 +1,28 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 3 May 2017 08:27:40 +0200
Subject: procd: clean up trailing whitespace in nand.sh
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
index 0ed1b632d5a3ecc0299d3f8da853191c453d3bb4..e0d3f2dfdb1e04e17ccf6fea60b0f2af617206f3 100644
--- a/package/system/procd/files/nand.sh
+++ b/package/system/procd/files/nand.sh
@@ -194,7 +194,7 @@ nand_upgrade_prepare_ubi() {
nand_do_upgrade_success() {
local conf_tar="/tmp/sysupgrade.tgz"
-
+
sync
[ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
echo "sysupgrade successful"
@@ -229,7 +229,7 @@ nand_upgrade_ubifs() {
local rootfs_length=`(cat $1 | wc -c) 2> /dev/null`
nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0"
-
+
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
local root_ubivol="$(nand_find_volume $ubidev rootfs)"
ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1

View File

@ -0,0 +1,32 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 3 May 2017 08:28:05 +0200
Subject: procd: prepare NAND sysupgrade for making upgraded dynamically linked
Use install_bin to copy upgraded with all dependencies. The old name
/tmp/upgraded is temporarily retained as a symlink to avoid breaking
things.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
index e0d3f2dfdb1e04e17ccf6fea60b0f2af617206f3..ec2a014a00461ca897d521e2d065f5399f1f8c48 100644
--- a/package/system/procd/files/nand.sh
+++ b/package/system/procd/files/nand.sh
@@ -318,7 +318,7 @@ nand_upgrade_stage1() {
[ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] &&
rm $CONF_TAR
- ubus call system nandupgrade "{\"path\": \"$path\" }"
+ ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }"
exit 0
}
}
@@ -359,6 +359,7 @@ nand_do_platform_check() {
# $(1): file to be used for upgrade
nand_do_upgrade() {
echo -n $1 > /tmp/sysupgrade-nand-path
- cp /sbin/upgraded /tmp/
+ install_bin /sbin/upgraded
+ ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded
nand_upgrade_stage1
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,897 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Fri, 21 Apr 2017 20:37:58 +0200
Subject: procd: remove procd-nand package
We always want to support staged upgrades now, so it's better to include
upgraded into the main package. /lib/upgrade/nand.sh is moved to
base-files.
The procd-nand-firstboot package is removed for now, it may return later
as a separate package.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/Makefile b/package/base-files/Makefile
index 9f6810f4d8bad89eb11db1023693ad59f7369d57..3e27e43c92af01b6cac212e77cde3d1db916ba6f 100644
--- a/package/base-files/Makefile
+++ b/package/base-files/Makefile
@@ -31,7 +31,7 @@ endif
define Package/base-files
SECTION:=base
CATEGORY:=Base system
- DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign
+ DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign +NAND_SUPPORT:ubi-utils
TITLE:=Base filesystem for OpenWrt
URL:=http://openwrt.org/
VERSION:=$(PKG_RELEASE)-$(REVISION)
@@ -103,9 +103,16 @@ ifdef CONFIG_SIGNED_PACKAGES
endef
endif
+ifeq ($(CONFIG_NAND_SUPPORT),)
+ define Package/base-files/nand-support
+ rm -f $(1)/lib/upgrade/nand.sh
+ endef
+endif
+
define Package/base-files/install
$(CP) ./files/* $(1)/
$(Package/base-files/install-key)
+ $(Package/base-files/nand-support)
if [ -d $(GENERIC_PLATFORM_DIR)/base-files/. ]; then \
$(CP) $(GENERIC_PLATFORM_DIR)/base-files/* $(1)/; \
fi
diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ec2a014a00461ca897d521e2d065f5399f1f8c48
--- /dev/null
+++ b/package/base-files/files/lib/upgrade/nand.sh
@@ -0,0 +1,365 @@
+#!/bin/sh
+# Copyright (C) 2014 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+# 'kernel' partition on NAND contains the kernel
+CI_KERNPART="kernel"
+
+# 'ubi' partition on NAND contains UBI
+CI_UBIPART="ubi"
+
+ubi_mknod() {
+ local dir="$1"
+ local dev="/dev/$(basename $dir)"
+
+ [ -e "$dev" ] && return 0
+
+ local devid="$(cat $dir/dev)"
+ local major="${devid%%:*}"
+ local minor="${devid##*:}"
+ mknod "$dev" c $major $minor
+}
+
+nand_find_volume() {
+ local ubidevdir ubivoldir
+ ubidevdir="/sys/devices/virtual/ubi/$1"
+ [ ! -d "$ubidevdir" ] && return 1
+ for ubivoldir in $ubidevdir/${1}_*; do
+ [ ! -d "$ubivoldir" ] && continue
+ if [ "$( cat $ubivoldir/name )" = "$2" ]; then
+ basename $ubivoldir
+ ubi_mknod "$ubivoldir"
+ return 0
+ fi
+ done
+}
+
+nand_find_ubi() {
+ local ubidevdir ubidev mtdnum
+ mtdnum="$( find_mtd_index $1 )"
+ [ ! "$mtdnum" ] && return 1
+ for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
+ [ ! -d "$ubidevdir" ] && continue
+ cmtdnum="$( cat $ubidevdir/mtd_num )"
+ [ ! "$mtdnum" ] && continue
+ if [ "$mtdnum" = "$cmtdnum" ]; then
+ ubidev=$( basename $ubidevdir )
+ ubi_mknod "$ubidevdir"
+ echo $ubidev
+ return 0
+ fi
+ done
+}
+
+nand_get_magic_long() {
+ dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
+}
+
+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
+}
+
+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_tar() {
+ identify_magic $(get_magic_long_tar "$1" "$2")
+}
+
+nand_restore_config() {
+ sync
+ local ubidev=$( nand_find_ubi $CI_UBIPART )
+ local ubivol="$( nand_find_volume $ubidev rootfs_data )"
+ [ ! "$ubivol" ] &&
+ ubivol="$( nand_find_volume $ubidev rootfs )"
+ mkdir /tmp/new_root
+ if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
+ echo "mounting ubifs $ubivol failed"
+ rmdir /tmp/new_root
+ return 1
+ fi
+ mv "$1" "/tmp/new_root/sysupgrade.tgz"
+ umount /tmp/new_root
+ sync
+ rmdir /tmp/new_root
+}
+
+nand_upgrade_prepare_ubi() {
+ local rootfs_length="$1"
+ local rootfs_type="$2"
+ local has_kernel="${3:-0}"
+ local has_env="${4:-0}"
+
+ local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
+ if [ ! "$mtdnum" ]; then
+ echo "cannot find ubi mtd partition $CI_UBIPART"
+ return 1
+ fi
+
+ local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+ if [ ! "$ubidev" ]; then
+ ubiattach -m "$mtdnum"
+ sync
+ ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+ 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
+
+ local kern_ubivol="$( nand_find_volume $ubidev kernel )"
+ local root_ubivol="$( nand_find_volume $ubidev rootfs )"
+ local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
+
+ # remove ubiblock device of rootfs
+ local root_ubiblk="ubiblock${root_ubivol:3}"
+ if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then
+ echo "removing $root_ubiblk"
+ if ! ubiblock -r /dev/$root_ubivol; then
+ echo "cannot remove $root_ubiblk"
+ return 1;
+ fi
+ fi
+
+ # kill volumes
+ [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N kernel || true
+ [ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs || true
+ [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
+
+ # update kernel
+ if [ "$has_kernel" = "1" ]; then
+ if ! ubimkvol /dev/$ubidev -N kernel -s $kernel_length; then
+ echo "cannot create kernel volume"
+ return 1;
+ fi
+ fi
+
+ # update rootfs
+ local root_size_param
+ if [ "$rootfs_type" = "ubifs" ]; then
+ root_size_param="-m"
+ else
+ root_size_param="-s $rootfs_length"
+ fi
+ if ! ubimkvol /dev/$ubidev -N rootfs $root_size_param; then
+ echo "cannot create rootfs volume"
+ return 1;
+ fi
+
+ # create rootfs_data for non-ubifs rootfs
+ if [ "$rootfs_type" != "ubifs" ]; then
+ if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then
+ echo "cannot initialize rootfs_data volume"
+ return 1
+ 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"
+ reboot -f
+}
+
+# Flash the UBI image to MTD partition
+nand_upgrade_ubinized() {
+ local ubi_file="$1"
+ local mtdnum="$(find_mtd_index "$CI_UBIPART")"
+
+ [ ! "$mtdnum" ] && {
+ CI_UBIPART="rootfs"
+ mtdnum="$(find_mtd_index "$CI_UBIPART")"
+ }
+
+ if [ ! "$mtdnum" ]; then
+ echo "cannot find mtd device $CI_UBIPART"
+ reboot -f
+ fi
+
+ local mtddev="/dev/mtd${mtdnum}"
+ ubidetach -p "${mtddev}" || true
+ sync
+ ubiformat "${mtddev}" -y -f "${ubi_file}"
+ ubiattach -p "${mtddev}"
+ nand_do_upgrade_success
+}
+
+# Write the UBIFS image to UBI volume
+nand_upgrade_ubifs() {
+ local rootfs_length=`(cat $1 | wc -c) 2> /dev/null`
+
+ nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0"
+
+ local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+ local root_ubivol="$(nand_find_volume $ubidev rootfs)"
+ ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
+
+ nand_do_upgrade_success
+}
+
+nand_upgrade_tar() {
+ local tar_file="$1"
+ local board_name="$(cat /tmp/sysinfo/board_name)"
+ local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
+
+ local kernel_length=`(tar xf $tar_file sysupgrade-$board_name/kernel -O | wc -c) 2> /dev/null`
+ local rootfs_length=`(tar xf $tar_file sysupgrade-$board_name/root -O | wc -c) 2> /dev/null`
+
+ local rootfs_type="$(identify_tar "$tar_file" sysupgrade-$board_name/root)"
+
+ local has_kernel=1
+ local has_env=0
+
+ [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
+ tar xf $tar_file sysupgrade-$board_name/kernel -O | mtd write - $CI_KERNPART
+ }
+ [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0
+
+ nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env"
+
+ local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+ [ "$has_kernel" = "1" ] && {
+ local kern_ubivol="$(nand_find_volume $ubidev kernel)"
+ tar xf $tar_file sysupgrade-$board_name/kernel -O | \
+ ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
+ }
+
+ local root_ubivol="$(nand_find_volume $ubidev rootfs)"
+ tar xf $tar_file sysupgrade-$board_name/root -O | \
+ ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
+
+ nand_do_upgrade_success
+}
+
+# Recognize type of passed file and start the upgrade process
+nand_do_upgrade_stage2() {
+ local file_type=$(identify $1)
+
+ [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
+
+ case "$file_type" in
+ "ubi") nand_upgrade_ubinized $1;;
+ "ubifs") nand_upgrade_ubifs $1;;
+ *) nand_upgrade_tar $1;;
+ esac
+}
+
+nand_upgrade_stage2() {
+ [ $1 = "nand" ] && {
+ [ -f "$2" ] && {
+ touch /tmp/sysupgrade
+
+ killall -9 telnetd
+ killall -9 dropbear
+ killall -9 ash
+
+ kill_remaining TERM
+ sleep 3
+ kill_remaining KILL
+
+ sleep 1
+
+ if [ -n "$(rootfs_type)" ]; then
+ v "Switching to ramdisk..."
+ run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2"
+ else
+ nand_do_upgrade_stage2 $2
+ fi
+ return 0
+ }
+ echo "Nand upgrade failed"
+ exit 1
+ }
+}
+
+nand_upgrade_stage1() {
+ [ -f /tmp/sysupgrade-nand-path ] && {
+ path="$(cat /tmp/sysupgrade-nand-path)"
+ [ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] &&
+ rm $CONF_TAR
+
+ ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }"
+ exit 0
+ }
+}
+append sysupgrade_pre_upgrade nand_upgrade_stage1
+
+# 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)
+#
+# You usually want to call this function in platform_check_image.
+#
+# $(1): board name, used in case of passing TAR file
+# $(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)"
+
+ [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && {
+ echo "Invalid sysupgrade file."
+ return 1
+ }
+
+ echo -n $2 > /tmp/sysupgrade-nand-path
+ cp /sbin/upgraded /tmp/
+
+ return 0
+}
+
+# Start NAND upgrade process
+#
+# $(1): file to be used for upgrade
+nand_do_upgrade() {
+ echo -n $1 > /tmp/sysupgrade-nand-path
+ install_bin /sbin/upgraded
+ ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded
+ nand_upgrade_stage1
+}
diff --git a/package/system/procd/Makefile b/package/system/procd/Makefile
index d343f7481f3bb627b3e7ad79f45864de82a42371..b95ef64b727f6f07c8f92c9caf027c21dbb30863 100644
--- a/package/system/procd/Makefile
+++ b/package/system/procd/Makefile
@@ -24,7 +24,7 @@ PKG_LICENSE_FILES:=
PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
-PKG_CONFIG_DEPENDS:= CONFIG_KERNEL_SECCOMP CONFIG_NAND_SUPPORT CONFIG_PROCD_SHOW_BOOT CONFIG_PROCD_ZRAM_TMPFS \
+PKG_CONFIG_DEPENDS:= CONFIG_KERNEL_SECCOMP CONFIG_PROCD_SHOW_BOOT CONFIG_PROCD_ZRAM_TMPFS \
CONFIG_KERNEL_NAMESPACES CONFIG_PACKAGE_procd-ujail CONFIG_PACKAGE_procd-seccomp
include $(INCLUDE_DIR)/package.mk
@@ -35,7 +35,7 @@ TARGET_LDFLAGS += $(if $(CONFIG_USE_GLIBC),-lrt)
define Package/procd
SECTION:=base
CATEGORY:=Base system
- DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus +NAND_SUPPORT:procd-nand
+ DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus
TITLE:=OpenWrt system process manager
endef
@@ -53,20 +53,6 @@ define Package/procd-seccomp
TITLE:=OpenWrt process seccomp helper + utrace
endef
-define Package/procd-nand
- SECTION:=utils
- CATEGORY:=Utilities
- DEPENDS:=@NAND_SUPPORT +ubi-utils
- TITLE:=OpenWrt sysupgrade nand helper
-endef
-
-define Package/procd-nand-firstboot
- SECTION:=utils
- CATEGORY:=Utilities
- DEPENDS:=procd-nand
- TITLE:=OpenWrt firstboot nand helper
-endef
-
define Package/procd/config
menu "Configuration"
depends on PACKAGE_procd
@@ -84,10 +70,6 @@ endmenu
endef
-ifeq ($(CONFIG_NAND_SUPPORT),y)
- CMAKE_OPTIONS += -DBUILD_UPGRADED=1
-endif
-
ifeq ($(CONFIG_PROCD_SHOW_BOOT),y)
CMAKE_OPTIONS += -DSHOW_BOOT_ON_CONSOLE=1
endif
@@ -107,7 +89,7 @@ endif
define Package/procd/install
$(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{init,procd,askfirst,udevtrigger} $(1)/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{init,procd,askfirst,udevtrigger,upgraded} $(1)/sbin/
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libsetlbf.so $(1)/lib
$(INSTALL_BIN) ./files/reload_config $(1)/sbin/
$(INSTALL_DATA) ./files/hotplug*.json $(1)/etc/
@@ -126,21 +108,6 @@ define Package/procd-seccomp/install
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libpreload-trace.so $(1)/lib
endef
-define Package/procd-nand/install
- $(INSTALL_DIR) $(1)/sbin $(1)/lib/upgrade
-
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/upgraded $(1)/sbin/
- $(INSTALL_DATA) ./files/nand.sh $(1)/lib/upgrade/
-endef
-
-define Package/procd-nand-firstboot/install
- $(INSTALL_DIR) $(1)/lib/preinit
-
- $(INSTALL_DATA) ./files/nand-preinit.sh $(1)/lib/preinit/60-nand-firstboot.sh
-endef
-
$(eval $(call BuildPackage,procd))
$(eval $(call BuildPackage,procd-ujail))
$(eval $(call BuildPackage,procd-seccomp))
-$(eval $(call BuildPackage,procd-nand))
-$(eval $(call BuildPackage,procd-nand-firstboot))
diff --git a/package/system/procd/files/nand-preinit.sh b/package/system/procd/files/nand-preinit.sh
deleted file mode 100644
index cf596246d1f2891cbeb7b5c7cac4bb6e002b13fb..0000000000000000000000000000000000000000
--- a/package/system/procd/files/nand-preinit.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2014 OpenWrt.org
-
-nand_takeover() {
- . /lib/upgrade/nand.sh
- mtd=$(find_mtd_index "$CI_UBIPART")
- esize=$(cat /proc/mtd | grep mtd$mtd |cut -d" " -f 3)
- [ -z "$esize" ] && return 1
- esize=$(printf "%d" 0x$esize)
- for a in `seq 0 64`; do
- mtd -o $((a * esize)) -l 400 dump /dev/mtd$mtd > /tmp/takeover.hdr
- MAGIC=$(dd if=/tmp/takeover.hdr bs=1 skip=261 count=5 2> /dev/null)
- SIZE=$(printf "%d" 0x$(dd if=/tmp/takeover.hdr bs=4 count=1 2> /dev/null | hexdump -v -n 4 -e '1/1 "%02x"'))
- [ "$MAGIC" = "ustar" ] && {
- mtd -o $((a * esize)) -l $((SIZE + 4)) dump /dev/mtd$mtd | dd bs=1 skip=4 of=/tmp/sysupgrade.tar
- nand_do_upgrade_stage2 /tmp/sysupgrade.tar
- }
- done
-}
-
-boot_hook_add initramfs nand_takeover
diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
deleted file mode 100644
index ec2a014a00461ca897d521e2d065f5399f1f8c48..0000000000000000000000000000000000000000
--- a/package/system/procd/files/nand.sh
+++ /dev/null
@@ -1,365 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2014 OpenWrt.org
-#
-
-. /lib/functions.sh
-
-# 'kernel' partition on NAND contains the kernel
-CI_KERNPART="kernel"
-
-# 'ubi' partition on NAND contains UBI
-CI_UBIPART="ubi"
-
-ubi_mknod() {
- local dir="$1"
- local dev="/dev/$(basename $dir)"
-
- [ -e "$dev" ] && return 0
-
- local devid="$(cat $dir/dev)"
- local major="${devid%%:*}"
- local minor="${devid##*:}"
- mknod "$dev" c $major $minor
-}
-
-nand_find_volume() {
- local ubidevdir ubivoldir
- ubidevdir="/sys/devices/virtual/ubi/$1"
- [ ! -d "$ubidevdir" ] && return 1
- for ubivoldir in $ubidevdir/${1}_*; do
- [ ! -d "$ubivoldir" ] && continue
- if [ "$( cat $ubivoldir/name )" = "$2" ]; then
- basename $ubivoldir
- ubi_mknod "$ubivoldir"
- return 0
- fi
- done
-}
-
-nand_find_ubi() {
- local ubidevdir ubidev mtdnum
- mtdnum="$( find_mtd_index $1 )"
- [ ! "$mtdnum" ] && return 1
- for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
- [ ! -d "$ubidevdir" ] && continue
- cmtdnum="$( cat $ubidevdir/mtd_num )"
- [ ! "$mtdnum" ] && continue
- if [ "$mtdnum" = "$cmtdnum" ]; then
- ubidev=$( basename $ubidevdir )
- ubi_mknod "$ubidevdir"
- echo $ubidev
- return 0
- fi
- done
-}
-
-nand_get_magic_long() {
- dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
-}
-
-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
-}
-
-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_tar() {
- identify_magic $(get_magic_long_tar "$1" "$2")
-}
-
-nand_restore_config() {
- sync
- local ubidev=$( nand_find_ubi $CI_UBIPART )
- local ubivol="$( nand_find_volume $ubidev rootfs_data )"
- [ ! "$ubivol" ] &&
- ubivol="$( nand_find_volume $ubidev rootfs )"
- mkdir /tmp/new_root
- if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
- echo "mounting ubifs $ubivol failed"
- rmdir /tmp/new_root
- return 1
- fi
- mv "$1" "/tmp/new_root/sysupgrade.tgz"
- umount /tmp/new_root
- sync
- rmdir /tmp/new_root
-}
-
-nand_upgrade_prepare_ubi() {
- local rootfs_length="$1"
- local rootfs_type="$2"
- local has_kernel="${3:-0}"
- local has_env="${4:-0}"
-
- local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
- if [ ! "$mtdnum" ]; then
- echo "cannot find ubi mtd partition $CI_UBIPART"
- return 1
- fi
-
- local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
- if [ ! "$ubidev" ]; then
- ubiattach -m "$mtdnum"
- sync
- ubidev="$( nand_find_ubi "$CI_UBIPART" )"
- 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
-
- local kern_ubivol="$( nand_find_volume $ubidev kernel )"
- local root_ubivol="$( nand_find_volume $ubidev rootfs )"
- local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
-
- # remove ubiblock device of rootfs
- local root_ubiblk="ubiblock${root_ubivol:3}"
- if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then
- echo "removing $root_ubiblk"
- if ! ubiblock -r /dev/$root_ubivol; then
- echo "cannot remove $root_ubiblk"
- return 1;
- fi
- fi
-
- # kill volumes
- [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N kernel || true
- [ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs || true
- [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
-
- # update kernel
- if [ "$has_kernel" = "1" ]; then
- if ! ubimkvol /dev/$ubidev -N kernel -s $kernel_length; then
- echo "cannot create kernel volume"
- return 1;
- fi
- fi
-
- # update rootfs
- local root_size_param
- if [ "$rootfs_type" = "ubifs" ]; then
- root_size_param="-m"
- else
- root_size_param="-s $rootfs_length"
- fi
- if ! ubimkvol /dev/$ubidev -N rootfs $root_size_param; then
- echo "cannot create rootfs volume"
- return 1;
- fi
-
- # create rootfs_data for non-ubifs rootfs
- if [ "$rootfs_type" != "ubifs" ]; then
- if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then
- echo "cannot initialize rootfs_data volume"
- return 1
- 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"
- reboot -f
-}
-
-# Flash the UBI image to MTD partition
-nand_upgrade_ubinized() {
- local ubi_file="$1"
- local mtdnum="$(find_mtd_index "$CI_UBIPART")"
-
- [ ! "$mtdnum" ] && {
- CI_UBIPART="rootfs"
- mtdnum="$(find_mtd_index "$CI_UBIPART")"
- }
-
- if [ ! "$mtdnum" ]; then
- echo "cannot find mtd device $CI_UBIPART"
- reboot -f
- fi
-
- local mtddev="/dev/mtd${mtdnum}"
- ubidetach -p "${mtddev}" || true
- sync
- ubiformat "${mtddev}" -y -f "${ubi_file}"
- ubiattach -p "${mtddev}"
- nand_do_upgrade_success
-}
-
-# Write the UBIFS image to UBI volume
-nand_upgrade_ubifs() {
- local rootfs_length=`(cat $1 | wc -c) 2> /dev/null`
-
- nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0"
-
- local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
- local root_ubivol="$(nand_find_volume $ubidev rootfs)"
- ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
-
- nand_do_upgrade_success
-}
-
-nand_upgrade_tar() {
- local tar_file="$1"
- local board_name="$(cat /tmp/sysinfo/board_name)"
- local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
-
- local kernel_length=`(tar xf $tar_file sysupgrade-$board_name/kernel -O | wc -c) 2> /dev/null`
- local rootfs_length=`(tar xf $tar_file sysupgrade-$board_name/root -O | wc -c) 2> /dev/null`
-
- local rootfs_type="$(identify_tar "$tar_file" sysupgrade-$board_name/root)"
-
- local has_kernel=1
- local has_env=0
-
- [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
- tar xf $tar_file sysupgrade-$board_name/kernel -O | mtd write - $CI_KERNPART
- }
- [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0
-
- nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env"
-
- local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
- [ "$has_kernel" = "1" ] && {
- local kern_ubivol="$(nand_find_volume $ubidev kernel)"
- tar xf $tar_file sysupgrade-$board_name/kernel -O | \
- ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
- }
-
- local root_ubivol="$(nand_find_volume $ubidev rootfs)"
- tar xf $tar_file sysupgrade-$board_name/root -O | \
- ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
-
- nand_do_upgrade_success
-}
-
-# Recognize type of passed file and start the upgrade process
-nand_do_upgrade_stage2() {
- local file_type=$(identify $1)
-
- [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
-
- case "$file_type" in
- "ubi") nand_upgrade_ubinized $1;;
- "ubifs") nand_upgrade_ubifs $1;;
- *) nand_upgrade_tar $1;;
- esac
-}
-
-nand_upgrade_stage2() {
- [ $1 = "nand" ] && {
- [ -f "$2" ] && {
- touch /tmp/sysupgrade
-
- killall -9 telnetd
- killall -9 dropbear
- killall -9 ash
-
- kill_remaining TERM
- sleep 3
- kill_remaining KILL
-
- sleep 1
-
- if [ -n "$(rootfs_type)" ]; then
- v "Switching to ramdisk..."
- run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2"
- else
- nand_do_upgrade_stage2 $2
- fi
- return 0
- }
- echo "Nand upgrade failed"
- exit 1
- }
-}
-
-nand_upgrade_stage1() {
- [ -f /tmp/sysupgrade-nand-path ] && {
- path="$(cat /tmp/sysupgrade-nand-path)"
- [ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] &&
- rm $CONF_TAR
-
- ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }"
- exit 0
- }
-}
-append sysupgrade_pre_upgrade nand_upgrade_stage1
-
-# 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)
-#
-# You usually want to call this function in platform_check_image.
-#
-# $(1): board name, used in case of passing TAR file
-# $(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)"
-
- [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && {
- echo "Invalid sysupgrade file."
- return 1
- }
-
- echo -n $2 > /tmp/sysupgrade-nand-path
- cp /sbin/upgraded /tmp/
-
- return 0
-}
-
-# Start NAND upgrade process
-#
-# $(1): file to be used for upgrade
-nand_do_upgrade() {
- echo -n $1 > /tmp/sysupgrade-nand-path
- install_bin /sbin/upgraded
- ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded
- nand_upgrade_stage1
-}

View File

@ -0,0 +1,468 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Sat, 22 Apr 2017 00:54:50 +0200
Subject: base-files: always use staged sysupgrade
Support for the -d and -p options is dropped; it may be added again at some
point by adding these flags to the ubus sysupgrade call.
A downside of this is that we get a lot less information about the progress
of the upgrade: as soon as the actual upgrade starts, all shell sessions
are killed to allow unmounting the root filesystem.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh
index 2064adf775c491725dbff5826b94bd6132d8d060..23f18ceb775caac057ee7a757922954f812f77ce 100644
--- a/package/base-files/files/lib/upgrade/common.sh
+++ b/package/base-files/files/lib/upgrade/common.sh
@@ -92,51 +92,37 @@ run_ramfs() { # <command> [...]
exec /bin/busybox ash -c "$*"
}
-kill_remaining() { # [ <signal> ]
+kill_remaining() { # [ <signal> [ <loop> ] ]
local sig="${1:-TERM}"
+ local loop="${2:-0}"
+ local run=true
+ local stat
+
echo -n "Sending $sig to remaining processes ... "
- local my_pid=$$
- local my_ppid=$(cut -d' ' -f4 /proc/$my_pid/stat)
- local my_ppisupgraded=
- grep -q upgraded /proc/$my_ppid/cmdline >/dev/null && {
- local my_ppisupgraded=1
- }
-
- local stat
- for stat in /proc/[0-9]*/stat; do
- [ -f "$stat" ] || continue
-
- local pid name state ppid rest
- read pid name state ppid rest < $stat
- name="${name#(}"; name="${name%)}"
-
- local cmdline
- read cmdline < /proc/$pid/cmdline
-
- # Skip kernel threads
- [ -n "$cmdline" ] || continue
-
- if [ $$ -eq 1 ] || [ $my_ppid -eq 1 ] && [ -n "$my_ppisupgraded" ]; then
- # Running as init process, kill everything except me
- if [ $pid -ne $$ ] && [ $pid -ne $my_ppid ]; then
- echo -n "$name "
- kill -$sig $pid 2>/dev/null
- fi
- else
- case "$name" in
- # Skip essential services
- *procd*|*ash*|*init*|*watchdog*|*ssh*|*dropbear*|*telnet*|*login*|*hostapd*|*wpa_supplicant*|*nas*) : ;;
-
- # Killable process
- *)
- if [ $pid -ne $$ ] && [ $ppid -ne $$ ]; then
- echo -n "$name "
- kill -$sig $pid 2>/dev/null
- fi
- ;;
- esac
- fi
+ while $run; do
+ run=false
+ for stat in /proc/[0-9]*/stat; do
+ [ -f "$stat" ] || continue
+
+ local pid name state ppid rest
+ read pid name state ppid rest < $stat
+ name="${name#(}"; name="${name%)}"
+
+ # Skip PID1, ourself and our children
+ [ $pid -ne 1 -a $pid -ne $$ -a $ppid -ne $$ ] || continue
+
+ local cmdline
+ read cmdline < /proc/$pid/cmdline
+
+ # Skip kernel threads
+ [ -n "$cmdline" ] || continue
+
+ echo -n "$name "
+ kill -$sig $pid 2>/dev/null
+
+ [ $loop -eq 1 ] && run=true
+ done
done
echo ""
}
@@ -171,28 +157,31 @@ v() {
[ "$VERBOSE" -ge 1 ] && echo "$@"
}
+json_string() {
+ local v="$1"
+ v="${v//\\/\\\\}"
+ v="${v//\"/\\\"}"
+ echo "\"$v\""
+}
+
rootfs_type() {
/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }'
}
get_image() { # <source> [ <command> ]
local from="$1"
- local conc="$2"
- local cmd
-
- case "$from" in
- http://*|ftp://*) cmd="wget -O- -q";;
- *) cmd="cat";;
- esac
- if [ -z "$conc" ]; then
- local magic="$(eval $cmd \"$from\" 2>/dev/null | dd bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
+ local cat="$2"
+
+ if [ -z "$cat" ]; then
+ local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
case "$magic" in
- 1f8b) conc="zcat";;
- 425a) conc="bzcat";;
+ 1f8b) cat="zcat";;
+ 425a) cat="bzcat";;
+ *) cat="cat";;
esac
fi
- eval "$cmd \"$from\" 2>/dev/null ${conc:+| $conc}"
+ $cat "$from" 2>/dev/null
}
get_magic_word() {
@@ -316,12 +305,14 @@ default_do_upgrade() {
fi
}
-do_upgrade() {
+do_upgrade_stage2() {
v "Performing system upgrade..."
- if type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
- platform_do_upgrade "$ARGV"
+ if [ -n "$do_upgrade" ]; then
+ $do_upgrade "$IMAGE"
+ elif type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
+ platform_do_upgrade "$IMAGE"
else
- default_do_upgrade "$ARGV"
+ default_do_upgrade "$IMAGE"
fi
if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then
@@ -329,11 +320,11 @@ do_upgrade() {
fi
v "Upgrade completed"
- [ -n "$DELAY" ] && sleep "$DELAY"
- ask_bool 1 "Reboot" && {
- v "Rebooting system..."
- reboot -f
- sleep 5
- echo b 2>/dev/null >/proc/sysrq-trigger
- }
+ sleep 1
+
+ v "Rebooting system..."
+ umount -a
+ reboot -f
+ sleep 5
+ echo b 2>/dev/null >/proc/sysrq-trigger
}
diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh
index ec2a014a00461ca897d521e2d065f5399f1f8c48..05940e2567e22fe1936fb5afdc7c1df4826570ee 100644
--- a/package/base-files/files/lib/upgrade/nand.sh
+++ b/package/base-files/files/lib/upgrade/nand.sh
@@ -272,7 +272,16 @@ nand_upgrade_tar() {
}
# Recognize type of passed file and start the upgrade process
-nand_do_upgrade_stage2() {
+nand_do_upgrade() {
+ if [ -n "$IS_PRE_UPGRADE" ]; then
+ # Previously, nand_do_upgrade was called from the platform_pre_upgrade
+ # hook; this piece of code handles scripts that haven't been
+ # updated. All scripts should gradually move to call nand_do_upgrade
+ # from platform_do_upgrade instead.
+ export do_upgrade=nand_do_upgrade
+ return
+ fi
+
local file_type=$(identify $1)
[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
@@ -284,46 +293,6 @@ nand_do_upgrade_stage2() {
esac
}
-nand_upgrade_stage2() {
- [ $1 = "nand" ] && {
- [ -f "$2" ] && {
- touch /tmp/sysupgrade
-
- killall -9 telnetd
- killall -9 dropbear
- killall -9 ash
-
- kill_remaining TERM
- sleep 3
- kill_remaining KILL
-
- sleep 1
-
- if [ -n "$(rootfs_type)" ]; then
- v "Switching to ramdisk..."
- run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2"
- else
- nand_do_upgrade_stage2 $2
- fi
- return 0
- }
- echo "Nand upgrade failed"
- exit 1
- }
-}
-
-nand_upgrade_stage1() {
- [ -f /tmp/sysupgrade-nand-path ] && {
- path="$(cat /tmp/sysupgrade-nand-path)"
- [ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] &&
- rm $CONF_TAR
-
- ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }"
- exit 0
- }
-}
-append sysupgrade_pre_upgrade nand_upgrade_stage1
-
# 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
@@ -353,13 +322,3 @@ nand_do_platform_check() {
return 0
}
-
-# Start NAND upgrade process
-#
-# $(1): file to be used for upgrade
-nand_do_upgrade() {
- echo -n $1 > /tmp/sysupgrade-nand-path
- install_bin /sbin/upgraded
- ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded
- nand_upgrade_stage1
-}
diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2
new file mode 100755
index 0000000000000000000000000000000000000000..4e2aa3a23c3bab07a795762a30a4d4f701081934
--- /dev/null
+++ b/package/base-files/files/lib/upgrade/stage2
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+export IMAGE="$1"
+COMMAND="$2"
+
+export ARGV="$IMAGE"
+export ARGC=1
+
+export SAVE_CONFIG=1
+export SAVE_PARTITIONS=1
+
+export INTERACTIVE=0
+export VERBOSE=1
+export CONFFILES=/tmp/sysupgrade.conffiles
+export CONF_TAR=/tmp/sysupgrade.tgz
+
+
+[ -f "$CONF_TAR" ] || export SAVE_CONFIG=0
+[ -f /tmp/sysupgrade.always.overwrite.bootdisk.partmap ] && export SAVE_PARTITIONS=0
+
+include /lib/upgrade
+
+
+killall -9 telnetd
+killall -9 dropbear
+killall -9 ash
+
+kill_remaining TERM
+sleep 3
+kill_remaining KILL 1
+
+sleep 1
+
+
+if [ -n "$IMAGE" ] && type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
+ IS_PRE_UPGRADE=1 platform_pre_upgrade "$IMAGE"
+
+ # Needs to be unset again because of busybox weirdness ...
+ IS_PRE_UPGRADE=
+fi
+
+if [ -n "$(rootfs_type)" ]; then
+ echo "Switching to ramdisk..."
+ run_ramfs "$COMMAND"
+else
+ exec /bin/busybox ash -c "$COMMAND"
+fi
diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
index 759c841e131a415c8009995c372cce1f55fb78a0..d48416f6de244b97f426ae0b83d425ac5c1bc5b3 100755
--- a/package/base-files/files/sbin/sysupgrade
+++ b/package/base-files/files/sbin/sysupgrade
@@ -1,4 +1,7 @@
#!/bin/sh
+
+[ "$1" = "nand" ] && exec /lib/upgrade/stage2 "$2" "$3"
+
. /lib/functions.sh
. /lib/functions/system.sh
@@ -11,7 +14,6 @@ export VERBOSE=1
export SAVE_CONFIG=1
export SAVE_OVERLAY=0
export SAVE_PARTITIONS=1
-export DELAY=
export CONF_IMAGE=
export CONF_BACKUP_LIST=0
export CONF_BACKUP=
@@ -25,7 +27,6 @@ export TEST=0
while [ -n "$1" ]; do
case "$1" in
-i) export INTERACTIVE=1;;
- -d) export DELAY="$2"; shift;;
-v) export VERBOSE="$(($VERBOSE + 1))";;
-q) export VERBOSE="$(($VERBOSE - 1))";;
-n) export SAVE_CONFIG=0;;
@@ -50,10 +51,9 @@ done
export CONFFILES=/tmp/sysupgrade.conffiles
export CONF_TAR=/tmp/sysupgrade.tgz
-export ARGV="$*"
-export ARGC="$#"
+IMAGE="$1"
-[ -z "$ARGV" -a -z "$NEED_IMAGE" -o $HELP -gt 0 ] && {
+[ -z "$IMAGE" -a -z "$NEED_IMAGE" -o $HELP -gt 0 ] && {
cat <<EOF
Usage: $0 [<upgrade-option>...] <image file or URL>
$0 [-q] [-i] <backup-command> <file>
@@ -90,7 +90,7 @@ EOF
exit 1
}
-[ -n "$ARGV" -a -n "$NEED_IMAGE" ] && {
+[ -n "$IMAGE" -a -n "$NEED_IMAGE" ] && {
cat <<-EOF
-b|--create-backup and -r|--restore-backup do not perform a firmware upgrade.
Do not specify both -b|-r and a firmware image.
@@ -134,14 +134,13 @@ sysupgrade_image_check="platform_check_image"
include /lib/upgrade
-[ "$1" = "nand" ] && nand_upgrade_stage2 $@
-
do_save_conffiles() {
local conf_tar="${1:-$CONF_TAR}"
[ -z "$(rootfs_type)" ] && {
echo "Cannot save config while running from ramdisk."
ask_bool 0 "Abort" && exit
+ rm -f "$conf_tar"
return 0
}
run_hooks "$CONFFILES" $sysupgrade_init_conffiles
@@ -182,8 +181,33 @@ type platform_check_image >/dev/null 2>/dev/null || {
exit 1
}
+case "$IMAGE" in
+ http://*)
+ wget -O/tmp/sysupgrade.img "$IMAGE"
+ IMAGE=/tmp/sysupgrade.img
+ ;;
+esac
+
+IMAGE="$(readlink -f "$IMAGE")"
+
+case "$IMAGE" in
+ '')
+ echo "Image file not found."
+ exit 1
+ ;;
+ /tmp/*) ;;
+ *)
+ v "Image not in /tmp, copying..."
+ cp -f "$IMAGE" /tmp/sysupgrade.img
+ IMAGE=/tmp/sysupgrade.img
+ ;;
+esac
+
+export ARGV="$IMAGE"
+export ARGC=1
+
for check in $sysupgrade_image_check; do
- ( eval "$check \"\$ARGV\"" ) || {
+ ( $check "$IMAGE" ) || {
if [ $FORCE -eq 1 ]; then
echo "Image check '$check' failed but --force given - will update anyway!"
break
@@ -209,6 +233,7 @@ elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then
[ $TEST -eq 1 ] || do_save_conffiles
export SAVE_CONFIG=1
else
+ [ $TEST -eq 1 ] || rm -f "$CONF_TAR"
export SAVE_CONFIG=0
fi
@@ -216,28 +241,18 @@ if [ $TEST -eq 1 ]; then
exit 0
fi
-run_hooks "" $sysupgrade_pre_upgrade
-
-# Some platforms/devices may want different sysupgrade process, e.g. without
-# killing processes yet or calling ubus system upgrade method.
-# This is needed e.g. on NAND devices where we just want to trigger stage1 at
-# this point.
-if type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
- platform_pre_upgrade "$ARGV"
+if [ $SAVE_PARTITIONS -eq 0 ]; then
+ touch /tmp/sysupgrade.always.overwrite.bootdisk.partmap
+else
+ rm -f /tmp/sysupgrade.always.overwrite.bootdisk.partmap
fi
-ubus call system upgrade
-touch /tmp/sysupgrade
-
-if [ ! -f /tmp/failsafe ] ; then
- kill_remaining TERM
- sleep 3
- kill_remaining KILL
-fi
+run_hooks "" $sysupgrade_pre_upgrade
-if [ -n "$(rootfs_type)" ]; then
- v "Switching to ramdisk..."
- run_ramfs '. /lib/functions.sh; include /lib/upgrade; do_upgrade'
-else
- do_upgrade
-fi
+install_bin /sbin/upgraded
+v "Commencing upgrade. All shell sessions will be closed now."
+ubus call system sysupgrade "{
+ \"prefix\": \"$RAM_ROOT\",
+ \"path\": $(json_string "$IMAGE"),
+ \"command\": \". /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2\"
+}"

View File

@ -0,0 +1,19 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 3 May 2017 08:29:24 +0200
Subject: fstools: clean up trailing whitespace in snapshot script
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/system/fstools/files/snapshot b/package/system/fstools/files/snapshot
index a0e0ec0c334ca72086c3e30c62ae988c61ff1bde..eec7214032d1b147d5e989cd305c5c0cd1357a55 100644
--- a/package/system/fstools/files/snapshot
+++ b/package/system/fstools/files/snapshot
@@ -42,7 +42,7 @@ do_snapshot_upgrade() {
opkg list-upgradable
[ $? -eq 0 ] || exit 2
-
+
UPDATES=`opkg list-upgradable | cut -d" " -f1`
[ -z "${UPDATES}" ] && exit 0

View File

@ -0,0 +1,36 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 3 May 2017 08:29:55 +0200
Subject: fstools: snapshot: handle jffs2 conversion using upgraded
We can reuse the kill_remaining and run_ramfs facilities of the stage2 run
by upgraded.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/system/fstools/files/snapshot b/package/system/fstools/files/snapshot
index eec7214032d1b147d5e989cd305c5c0cd1357a55..79be0d24bb68cc9b4ea8ce5b5d6b7558b2f0b0c5 100644
--- a/package/system/fstools/files/snapshot
+++ b/package/system/fstools/files/snapshot
@@ -64,14 +64,16 @@ do_convert_jffs2() {
do_convert() {
. /lib/functions.sh
. /lib/upgrade/common.sh
- ubus call system upgrade
- touch /tmp/sysupgrade
+
cd /overlay
tar czf /tmp/snapshot.tar.gz *
- kill_remaining TERM
- sleep 3
- kill_remaining KILL
- run_ramfs '. /sbin/snapshot; do_convert_jffs2'
+
+ install_bin /sbin/upgraded
+ ubus call system sysupgrade "{
+ \"prefix\": \"$RAM_ROOT\",
+ \"path\": \"\",
+ \"command\": \". /sbin/snapshot; do_convert_jffs2\"
+ }"
}
[ -n "$(cat /proc/mounts|grep /overlay|grep jffs2)" ] && {

View File

@ -0,0 +1,255 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Sun, 23 Apr 2017 23:33:14 +0200
Subject: base-files: sysupgrade cleanup
Some functions only used by stage2 are moved there from common.sh.
One piece that could still use more cleanup is platform_pre_upgrade: many
targets reference files from there are aren't available in the ramfs, so
we need to evaluate it before the switch; conversely, flash writes happen
in that function on some targets. Targets that do the latter should be
fixed eventually to use platform_do_upgrade for that purpose.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh
index 23f18ceb775caac057ee7a757922954f812f77ce..fc59bf2323498d332159b00eb7ab443bfe6b147e 100644
--- a/package/base-files/files/lib/upgrade/common.sh
+++ b/package/base-files/files/lib/upgrade/common.sh
@@ -30,103 +30,6 @@ install_bin() { # <file> [ <symlink> ... ]
}; done
}
-supivot() { # <new_root> <old_root>
- /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1
- mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
- /bin/mount -o noatime,move /proc $1/proc && \
- pivot_root $1 $1$2 || {
- /bin/umount -l $1 $1
- return 1
- }
-
- /bin/mount -o noatime,move $2/sys /sys
- /bin/mount -o noatime,move $2/dev /dev
- /bin/mount -o noatime,move $2/tmp /tmp
- /bin/mount -o noatime,move $2/overlay /overlay 2>&-
- return 0
-}
-
-run_ramfs() { # <command> [...]
- install_bin /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \
- /sbin/pivot_root /usr/bin/wget /sbin/reboot /bin/sync /bin/dd \
- /bin/grep /bin/cp /bin/mv /bin/tar /usr/bin/md5sum "/usr/bin/[" \
- /bin/dd /bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump \
- /bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \
- /bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir \
- /bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find
-
- install_bin /sbin/mtd
- install_bin /sbin/mount_root
- install_bin /sbin/snapshot
- install_bin /sbin/snapshot_tool
- install_bin /usr/sbin/ubiupdatevol
- install_bin /usr/sbin/ubiattach
- install_bin /usr/sbin/ubiblock
- install_bin /usr/sbin/ubiformat
- install_bin /usr/sbin/ubidetach
- install_bin /usr/sbin/ubirsvol
- install_bin /usr/sbin/ubirmvol
- install_bin /usr/sbin/ubimkvol
- install_bin /usr/sbin/partx
- for file in $RAMFS_COPY_BIN; do
- install_bin ${file//:/ }
- done
- install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA
-
- [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
-
- supivot $RAM_ROOT /mnt || {
- echo "Failed to switch over to ramfs. Please reboot."
- exit 1
- }
-
- /bin/mount -o remount,ro /mnt
- /bin/umount -l /mnt
-
- grep /overlay /proc/mounts > /dev/null && {
- /bin/mount -o noatime,remount,ro /overlay
- /bin/umount -l /overlay
- }
-
- # spawn a new shell from ramdisk to reduce the probability of cache issues
- exec /bin/busybox ash -c "$*"
-}
-
-kill_remaining() { # [ <signal> [ <loop> ] ]
- local sig="${1:-TERM}"
- local loop="${2:-0}"
- local run=true
- local stat
-
- echo -n "Sending $sig to remaining processes ... "
-
- while $run; do
- run=false
- for stat in /proc/[0-9]*/stat; do
- [ -f "$stat" ] || continue
-
- local pid name state ppid rest
- read pid name state ppid rest < $stat
- name="${name#(}"; name="${name%)}"
-
- # Skip PID1, ourself and our children
- [ $pid -ne 1 -a $pid -ne $$ -a $ppid -ne $$ ] || continue
-
- local cmdline
- read cmdline < /proc/$pid/cmdline
-
- # Skip kernel threads
- [ -n "$cmdline" ] || continue
-
- echo -n "$name "
- kill -$sig $pid 2>/dev/null
-
- [ $loop -eq 1 ] && run=true
- done
- done
- echo ""
-}
-
run_hooks() {
local arg="$1"; shift
for func in "$@"; do
diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2
index 4e2aa3a23c3bab07a795762a30a4d4f701081934..cc8047d988e39ca9ba27d2588744aad469d1d978 100755
--- a/package/base-files/files/lib/upgrade/stage2
+++ b/package/base-files/files/lib/upgrade/stage2
@@ -24,6 +24,104 @@ export CONF_TAR=/tmp/sysupgrade.tgz
include /lib/upgrade
+supivot() { # <new_root> <old_root>
+ /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1
+ mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
+ /bin/mount -o noatime,move /proc $1/proc && \
+ pivot_root $1 $1$2 || {
+ /bin/umount -l $1 $1
+ return 1
+ }
+
+ /bin/mount -o noatime,move $2/sys /sys
+ /bin/mount -o noatime,move $2/dev /dev
+ /bin/mount -o noatime,move $2/tmp /tmp
+ /bin/mount -o noatime,move $2/overlay /overlay 2>&-
+ return 0
+}
+
+switch_to_ramfs() {
+ install_bin /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \
+ /sbin/pivot_root /sbin/reboot /bin/sync /bin/dd /bin/grep \
+ /bin/cp /bin/mv /bin/tar /usr/bin/md5sum "/usr/bin/[" /bin/dd \
+ /bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump \
+ /bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \
+ /bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir \
+ /bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find \
+ /bin/mknod
+
+ install_bin /sbin/mtd
+ install_bin /sbin/mount_root
+ install_bin /sbin/snapshot
+ install_bin /sbin/snapshot_tool
+ install_bin /usr/sbin/ubiupdatevol
+ install_bin /usr/sbin/ubiattach
+ install_bin /usr/sbin/ubiblock
+ install_bin /usr/sbin/ubiformat
+ install_bin /usr/sbin/ubidetach
+ install_bin /usr/sbin/ubirsvol
+ install_bin /usr/sbin/ubirmvol
+ install_bin /usr/sbin/ubimkvol
+ install_bin /usr/sbin/partx
+ install_bin /usr/sbin/losetup
+ install_bin /usr/sbin/mkfs.ext4
+ for file in $RAMFS_COPY_BIN; do
+ install_bin ${file//:/ }
+ done
+ install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA
+
+ [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
+
+ supivot $RAM_ROOT /mnt || {
+ echo "Failed to switch over to ramfs. Please reboot."
+ exit 1
+ }
+
+ /bin/mount -o remount,ro /mnt
+ /bin/umount -l /mnt
+
+ grep /overlay /proc/mounts > /dev/null && {
+ /bin/mount -o noatime,remount,ro /overlay
+ /bin/umount -l /overlay
+ }
+}
+
+kill_remaining() { # [ <signal> [ <loop> ] ]
+ local sig="${1:-TERM}"
+ local loop="${2:-0}"
+ local run=true
+ local stat
+
+ echo -n "Sending $sig to remaining processes ... "
+
+ while $run; do
+ run=false
+ for stat in /proc/[0-9]*/stat; do
+ [ -f "$stat" ] || continue
+
+ local pid name state ppid rest
+ read pid name state ppid rest < $stat
+ name="${name#(}"; name="${name%)}"
+
+ # Skip PID1, ourself and our children
+ [ $pid -ne 1 -a $pid -ne $$ -a $ppid -ne $$ ] || continue
+
+ local cmdline
+ read cmdline < /proc/$pid/cmdline
+
+ # Skip kernel threads
+ [ -n "$cmdline" ] || continue
+
+ echo -n "$name "
+ kill -$sig $pid 2>/dev/null
+
+ [ $loop -eq 1 ] && run=true
+ done
+ done
+ echo ""
+}
+
+
killall -9 telnetd
killall -9 dropbear
killall -9 ash
@@ -44,7 +142,8 @@ fi
if [ -n "$(rootfs_type)" ]; then
echo "Switching to ramdisk..."
- run_ramfs "$COMMAND"
-else
- exec /bin/busybox ash -c "$COMMAND"
+ switch_to_ramfs
fi
+
+# Exec new shell from ramfs
+exec /bin/busybox ash -c "$COMMAND"
diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
index d48416f6de244b97f426ae0b83d425ac5c1bc5b3..2060679e61948e4661a408df009ff3ef3c6faa91 100755
--- a/package/base-files/files/sbin/sysupgrade
+++ b/package/base-files/files/sbin/sysupgrade
@@ -1,7 +1,5 @@
#!/bin/sh
-[ "$1" = "nand" ] && exec /lib/upgrade/stage2 "$2" "$3"
-
. /lib/functions.sh
. /lib/functions/system.sh

View File

@ -0,0 +1,71 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Mon, 24 Apr 2017 01:31:04 +0200
Subject: base-files: add support for staged sysupgrades from failsafe mode
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/lib/preinit/40_run_failsafe_hook b/package/base-files/files/lib/preinit/40_run_failsafe_hook
index cb43ad39cbae07c533af63d7ff445d41a5b988df..fee0c8f0e19f2bf46771cd23ceaaff2db7af7611 100644
--- a/package/base-files/files/lib/preinit/40_run_failsafe_hook
+++ b/package/base-files/files/lib/preinit/40_run_failsafe_hook
@@ -4,8 +4,12 @@
run_failsafe_hook() {
if [ "$FAILSAFE" = "true" ]; then
+ lock /tmp/.failsafe
boot_run_hook failsafe
- lock -w /tmp/.failsafe
+ while [ ! -e /tmp/sysupgrade ]; do
+ lock -w /tmp/.failsafe
+ done
+ exit
fi
}
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 15dcbd884f1f2ec4fd84c92482a9b656d1a26dd7..96e95b1d99c631536c0b30ee5c2e19b3c63bbc64 100644
--- a/package/base-files/files/lib/preinit/99_10_failsafe_login
+++ b/package/base-files/files/lib/preinit/99_10_failsafe_login
@@ -7,9 +7,13 @@ failsafe_netlogin () {
}
failsafe_shell() {
- lock /tmp/.failsafe
- ash --login
- echo "Please reboot system when done with failsafe network logins"
+ 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 &
}
boot_hook_add failsafe failsafe_netlogin
diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
index 2060679e61948e4661a408df009ff3ef3c6faa91..853134a2cb8a2ef1d56671bfeee46704892909d8 100755
--- a/package/base-files/files/sbin/sysupgrade
+++ b/package/base-files/files/sbin/sysupgrade
@@ -249,8 +249,16 @@ run_hooks "" $sysupgrade_pre_upgrade
install_bin /sbin/upgraded
v "Commencing upgrade. All shell sessions will be closed now."
-ubus call system sysupgrade "{
- \"prefix\": \"$RAM_ROOT\",
- \"path\": $(json_string "$IMAGE"),
- \"command\": \". /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2\"
-}"
+
+COMMAND='. /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2'
+
+if [ -n "$FAILSAFE" ]; then
+ printf '%s\x00%s\x00%s' "$RAM_ROOT" "$IMAGE" "$COMMAND" >/tmp/sysupgrade
+ lock -u /tmp/.failsafe
+else
+ ubus call system sysupgrade "{
+ \"prefix\": $(json_string "$RAM_ROOT"),
+ \"path\": $(json_string "$IMAGE"),
+ \"command\": $(json_string "$COMMAND")
+ }"
+fi

View File

@ -0,0 +1,62 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 3 May 2017 08:57:29 +0200
Subject: x86: sysupgrade: move partition table change check to platform_check_image
The staged sysupgrade will prevent us from using ask_bool in
platform_do_upgrade; therefore, the check is moved to platform_check_image.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
index d3e9f360aadedad0995da55205364940c9884ba4..81b349a81816033eef9df464b2a70fdb998e5a1d 100644
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
@@ -1,13 +1,37 @@
platform_check_image() {
+ local diskdev partdev diff
[ "$#" -gt 1 ] && return 1
case "$(get_magic_word "$1")" in
- eb48|eb63) return 0;;
+ eb48|eb63) ;;
*)
echo "Invalid image type"
return 1
;;
esac
+
+ export_bootdevice && export_partdevice diskdev 0 || {
+ echo "Unable to determine upgrade device"
+ return 1
+ }
+
+ get_partitions "/dev/$diskdev" bootdisk
+
+ #extract the boot sector from the image
+ get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
+
+ 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
+ echo "Partition layout has changed. Full image will be written."
+ ask_bool 0 "Abort" && exit 1
+ return 0
+ fi
}
platform_copy_config() {
@@ -36,9 +60,6 @@ platform_do_upgrade() {
#compare tables
diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
if [ -n "$diff" ]; then
- echo "Partition layout is changed. Full image will be written."
- ask_bool 0 "Abort" && exit
-
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
return 0
fi

View File

@ -0,0 +1,90 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 3 May 2017 09:05:25 +0200
Subject: x86: sysupgrade: refactor platform_do_upgrade
By returning early when no upgrade device can be found and handling the
SAVE_PARTITIONS=0 case differently, we can get rid of two levels of if.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
index 81b349a81816033eef9df464b2a70fdb998e5a1d..4fa71999be7be3972676a1019488972dccd57fa2 100644
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
@@ -47,40 +47,43 @@ platform_copy_config() {
platform_do_upgrade() {
local diskdev partdev diff
- if export_bootdevice && export_partdevice diskdev 0; then
- sync
- if [ "$SAVE_PARTITIONS" = "1" ]; then
- get_partitions "/dev/$diskdev" bootdisk
-
- #extract the boot sector from the image
- get_image "$@" | dd 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)"
- if [ -n "$diff" ]; then
- get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
- return 0
- fi
-
- #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
- echo "Writing image to /dev/$partdev..."
- get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
- else
- echo "Unable to find partition $part device, skipped."
- fi
- done < /tmp/partmap.image
-
- #copy partition uuid
- echo "Writing new UUID to /dev/$diskdev..."
- get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
+ export_bootdevice && export_partdevice diskdev 0 || {
+ echo "Unable to determine upgrade device"
+ return 1
+ }
+
+ sync
+
+ if [ "$SAVE_PARTITIONS" = "1" ]; then
+ get_partitions "/dev/$diskdev" bootdisk
+
+ #extract the boot sector from the image
+ get_image "$@" | dd 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 of="/dev/$diskdev" bs=4096 conv=fsync
+ return 0
+ fi
+
+ #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
+ echo "Writing image to /dev/$partdev..."
+ get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
else
- get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
+ echo "Unable to find partition $part device, skipped."
fi
+ done < /tmp/partmap.image
- sleep 1
- fi
+ #copy partition uuid
+ echo "Writing new UUID to /dev/$diskdev..."
+ get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
}

View File

@ -0,0 +1,26 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 3 May 2017 09:08:29 +0200
Subject: x86: sysupgrade: explicitly rescan disk after writing partition table
This should ensure that the kernel partition can be mounted in
platform_copy_config when its size has changed.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
index 4fa71999be7be3972676a1019488972dccd57fa2..439ba8f5125d97932248ff966340165a84e1b24a 100644
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
@@ -70,6 +70,12 @@ platform_do_upgrade() {
if [ -n "$diff" ]; then
get_image "$@" | dd 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"
+
return 0
fi

View File

@ -0,0 +1,85 @@
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Thu, 1 Jun 2017 18:39:12 +0200
Subject: mvebu: fix sysupgrade
mvebu was modifying RAMFS_COPY_BIN and RAMFS_COPY_DATA from a
sysupgrade_pre_upgrade hook. As the ramfs is created from stage2, this
did not have an effect anymore after the staged sysupgrade changes.
As it doesn't really hurt to copy fw_printenv and fw_setenv
unconditionally, simply add them in /lib/upgrade/platform.sh, so stage2
will see them.
Config copying is moved to a function called by platform_copy_config, where
it belongs.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
Fixes: FS#821
Fixes: 30f61a34b4cf "base-files: always use staged sysupgrade"
diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2
index cc8047d988e39ca9ba27d2588744aad469d1d978..bdbb8926643287f48a4ae62c5d1d4b4a29130859 100755
--- a/package/base-files/files/lib/upgrade/stage2
+++ b/package/base-files/files/lib/upgrade/stage2
@@ -48,7 +48,7 @@ switch_to_ramfs() {
/bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \
/bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir \
/bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find \
- /bin/mknod
+ /bin/mknod /bin/touch
install_bin /sbin/mtd
install_bin /sbin/mount_root
diff --git a/target/linux/mvebu/base-files/lib/upgrade/linksys.sh b/target/linux/mvebu/base-files/lib/upgrade/linksys.sh
index fc403332bd38fc521a056ab85783abd90629a1cf..63d1cd14a4deed407b217a518ae25a752f62969e 100644
--- a/target/linux/mvebu/base-files/lib/upgrade/linksys.sh
+++ b/target/linux/mvebu/base-files/lib/upgrade/linksys.sh
@@ -73,14 +73,7 @@ platform_do_upgrade_linksys() {
}
}
-linksys_preupgrade() {
- export RAMFS_COPY_BIN="${RAMFS_COPY_BIN} /usr/sbin/fw_printenv /usr/sbin/fw_setenv"
- export RAMFS_COPY_BIN="${RAMFS_COPY_BIN} /bin/mkdir /bin/touch"
- export RAMFS_COPY_DATA="${RAMFS_COPY_DATA} /etc/fw_env.config /var/lock/fw_printenv.lock"
-
- [ -f /tmp/sysupgrade.tgz ] && {
- cp /tmp/sysupgrade.tgz /tmp/syscfg/sysupgrade.tgz
- }
+platform_copy_config_linksys() {
+ cp -f /tmp/sysupgrade.tgz /tmp/syscfg/sysupgrade.tgz
+ sync
}
-
-append sysupgrade_pre_upgrade linksys_preupgrade
diff --git a/target/linux/mvebu/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/base-files/lib/upgrade/platform.sh
index 46b84435977b83d002ae766fe37c6459a55177ff..7465f7be7649f778ada62cf90aa94b16c11c7e34 100755
--- a/target/linux/mvebu/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mvebu/base-files/lib/upgrade/platform.sh
@@ -4,7 +4,8 @@
. /lib/mvebu.sh
-RAMFS_COPY_DATA=/lib/mvebu.sh
+RAMFS_COPY_BIN='/usr/sbin/fw_printenv /usr/sbin/fw_setenv'
+RAMFS_COPY_DATA='/lib/mvebu.sh /etc/fw_env.config /var/lock/fw_printenv.lock'
platform_check_image() {
local board=$(mvebu_board_name)
@@ -39,6 +40,16 @@ platform_do_upgrade() {
esac
}
+platform_copy_config() {
+ local board=$(mvebu_board_name)
+
+ case "$board" in
+ armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-rango|armada-385-linksys-shelby|armada-xp-linksys-mamba)
+ platform_copy_config_linksys
+ ;;
+ esac
+}
+
disable_watchdog() {
killall watchdog
( ps | grep -v 'grep' | grep '/dev/watchdog' ) && {