base-files: stage2: add 'tail' to sysupgrade environment
[openwrt/staging/nbd.git] / package / base-files / files / lib / upgrade / stage2
index c7629c383f3cbd9b8a44fe85c22f15db46dc50e1..f4db88d31ea18f0016ae08828f9b7d6a204db43d 100755 (executable)
@@ -33,22 +33,32 @@ supivot() { # <new_root> <old_root>
 }
 
 switch_to_ramfs() {
+       RAMFS_COPY_LOSETUP="$(command -v /usr/sbin/losetup)"
+       RAMFS_COPY_LVM="$(command -v lvm)"
+
        for binary in \
                /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount    \
                pivot_root mount_root reboot sync kill sleep            \
-               md5sum hexdump cat zcat bzcat dd tar                    \
+               md5sum hexdump cat zcat dd tar gzip                     \
                ls basename find cp mv rm mkdir rmdir mknod touch chmod \
-               '[' printf wc grep awk sed cut                          \
+               '[' printf wc grep awk sed cut sort tail                \
                mtd partx losetup mkfs.ext4 nandwrite flash_erase       \
                ubiupdatevol ubiattach ubiblock ubiformat               \
                ubidetach ubirsvol ubirmvol ubimkvol                    \
-               snapshot snapshot_tool date                             \
+               snapshot snapshot_tool date logger                      \
+               /usr/sbin/fw_printenv /usr/bin/fwtool                   \
+               $RAMFS_COPY_LOSETUP $RAMFS_COPY_LVM                     \
                $RAMFS_COPY_BIN
        do
                local file="$(command -v "$binary" 2>/dev/null)"
                [ -n "$file" ] && install_bin "$file"
        done
-       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
+       install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh     \
+               /lib/upgrade/*.sh /lib/upgrade/do_stage2                \
+               /usr/share/libubox/jshn.sh /usr/sbin/fw_setenv          \
+               /etc/fw_env.config $RAMFS_COPY_DATA
+
+       mkdir -p $RAM_ROOT/var/lock
 
        [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
 
@@ -60,6 +70,16 @@ switch_to_ramfs() {
        /bin/mount -o remount,ro /mnt
        /bin/umount -l /mnt
 
+       grep -e "^/dev/dm-.*" -e "^/dev/loop.*" /proc/mounts | while read bdev mp _r; do
+               umount $mp
+       done
+
+       [ "$RAMFS_COPY_LOSETUP" ] && losetup -D
+       [ "$RAMFS_COPY_LVM" ] && {
+               mkdir -p /tmp/lvm/cache
+               $RAMFS_COPY_LVM vgchange -aln --ignorelockingfailure
+       }
+
        grep /overlay /proc/mounts > /dev/null && {
                /bin/mount -o noatime,remount,ro /overlay
                /bin/umount -l /overlay
@@ -75,7 +95,7 @@ kill_remaining() { # [ <signal> [ <loop> ] ]
        local stat
        local proc_ppid=$(cut -d' ' -f4  /proc/$$/stat)
 
-       vn "Sending $sig to remaining processes ..."
+       v "Sending $sig to remaining processes ..."
 
        while $run; do
                run=false
@@ -83,19 +103,22 @@ kill_remaining() { # [ <signal> [ <loop> ] ]
                        [ -f "$stat" ] || continue
 
                        local pid name state ppid rest
-                       read pid name state ppid rest < $stat
-                       name="${name#(}"; name="${name%)}"
+                       read pid rest < $stat
+                       name="${rest#\(}" ; rest="${name##*\) }" ; name="${name%\)*}"
+                       set -- $rest ; state="$1" ; ppid="$2"
 
                        # Skip PID1, our parent, ourself and our children
                        [ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue
 
+                       [ -f "/proc/$pid/cmdline" ] || continue
+
                        local cmdline
                        read cmdline < /proc/$pid/cmdline
 
                        # Skip kernel threads
                        [ -n "$cmdline" ] || continue
 
-                       _vn " $name"
+                       v "Sending signal $sig to $name ($pid)"
                        kill -$sig $pid 2>/dev/null
 
                        [ $loop -eq 1 ] && run=true
@@ -103,26 +126,41 @@ kill_remaining() { # [ <signal> [ <loop> ] ]
 
                let loop_limit--
                [ $loop_limit -eq 0 ] && {
-                       _v
                        v "Failed to kill all processes."
                        exit 1
                }
        done
-       _v
 }
 
 indicate_upgrade
 
-killall -9 telnetd
-killall -9 dropbear
-killall -9 ash
+while read -r a b c; do
+       case "$a" in
+               MemT*) mem="$b" ;; esac
+done < /proc/meminfo
+
+[ "$mem" -gt 32768 ] && \
+       skip_services="dnsmasq log network"
+for service in /etc/init.d/*; do
+       service=${service##*/}
+
+       case " $skip_services " in
+               *" $service "*) continue ;; esac
+
+       ubus call service delete '{ "name": "'"$service"'" }' 2>/dev/null
+done
+
+killall -9 telnetd 2>/dev/null
+killall -9 dropbear 2>/dev/null
+killall -9 ash 2>/dev/null
 
 kill_remaining TERM
-sleep 3
+sleep 4
 kill_remaining KILL 1
 
-sleep 1
+sleep 6
 
+echo 3 > /proc/sys/vm/drop_caches
 
 if [ -n "$IMAGE" ] && type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
        platform_pre_upgrade "$IMAGE"