blob: ff93ffa30c0502e1050ce57daac653950efb8848 [file] [log] [blame]
developer707745c2022-07-20 14:30:33 +08001#!/bin/sh
2
3
4COMMAND=/lib/upgrade/do_stage2
5
6
developer4f4b9842023-02-13 17:54:38 +08007RAMFS_COPY_BIN='mkfs.f2fs blkid blockdev dmsetup fw_printenv fw_setenv'
developer707745c2022-07-20 14:30:33 +08008RAMFS_COPY_DATA="/etc/fw_env.config /var/lock/fw_printenv.lock"
9RAM_ROOT=/tmp/root
10
11export IMAGE=$1
12export VERBOSE=1
13
14_vn() {
15 [ -n "$VERBOSE" ] && [ "$VERBOSE" -ge 1 ] && echo -n "$*" >&2
16}
17
18vn() {
19 _vn "$(date) upgrade: $@"
20}
21
22_v() {
23 [ -n "$VERBOSE" ] && [ "$VERBOSE" -ge 1 ] && echo "$*" >&2
24}
25
26v() {
27 _v "$(date) upgrade: $@"
28}
29
30
31#include /lib/upgrade
32
33
34rootfs_type() {
35 /bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }'
36}
37
38[ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; }
39libs() { ldd $* 2>/dev/null | sed -r 's/(.* => )?(.*) .*/\2/'; }
40
41install_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
63install_bin() {
64 local src files
65 src=$1
66 files=$1
67 [ -x "$src" ] && files="$src $(libs $src)"
68 install_file $files
69}
70
71supivot_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
87supivot() { # <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
110switch_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
146kill_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
191echo 3 > /proc/sys/vm/drop_caches
192
193dual_boot=$(cat /sys/module/boot_param/parameters/dual_boot 2>/dev/null)
194
195if [ -n "$(rootfs_type)" ] && [ x"${dual_boot}" != xY ]; then
196 v "Switching to ramdisk..."
197 switch_to_ramfs
198fi
199
200# Exec new shell from ramfs
201exec /bin/busybox ash -c "$COMMAND"