developer | 707745c | 2022-07-20 14:30:33 +0800 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | |
| 3 | |
| 4 | COMMAND=/lib/upgrade/do_stage2 |
| 5 | |
| 6 | |
developer | 4f4b984 | 2023-02-13 17:54:38 +0800 | [diff] [blame] | 7 | RAMFS_COPY_BIN='mkfs.f2fs blkid blockdev dmsetup fw_printenv fw_setenv' |
developer | 707745c | 2022-07-20 14:30:33 +0800 | [diff] [blame] | 8 | RAMFS_COPY_DATA="/etc/fw_env.config /var/lock/fw_printenv.lock" |
| 9 | RAM_ROOT=/tmp/root |
| 10 | |
| 11 | export IMAGE=$1 |
| 12 | export VERBOSE=1 |
| 13 | |
| 14 | _vn() { |
| 15 | [ -n "$VERBOSE" ] && [ "$VERBOSE" -ge 1 ] && echo -n "$*" >&2 |
| 16 | } |
| 17 | |
| 18 | vn() { |
| 19 | _vn "$(date) upgrade: $@" |
| 20 | } |
| 21 | |
| 22 | _v() { |
| 23 | [ -n "$VERBOSE" ] && [ "$VERBOSE" -ge 1 ] && echo "$*" >&2 |
| 24 | } |
| 25 | |
| 26 | v() { |
| 27 | _v "$(date) upgrade: $@" |
| 28 | } |
| 29 | |
| 30 | |
| 31 | #include /lib/upgrade |
| 32 | |
| 33 | |
| 34 | rootfs_type() { |
| 35 | /bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }' |
| 36 | } |
| 37 | |
| 38 | [ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; } |
| 39 | libs() { ldd $* 2>/dev/null | sed -r 's/(.* => )?(.*) .*/\2/'; } |
| 40 | |
| 41 | install_file() { # <file> [ <file> ... ] |
| 42 | local target dest dir |
| 43 | for file in "$@"; do |
| 44 | if [ -L "$file" ]; then |
| 45 | target="$(readlink -f "$file")" |
| 46 | dest="$RAM_ROOT/$file" |
| 47 | [ ! -f "$dest" ] && { |
| 48 | dir="$(dirname "$dest")" |
| 49 | mkdir -p "$dir" |
| 50 | ln -s "$target" "$dest" |
| 51 | } |
| 52 | file="$target" |
| 53 | fi |
| 54 | dest="$RAM_ROOT/$file" |
| 55 | [ -f "$file" -a ! -f "$dest" ] && { |
| 56 | dir="$(dirname "$dest")" |
| 57 | mkdir -p "$dir" |
| 58 | cp "$file" "$dest" |
| 59 | } |
| 60 | done |
| 61 | } |
| 62 | |
| 63 | install_bin() { |
| 64 | local src files |
| 65 | src=$1 |
| 66 | files=$1 |
| 67 | [ -x "$src" ] && files="$src $(libs $src)" |
| 68 | install_file $files |
| 69 | } |
| 70 | |
| 71 | supivot_orig() { # <new_root> <old_root> |
| 72 | /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1 |
| 73 | mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \ |
| 74 | /bin/mount -o noatime,move /proc $1/proc && \ |
| 75 | pivot_root $1 $1$2 || { |
| 76 | /bin/umount -l $1 $1 |
| 77 | return 1 |
| 78 | } |
| 79 | |
| 80 | /bin/mount -o noatime,move $2/sys /sys |
| 81 | /bin/mount -o noatime,move $2/dev /dev |
| 82 | /bin/mount -o noatime,move $2/tmp /tmp |
| 83 | /bin/mount -o noatime,move $2/overlay /overlay 2>&- |
| 84 | return 0 |
| 85 | } |
| 86 | |
| 87 | supivot() { # <new_root> <old_root> |
| 88 | v "in supivot $1 $2" |
| 89 | mount --make-rprivate / |
| 90 | mount --make-rprivate /tmp |
| 91 | /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1 |
| 92 | #mount --make-rprivate /proc |
| 93 | #mount --make-rprivate /tmp |
| 94 | #mount --make-rprivate $1 |
| 95 | #cd / |
| 96 | #mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay $1/home/root && \ |
| 97 | mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \ |
| 98 | /bin/mount --bind /proc $1/proc && \ |
| 99 | pivot_root $1 $1$2 || { |
| 100 | /bin/umount -l $1 $1 |
| 101 | v "pivot_root failed, supivot return 1" |
| 102 | return 1 |
| 103 | } |
| 104 | |
| 105 | for i in sys dev tmp overlay; do mount --move $2/$i /$i; done |
| 106 | v "supivot return 0" |
| 107 | return 0 |
| 108 | } |
| 109 | |
| 110 | switch_to_ramfs() { |
| 111 | for binary in \ |
| 112 | /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \ |
| 113 | pivot_root mount_root reboot sync kill sleep \ |
| 114 | md5sum hexdump cat zcat bzcat dd tar \ |
| 115 | ls basename find cp mv rm mkdir rmdir mknod touch chmod \ |
| 116 | '[' printf wc grep awk sed cut \ |
| 117 | mtd partx losetup mkfs.ext4 nandwrite flash_erase \ |
| 118 | ubiupdatevol ubiattach ubiblock ubiformat \ |
| 119 | ubidetach ubirsvol ubirmvol ubimkvol \ |
| 120 | snapshot snapshot_tool date ps ifconfig \ |
| 121 | $RAMFS_COPY_BIN |
| 122 | do |
| 123 | local file="$(command -v "$binary" 2>/dev/null)" |
| 124 | [ -n "$file" ] && install_bin "$file" |
| 125 | done |
| 126 | install_file /etc/resolv.conf /usr/bin/* /usr/sbin/* /lib/*.sh /lib/upgrade/sysupgrade /lib/upgrade/*.sh /lib/upgrade/do_stage2 /usr/share/libubox/jshn.sh $RAMFS_COPY_DATA |
| 127 | |
| 128 | [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64 |
| 129 | |
| 130 | supivot $RAM_ROOT /mnt || { |
| 131 | v "Failed to switch over to ramfs. Please reboot." |
| 132 | exit 1 |
| 133 | } |
| 134 | |
| 135 | /bin/mount -o remount,ro /mnt |
| 136 | /bin/umount -l /mnt |
| 137 | |
| 138 | grep /overlay /proc/mounts > /dev/null && { |
| 139 | /bin/mount -o noatime,remount,ro /overlay |
| 140 | /bin/umount -l /overlay |
| 141 | } |
| 142 | v "switch_ramfs end" |
| 143 | } |
| 144 | |
| 145 | |
| 146 | kill_remaining() { # [ <signal> [ <loop> ] ] |
| 147 | local loop_limit=10 |
| 148 | |
| 149 | local sig="${1:-TERM}" |
| 150 | local loop="${2:-0}" |
| 151 | local run=true |
| 152 | local stat |
| 153 | local proc_ppid=$(cut -d' ' -f4 /proc/$$/stat) |
| 154 | |
| 155 | vn "Sending $sig to remaining processes ..." |
| 156 | |
| 157 | while $run; do |
| 158 | run=false |
| 159 | for stat in /proc/[0-9]*/stat; do |
| 160 | [ -f "$stat" ] || continue |
| 161 | |
| 162 | local pid name state ppid rest |
| 163 | read pid name state ppid rest < $stat |
| 164 | name="${name#(}"; name="${name%)}" |
| 165 | |
| 166 | # Skip PID1, our parent, ourself and our children |
| 167 | [ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue |
| 168 | |
| 169 | local cmdline |
| 170 | read cmdline < /proc/$pid/cmdline |
| 171 | |
| 172 | # Skip kernel threads |
| 173 | [ -n "$cmdline" ] || continue |
| 174 | |
| 175 | _vn " $name" |
| 176 | kill -$sig $pid 2>/dev/null |
| 177 | |
| 178 | [ $loop -eq 1 ] && run=true |
| 179 | done |
| 180 | |
| 181 | let loop_limit-- |
| 182 | [ $loop_limit -eq 0 ] && { |
| 183 | _v |
| 184 | v "Failed to kill all processes." |
| 185 | exit 1 |
| 186 | } |
| 187 | done |
| 188 | _v |
| 189 | } |
| 190 | |
| 191 | echo 3 > /proc/sys/vm/drop_caches |
| 192 | |
| 193 | dual_boot=$(cat /sys/module/boot_param/parameters/dual_boot 2>/dev/null) |
| 194 | |
| 195 | if [ -n "$(rootfs_type)" ] && [ x"${dual_boot}" != xY ]; then |
| 196 | v "Switching to ramdisk..." |
| 197 | switch_to_ramfs |
| 198 | fi |
| 199 | |
| 200 | # Exec new shell from ramfs |
| 201 | exec /bin/busybox ash -c "$COMMAND" |