/branches/18.06.1/package/base-files/files/lib/upgrade/common.sh |
@@ -0,0 +1,255 @@ |
#!/bin/sh |
|
RAM_ROOT=/tmp/root |
|
[ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; } |
libs() { ldd $* 2>/dev/null | sed -r 's/(.* => )?(.*) .*/\2/'; } |
|
install_file() { # <file> [ <file> ... ] |
local target dest dir |
for file in "$@"; do |
if [ -L "$file" ]; then |
target="$(readlink -f "$file")" |
dest="$RAM_ROOT/$file" |
[ ! -f "$dest" ] && { |
dir="$(dirname "$dest")" |
mkdir -p "$dir" |
ln -s "$target" "$dest" |
} |
file="$target" |
fi |
dest="$RAM_ROOT/$file" |
[ -f "$file" -a ! -f "$dest" ] && { |
dir="$(dirname "$dest")" |
mkdir -p "$dir" |
cp "$file" "$dest" |
} |
done |
} |
|
install_bin() { |
local src files |
src=$1 |
files=$1 |
[ -x "$src" ] && files="$src $(libs $src)" |
install_file $files |
} |
|
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 "$@" |
} |
|
json_string() { |
local v="$1" |
v="${v//\\/\\\\}" |
v="${v//\"/\\\"}" |
echo "\"$v\"" |
} |
|
rootfs_type() { |
/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }' |
} |
|
get_image() { # <source> [ <command> ] |
local from="$1" |
local cmd="$2" |
|
if [ -z "$cmd" ]; then |
local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')" |
case "$magic" in |
1f8b) cmd="zcat";; |
425a) cmd="bzcat";; |
*) cmd="cat";; |
esac |
fi |
|
cat "$from" 2>/dev/null | $cmd |
} |
|
get_magic_word() { |
(get_image "$@" | dd bs=2 count=1 | hexdump -v -n 2 -e '1/1 "%02x"') 2>/dev/null |
} |
|
get_magic_long() { |
(get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null |
} |
|
export_bootdevice() { |
local cmdline uuid disk uevent line |
local MAJOR MINOR DEVNAME DEVTYPE |
|
if read cmdline < /proc/cmdline; then |
case "$cmdline" in |
*block2mtd=*) |
disk="${cmdline##*block2mtd=}" |
disk="${disk%%,*}" |
;; |
*root=*) |
disk="${cmdline##*root=}" |
disk="${disk%% *}" |
;; |
esac |
|
case "$disk" in |
PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-02) |
uuid="${disk#PARTUUID=}" |
uuid="${uuid%-02}" |
for disk in $(find /dev -type b); do |
set -- $(dd if=$disk bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "') |
if [ "$4$3$2$1" = "$uuid" ]; then |
uevent="/sys/class/block/${disk##*/}/uevent" |
break |
fi |
done |
;; |
/dev/*) |
uevent="/sys/class/block/${disk##*/}/uevent" |
;; |
esac |
|
if [ -e "$uevent" ]; then |
while read line; do |
export -n "$line" |
done < "$uevent" |
export BOOTDEV_MAJOR=$MAJOR |
export BOOTDEV_MINOR=$MINOR |
return 0 |
fi |
fi |
|
return 1 |
} |
|
export_partdevice() { |
local var="$1" offset="$2" |
local uevent line MAJOR MINOR DEVNAME DEVTYPE |
|
for uevent in /sys/class/block/*/uevent; do |
while read line; do |
export -n "$line" |
done < "$uevent" |
if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then |
export "$var=$DEVNAME" |
return 0 |
fi |
done |
|
return 1 |
} |
|
hex_le32_to_cpu() { |
[ "$(echo 01 | hexdump -v -n 2 -e '/2 "%x"')" = "3031" ] && { |
echo "${1:0:2}${1:8:2}${1:6:2}${1:4:2}${1:2:2}" |
return |
} |
echo "$@" |
} |
|
get_partitions() { # <device> <filename> |
local disk="$1" |
local filename="$2" |
|
if [ -b "$disk" -o -f "$disk" ]; then |
v "Reading partition table from $filename..." |
|
local magic=$(dd if="$disk" bs=2 count=1 skip=255 2>/dev/null) |
if [ "$magic" != $'\x55\xAA' ]; then |
v "Invalid partition table on $disk" |
exit |
fi |
|
rm -f "/tmp/partmap.$filename" |
|
local part |
for part in 1 2 3 4; do |
set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk") |
|
local type="$(( $(hex_le32_to_cpu $1) % 256))" |
local lba="$(( $(hex_le32_to_cpu $2) ))" |
local num="$(( $(hex_le32_to_cpu $3) ))" |
|
[ $type -gt 0 ] || continue |
|
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" |
done |
fi |
} |
|
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 |
} |
|
indicate_upgrade() { |
. /etc/diag.sh |
set_state upgrade |
} |
|
# Flash firmware to MTD partition |
# |
# $(1): path to image |
# $(2): (optional) pipe command to extract firmware, e.g. dd bs=n skip=m |
default_do_upgrade() { |
sync |
if [ "$SAVE_CONFIG" -eq 1 ]; then |
get_image "$1" "$2" | mtd $MTD_ARGS $MTD_CONFIG_ARGS -j "$CONF_TAR" write - "${PART_NAME:-image}" |
else |
get_image "$1" "$2" | mtd $MTD_ARGS write - "${PART_NAME:-image}" |
fi |
[ $? -ne 0 ] && exit 1 |
} |
|
do_upgrade_stage2() { |
v "Performing system upgrade..." |
if [ -n "$do_upgrade" ]; then |
eval "$do_upgrade" |
elif type 'platform_do_upgrade' >/dev/null 2>/dev/null; then |
platform_do_upgrade "$IMAGE" |
else |
default_do_upgrade "$IMAGE" |
fi |
|
if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then |
platform_copy_config |
fi |
|
v "Upgrade completed" |
sleep 1 |
|
v "Rebooting system..." |
umount -a |
reboot -f |
sleep 5 |
echo b 2>/dev/null >/proc/sysrq-trigger |
} |