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