mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
278 lines
7.7 KiB
Bash
Executable file
278 lines
7.7 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
###############################################################################
|
|
# Global variables. can be used directly in any function called.
|
|
cur_vol="" # num,[0/1] Number used for ubifs root filesystem volume name.
|
|
# eg: rootfs_0 or rootfs_1, currently used
|
|
upd_vol="" # num,[0/1] Number used for ubifs root filesystem volume name.
|
|
# eg: rootfs_0 or rootfs_1, the one we want to update
|
|
cmdline="" # command line settings.
|
|
cmdline_match="" # Headers to match to the image
|
|
|
|
###############################################################################
|
|
# file local variables. should not be used in imported functions. Can be used
|
|
# by functions declared in this script
|
|
chroot_cmdline="" # command line for the iop_chroot command.
|
|
board="" # string, Board name that is going to be matched
|
|
# against header of firmware image
|
|
upd_ubi_id="" # num, UBI volume number for the volume name
|
|
# "rootfs_$upd_vol", use to know what volume to run
|
|
# ubiupdatevol on.
|
|
run_cleanup=0 # if set the cleanup should be run otherwise we skip it.
|
|
run_mount_cleanup=0 # set if we should run umount in cleanup
|
|
upd_kernel=0 # set to 1 if system has the kernel in own mtd partition
|
|
log_stdout=1 # set to 0 to prevent the log to also print to stdout
|
|
upd_noreboot=0 # set to 1 if we should not reboot after programming
|
|
upd_forceimage=0 # set this to force upgrade even if image is for wrong board.
|
|
upd_forceboot=0 # set this to force upgrade of boot loader
|
|
###############################################################################
|
|
# import external functions
|
|
source /lib/upgrade/iopsys.sh
|
|
[ -f /lib/upgrade/iopupgrade ] && source /lib/upgrade/iopupgrade
|
|
|
|
# only call function if it exists
|
|
function_call() {
|
|
if type "$1" 2>/dev/null >/dev/null
|
|
then
|
|
$1 $@
|
|
fi
|
|
}
|
|
|
|
###############################################################################
|
|
# Cleanup and error handling functions.
|
|
function log {
|
|
TIME=$(date)
|
|
[ $log_stdout -eq 1 ] && echo "$@"
|
|
echo "[$TIME] $@" >>/tmp/upd_log
|
|
}
|
|
|
|
# we need to handle ctrl-c, segmentation fault, sigpipe and other abnormal
|
|
# terminations. no printing to stdout/stderr allowed in this function or
|
|
# anyhting it calls as stdout/stderr might no longer exist
|
|
function finish {
|
|
|
|
if [ "$run_cleanup" == "1" ]
|
|
then
|
|
|
|
function_call upd_cleanup
|
|
log ""
|
|
fi
|
|
|
|
if [ "$run_mount_cleanup" == "1" ]
|
|
then
|
|
log "Cleaning up after mount"
|
|
umount_newroot
|
|
fi
|
|
# always kill the timeout process, will leave the sleep but that is harmless
|
|
# as long as the kill will nerver be run.
|
|
kill $TIMEOUT_PID 2>/dev/null
|
|
|
|
lock -u /tmp/iopu.lock
|
|
}
|
|
|
|
function sig_pipe {
|
|
log_stdout=0 # stdin,stdout,stderr do not exist anymore
|
|
log "Got sigpipe. Turning of log printing to stdout"
|
|
}
|
|
|
|
# if a timout happens terminate
|
|
function timeout {
|
|
finish
|
|
exit 1
|
|
}
|
|
|
|
# Not much that can be done if the mount fails but to try again.
|
|
# if after 10 seconds there still is errors abort program.
|
|
# UBIFS has some wierd time intervall after ubiupdatevol where
|
|
# a mount of the newly written data results in a busy error.
|
|
function mount_retry {
|
|
local tries=0
|
|
|
|
while [ $tries -lt 10 ]
|
|
do
|
|
if mount $@ 2>/dev/null
|
|
then
|
|
return
|
|
fi
|
|
tries=$((tries + 1))
|
|
sleep 1
|
|
done
|
|
|
|
log "mount failed for command [mount $@] so upgrade failed."
|
|
|
|
exit 1
|
|
}
|
|
|
|
function mount_newroot {
|
|
run_mount_cleanup=1
|
|
mkdir -p /tmp/newroot
|
|
mkdir -p /tmp/newroot_overlay
|
|
|
|
mount_retry -t ubifs ubi0:rootfs_$upd_vol /tmp/newroot
|
|
|
|
mount_retry -o noatime,lowerdir=/tmp/newroot,upperdir=/tmp/newroot/overlay,workdir=/tmp/newroot/lib/overlay.tmp -t overlay "overlayfs:/tmp/newroot/overlay" /tmp/newroot_overlay
|
|
mount_retry --bind /tmp/newroot/ /tmp/newroot_overlay/rom
|
|
|
|
mount_retry --bind /dev /tmp/newroot_overlay/dev
|
|
mount_retry --bind /proc /tmp/newroot_overlay/proc
|
|
mount_retry --bind /sys /tmp/newroot_overlay/sys
|
|
mount_retry -t tmpfs -o noatime,mode=0755 root /tmp/newroot_overlay/tmp
|
|
|
|
mkdir -p /tmp/newroot_overlay/tmp/oldroot
|
|
mount_retry --bind / /tmp/newroot_overlay/tmp/oldroot
|
|
mount_retry --bind /tmp /tmp/newroot_overlay/tmp/oldroot/tmp
|
|
}
|
|
|
|
function umount_newroot {
|
|
umount /tmp/newroot_overlay/tmp/oldroot/tmp
|
|
umount /tmp/newroot_overlay/tmp/oldroot
|
|
umount /tmp/newroot_overlay/tmp
|
|
umount /tmp/newroot_overlay/sys
|
|
umount /tmp/newroot_overlay/proc
|
|
umount /tmp/newroot_overlay/dev
|
|
umount /tmp/newroot_overlay/rom
|
|
umount /tmp/newroot_overlay
|
|
umount /tmp/newroot
|
|
run_mount_cleanup=0
|
|
}
|
|
|
|
function usage {
|
|
echo "usage: $0 iopu [opts] "
|
|
echo ""
|
|
echo "opts:"
|
|
echo ""
|
|
echo " -n Do not do the final reboot of the target board"
|
|
echo " -c Keep configuration"
|
|
echo " -x Force install even if firmware is not for this board"
|
|
echo " -b Force install of bootloader regardless of version installed"
|
|
echo " -r Jump into chroot env of other system"
|
|
}
|
|
|
|
###############################################################################
|
|
|
|
# just one instance
|
|
# this check has to be done before we install handler to avoid removing the
|
|
# lock even if it was not available.
|
|
if ! lock -n /tmp/iopu.lock
|
|
then
|
|
echo "Another instance of iopu already running"
|
|
echo "If you are sure this is wrong remove file /tmp/iopu.lock"
|
|
exit 1
|
|
fi
|
|
|
|
trap finish EXIT
|
|
trap timeout SIGALRM
|
|
trap sig_pipe SIGPIPE
|
|
|
|
while getopts "nrxb" opt; do
|
|
case $opt in
|
|
n)
|
|
upd_noreboot=1
|
|
;;
|
|
x)
|
|
upd_forceimage=1
|
|
;;
|
|
b)
|
|
upd_forceboot=1
|
|
;;
|
|
r)
|
|
upd_vol=$(get_flashbank_next)
|
|
mount_newroot
|
|
(ENV=/sbin/iopu_chroot_env chroot /tmp/newroot_overlay /bin/sh)
|
|
echo ""
|
|
umount_newroot
|
|
exit 0
|
|
;;
|
|
h)
|
|
upd_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# put a timeout on this if it takes longer than 120 seconds we should abort
|
|
# and clean up
|
|
(
|
|
sleep 120 # if 2 minutes pass
|
|
kill -ALRM $$ 2>/dev/null # send it a SIGALRM signal
|
|
)&
|
|
TIMEOUT_PID=$!
|
|
|
|
log "Firmware upgrade started"
|
|
|
|
# Should board name be checked
|
|
if [ $upd_forceimage -eq 0 ]
|
|
then
|
|
board=$(db get hw.board.iopVerBoard)
|
|
cmdline_match="board=$board"
|
|
fi
|
|
|
|
# find out what rootfs volume is active.
|
|
cur_vol=$(get_flashbank_current)
|
|
upd_vol=$(get_flashbank_next)
|
|
|
|
# convert volume name "rootfs_$upd_vol" into ubifs volume id
|
|
upd_ubi_id=$(ubinfo -d 0 -N rootfs_$upd_vol | awk "/Volume ID:/ {print \$3}")
|
|
log "installing Root Fileystem into UBI volume rootfs_$upd_vol"
|
|
|
|
# prepare to match dsl.
|
|
function_call upd_conf_dsl
|
|
|
|
# prepare to update CFE if it exists
|
|
function_call upd_conf_cfe
|
|
|
|
# prepare to update kernel if it is stored in MTD/JFFS2
|
|
function_call upd_conf_kernel
|
|
|
|
log "now starting writing data to flash with [ iopupgrade $cmdline -M "$cmdline_match" -u ubi0_$upd_ubi_id ]"
|
|
run_cleanup=1 # When we start to actually write data there might be some
|
|
# things that need cleanup if we get an error/crash
|
|
iopupgrade $cmdline -M "$cmdline_match" -u ubi0_$upd_ubi_id
|
|
|
|
# in case of any error we abort
|
|
if [ $? -ne 0 ]; then
|
|
log "iopupgrade program Failed"
|
|
exit 1
|
|
fi
|
|
|
|
log "Firmware programmed to flash."
|
|
|
|
|
|
log "Transfering configuration to new system."
|
|
|
|
# Force upgrade of boot loader
|
|
[ $upd_forceboot -eq 1 ] && chroot_cmdline="$chroot_cmdline -b"
|
|
|
|
mount_newroot
|
|
chroot /tmp/newroot_overlay /sbin/iopu_chroot $chroot_cmdline
|
|
umount_newroot
|
|
|
|
log "Update fully installed."
|
|
run_cleanup=0
|
|
|
|
# Now make sure that we actually boot the new system on the next reboot
|
|
upd_finnish
|
|
|
|
# spawn the reboot to a subshell to allow the main program to quit before reset
|
|
# to avoid any hanged network connection like ssh
|
|
if [ $upd_noreboot -eq 0 ]
|
|
then
|
|
(
|
|
log_stdout=0 # stdin,stdout,stderr do not exist anymore, we are in a
|
|
# subshell and then the trap is no longer working.
|
|
sleep 1
|
|
log "Rebooting NOW!!!"
|
|
log ""
|
|
reboot
|
|
)&
|
|
log "Reboot initiated"
|
|
else
|
|
log "Skipping reboot"
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|