123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- 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 3ddd1e74657e0f9893533f917cb56ed0c2e3196c..6f8e408401906666db945a981100962139fc7d32 100644
- --- a/package/base-files/files/lib/upgrade/common.sh
- +++ b/package/base-files/files/lib/upgrade/common.sh
- @@ -56,7 +56,6 @@ run_ramfs() { # <command> [...]
- /bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find \
- /bin/mknod
-
- - install_bin /bin/uclient-fetch /bin/wget
- install_bin /sbin/mtd
- install_bin /sbin/mount_root
- install_bin /sbin/snapshot
- @@ -96,51 +95,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*|*relayd*) : ;;
- -
- - # 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 ""
- }
- @@ -175,28 +160,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() {
- @@ -328,12 +316,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
- @@ -341,12 +331,11 @@ do_upgrade() {
- fi
-
- v "Upgrade completed"
- - [ -n "$DELAY" ] && sleep "$DELAY"
- - ask_bool 1 "Reboot" && {
- - v "Rebooting system..."
- - umount -a
- - 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 6bd2005344c081df20e5a330a69e49e37225c39f..1e69c8f9657b39adf2a2c33bd9bac9303bcbc3d7 100644
- --- a/package/base-files/files/lib/upgrade/nand.sh
- +++ b/package/base-files/files/lib/upgrade/nand.sh
- @@ -283,7 +283,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)
-
- if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
- @@ -299,45 +308,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
- - }
- -}
- -
- # 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
- @@ -364,13 +334,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 c095ca81c50c71021af2dc04a561ac22f6b7442b..2d67371ef74b4b970076a069e97f4fd6a1e0bc95 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.
- @@ -136,14 +136,13 @@ sysupgrade_pre_upgrade="fwtool_pre_upgrade"
-
- 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
- @@ -184,8 +183,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
- @@ -211,6 +235,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
-
- @@ -218,28 +243,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\"
- +}"
|