23d356a447fa3b94c386e26792ecd3913a9bb6c0
[openwrt/openwrt.git] / package / base-files / files / lib / upgrade / stage2
1 #!/bin/sh
2
3 . /lib/functions.sh
4 . /lib/functions/system.sh
5
6 export IMAGE="$1"
7 COMMAND="$2"
8
9 export INTERACTIVE=0
10 export VERBOSE=1
11 export CONFFILES=/tmp/sysupgrade.conffiles
12
13 RAMFS_COPY_BIN= # extra programs for temporary ramfs root
14 RAMFS_COPY_DATA= # extra data files
15
16 include /lib/upgrade
17
18
19 supivot() { # <new_root> <old_root>
20 /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1
21 mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
22 /bin/mount -o noatime,move /proc $1/proc && \
23 pivot_root $1 $1$2 || {
24 /bin/umount -l $1 $1
25 return 1
26 }
27
28 /bin/mount -o noatime,move $2/sys /sys
29 /bin/mount -o noatime,move $2/dev /dev
30 /bin/mount -o noatime,move $2/tmp /tmp
31 /bin/mount -o noatime,move $2/overlay /overlay 2>&-
32 return 0
33 }
34
35 switch_to_ramfs() {
36 for binary in \
37 /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \
38 pivot_root mount_root reboot sync kill sleep \
39 md5sum hexdump cat zcat bzcat dd tar \
40 ls basename find cp mv rm mkdir rmdir mknod touch chmod \
41 '[' printf wc grep awk sed cut \
42 mtd partx losetup mkfs.ext4 nandwrite flash_erase \
43 ubiupdatevol ubiattach ubiblock ubiformat \
44 ubidetach ubirsvol ubirmvol ubimkvol \
45 snapshot snapshot_tool date \
46 $RAMFS_COPY_BIN
47 do
48 local file="$(command -v "$binary" 2>/dev/null)"
49 [ -n "$file" ] && install_bin "$file"
50 done
51 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
52
53 [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
54
55 supivot $RAM_ROOT /mnt || {
56 v "Failed to switch over to ramfs. Please reboot."
57 exit 1
58 }
59
60 /bin/mount -o remount,ro /mnt
61 /bin/umount -l /mnt
62
63 grep /overlay /proc/mounts > /dev/null && {
64 /bin/mount -o noatime,remount,ro /overlay
65 /bin/umount -l /overlay
66 }
67 }
68
69 kill_remaining() { # [ <signal> [ <loop> ] ]
70 local loop_limit=10
71
72 local sig="${1:-TERM}"
73 local loop="${2:-0}"
74 local run=true
75 local stat
76 local proc_ppid=$(cut -d' ' -f4 /proc/$$/stat)
77
78 vn "Sending $sig to remaining processes ..."
79
80 while $run; do
81 run=false
82 for stat in /proc/[0-9]*/stat; do
83 [ -f "$stat" ] || continue
84
85 local pid name state ppid rest
86 read pid name state ppid rest < $stat
87 name="${name#(}"; name="${name%)}"
88
89 # Skip PID1, our parent, ourself and our children
90 [ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue
91
92 local cmdline
93 read cmdline < /proc/$pid/cmdline
94
95 # Skip kernel threads
96 [ -n "$cmdline" ] || continue
97
98 _vn " $name"
99 kill -$sig $pid 2>/dev/null
100
101 [ $loop -eq 1 ] && run=true
102 done
103
104 let loop_limit--
105 [ $loop_limit -eq 0 ] && {
106 _v
107 v "Failed to kill all processes."
108 exit 1
109 }
110 done
111 _v
112 }
113
114 indicate_upgrade
115
116 killall -9 telnetd
117 killall -9 dropbear
118 killall -9 ash
119
120 kill_remaining TERM
121 sleep 3
122 kill_remaining KILL 1
123
124 sleep 1
125
126 echo 3 > /proc/sys/vm/drop_caches
127
128 if [ -n "$IMAGE" ] && type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
129 platform_pre_upgrade "$IMAGE"
130 fi
131
132 if [ -n "$(rootfs_type)" ]; then
133 v "Switching to ramdisk..."
134 switch_to_ramfs
135 fi
136
137 # Exec new shell from ramfs
138 exec /bin/busybox ash -c "$COMMAND"