openwrt/package/base-files/files/lib/upgrade/common.sh
Mirko Vogt 4cca5cd4fd hot-fix nameclash in sysupgrade: rename pivot() to supivot() in sysupgrade
Sysupgrade defines its very own pivot() function.
Prior merging boot.sh and functions.sh sysupgrade just included boot.sh,
now it includes functions.sh which defines pivot() as well, however
slightly different which causes sysupgrade to fail.

This is a hot-fix to unbreak sysupgrade, however those two pivot()
functions should actually get merged.

SVN-Revision: 34815
2012-12-21 12:10:21 +00:00

231 lines
4.9 KiB
Bash

#!/bin/sh
RAM_ROOT=/tmp/root
ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; }
libs() { ldd $* | awk '{print $3}'; }
install_file() { # <file> [ <file> ... ]
for file in "$@"; do
dest="$RAM_ROOT/$file"
[ -f $file -a ! -f $dest ] && {
dir="$(dirname $dest)"
mkdir -p "$dir"
cp $file $dest
}
done
}
install_bin() { # <file> [ <symlink> ... ]
src=$1
files=$1
[ -x "$src" ] && files="$src $(libs $src)"
install_file $files
[ -e /lib/ld-linux.so.3 ] && {
install_file /lib/ld-linux.so.3
}
shift
for link in "$@"; do {
dest="$RAM_ROOT/$link"
dir="$(dirname $dest)"
mkdir -p "$dir"
[ -f "$dest" ] || ln -s $src $dest
}; done
}
supivot() { # <new_root> <old_root>
mount | grep "on $1 type" 2>&- 1>&- || mount -o bind $1 $1
mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
mount -o noatime,move /proc $1/proc && \
pivot_root $1 $1$2 || {
umount $1 $1
return 1
}
mount -o noatime,move $2/sys /sys
mount -o noatime,move $2/dev /dev
mount -o noatime,move $2/tmp /tmp
mount -o noatime,move $2/overlay /overlay 2>&-
return 0
}
run_ramfs() { # <command> [...]
install_bin /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \
/sbin/pivot_root /usr/bin/wget /sbin/reboot /bin/sync /bin/dd \
/bin/grep /bin/cp /bin/mv /bin/tar /usr/bin/md5sum "/usr/bin/[" \
/bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump \
/bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc
install_bin /sbin/mtd
for file in $RAMFS_COPY_BIN; do
install_bin $file
done
install_file /etc/resolv.conf /lib/functions.sh /lib/functions.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA
supivot $RAM_ROOT /mnt || {
echo "Failed to switch over to ramfs. Please reboot."
exit 1
}
mount -o remount,ro /mnt
umount -l /mnt
grep /overlay /proc/mounts > /dev/null && {
mount -o noatime,remount,ro /overlay
umount -l /overlay
}
# spawn a new shell from ramdisk to reduce the probability of cache issues
exec /bin/busybox ash -c "$*"
}
kill_remaining() { # [ <signal> ]
local sig="${1:-TERM}"
echo -n "Sending $sig to remaining processes ... "
local stat
for stat in /proc/[0-9]*/stat; do
[ -f "$stat" ] || continue
local pid name state ppid rest
read pid name state ppid rest < $stat
name="${name#(}"; name="${name%)}"
local cmdline
read cmdline < /proc/$pid/cmdline
# Skip kernel threads
[ -n "$cmdline" ] || continue
case "$name" in
# Skip essential services
*ash*|*init*|*watchdog*|*ssh*|*dropbear*|*telnet*|*login*|*hostapd*|*wpa_supplicant*) : ;;
# Killable process
*)
if [ $pid -ne $$ ] && [ $ppid -ne $$ ]; then
echo -n "$name "
kill -$sig $pid 2>/dev/null
fi
;;
esac
done
echo ""
}
run_hooks() {
local arg="$1"; shift
for func in "$@"; do
eval "$func $arg"
done
}
ask_bool() {
local default="$1"; shift;
local answer="$default"
[ "$INTERACTIVE" -eq 1 ] && {
case "$default" in
0) echo -n "$* (y/N): ";;
*) echo -n "$* (Y/n): ";;
esac
read answer
case "$answer" in
y*) answer=1;;
n*) answer=0;;
*) answer="$default";;
esac
}
[ "$answer" -gt 0 ]
}
v() {
[ "$VERBOSE" -ge 1 ] && echo "$@"
}
rootfs_type() {
mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }'
}
get_image() { # <source> [ <command> ]
local from="$1"
local conc="$2"
local cmd
case "$from" in
http://*|ftp://*) cmd="wget -O- -q";;
*) cmd="cat";;
esac
if [ -z "$conc" ]; then
local magic="$(eval $cmd $from | dd bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
case "$magic" in
1f8b) conc="zcat";;
425a) conc="bzcat";;
esac
fi
eval "$cmd $from ${conc:+| $conc}"
}
get_magic_word() {
get_image "$@" | dd bs=2 count=1 2>/dev/null | hexdump -v -n 2 -e '1/1 "%02x"'
}
get_magic_long() {
get_image "$@" | dd bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
}
refresh_mtd_partitions() {
mtd refresh rootfs
}
jffs2_copy_config() {
if grep rootfs_data /proc/mtd >/dev/null; then
# squashfs+jffs2
mtd -e rootfs_data jffs2write "$CONF_TAR" rootfs_data
else
# jffs2
mtd jffs2write "$CONF_TAR" rootfs
fi
}
default_do_upgrade() {
sync
if [ "$SAVE_CONFIG" -eq 1 -a -z "$USE_REFRESH" ]; then
get_image "$1" | mtd -j "$CONF_TAR" write - "${PART_NAME:-image}"
else
get_image "$1" | mtd write - "${PART_NAME:-image}"
fi
}
do_upgrade() {
v "Performing system upgrade..."
if type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
platform_do_upgrade "$ARGV"
else
default_do_upgrade "$ARGV"
fi
[ "$SAVE_CONFIG" -eq 1 -a -n "$USE_REFRESH" ] && {
v "Refreshing partitions"
if type 'platform_refresh_partitions' >/dev/null 2>/dev/null; then
platform_refresh_partitions
else
refresh_mtd_partitions
fi
if type 'platform_copy_config' >/dev/null 2>/dev/null; then
platform_copy_config
else
jffs2_copy_config
fi
}
v "Upgrade completed"
[ -n "$DELAY" ] && sleep "$DELAY"
ask_bool 1 "Reboot" && {
v "Rebooting system..."
reboot -f
sleep 5
echo b 2>/dev/null >/proc/sysrq-trigger
}
}