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