#!/bin/sh

# This script is called by ota.sh after the update is installed.
# Returning non-zero requires reflashing the device.


ROOT=/rootfs
PROGRESS_FILE=$ROOT/var/log/progress
MIGRATION_SCRIPT=/usr/bin/datamigration_ota
SAVE_DIR=$ROOT/media/internal/.save_for_software_update
SAVE_VAR_FILE=$SAVE_DIR/saved-var.tar.gz
BOOT_DEVICE=

# error value is mapped to miniboot_ota's PROGRESS.  For datamigration error,
# return -4.  Otherwise, if there is an error, return -3.
PROGRESS=-3


cleanup()
{
    echo "$0: $1"

    # use -n to preserve backup user data in media
    dosfsck -n /dev/mapper/store-media

    mount -o rw /dev/mapper/store-var $ROOT/var > /dev/null  2>&1
    mount -o rw /dev/mapper/store-log $ROOT/var/log > /dev/null  2>&1
    echo $PROGRESS > $PROGRESS_FILE

    exit 1
}

bind_mounts()
{
    mount -o bind /dev $ROOT/dev
    mount -o bind /proc $ROOT/proc
    mount -o bind /sys $ROOT/sys
    mount -o bind /tmp $ROOT/tmp
}

check_result()
{
    # e2fsck returns 0 on no error, 1 if error is fixed,
    # 2 (bit-wise) if error is fixed but device must reboot    
    if [ $1 -ne 0 ] && [ $1 -ne 1 ]
    then
        if [ $1 -eq 2 ] || [ $1 -eq 3 ]
        then
            # reboot and try again
            echo "recoverable fsck error"
            exit 1
        else
            if [ $2 = var ]
            then
                if ! mke2fs.e2fsprogs -j /dev/store/var
                then
                    cleanup "mkfs error for var"
                fi
                # After wiping var, restore var from the tar file created
                # in pre-update.  Exclude the now obsolete ActiveRecord files
                # in dbdata
                tar -xvzf $SAVE_VAR_FILE --exclude=$ROOT/var/luna/data/dbdata
            elif [ $2 = log ]
            then
                if ! mke2fs.e2fsprogs -j /dev/store/log
                then
                    cleanup "mkfs error for log"
                fi
            elif [ $2 = update ]
            then
                if ! mke2fs.e2fsprogs -j /dev/store/update
                then
                    cleanup "mkfs error for update"
                fi
            else
                cleanup "fsck error for $2"
            fi
        fi
    fi
}


##################################################################

BOOT_DEVICE=$1
START_STEPS=$2
PARTITION_STEPS=$3

echo "BOOT_DEVICE = $1, step offset = $2"; sync

/usr/bin/killall fbprogress
/usr/bin/fbprogress -p /tmp/progress -f finishing -s $START_STEPS &

echo "removing files"; sync
# remove files, including the update packages, that would prevent shrinking
# the size of /var, /var/lib/update, or /var/log
rm -f $ROOT/var/lib/software/tmp/*
rm -fR $ROOT/var/luna/data/dbdata/*
rm -fR $ROOT/var/lib/update/*
# in case a misbehaving component swamped RDX
rm -f $ROOT/var/log/reports/javaoom/*
rm -f $ROOT/var/log/reports/kernelpanics/*
rm -f $ROOT/var/log/reports/minicores/*
rm -f $ROOT/var/tmp

umount $ROOT/media/internal
umount $ROOT/var/lib/update
umount $ROOT/var/log
umount $ROOT/var

# fsck root and boot partitions before proceeding
sync
if ! umount $ROOT/boot
then
    echo "unmounting boot failed"
    ls -l /proc/*/fd | grep $ROOT/boot
fi

umount $ROOT/dev
umount $ROOT/proc
umount $ROOT/sys
umount $ROOT/tmp
umount $ROOT

echo "run fsck on $BOOT_DEVICE"
e2fsck.e2fsprogs -f -p -v $BOOT_DEVICE
check_result $? boot

echo "run fsck on root"
e2fsck.e2fsprogs -f -p -v /dev/mapper/store-root
check_result $? root

mount -o ro /dev/mapper/store-root $ROOT
mount -o ro $BOOT_DEVICE $ROOT/boot
bind_mounts
echo "$ROOT remounted"

# repartition if appropriate
if [ ! -e /dev/store/filecache ]
then
    echo "check var"
    e2fsck.e2fsprogs -f -p -v /dev/mapper/store-var
    check_result $? var
    
    echo "resize var"
    if ! resize2fs /dev/store/var 64M || ! lvresize -f -L 64M /dev/store/var
    then
        cleanup "error resizing var partition"
    fi

    echo "check log"
    e2fsck.e2fsprogs -f -p -v /dev/mapper/store-log
    check_result $? log

    echo "resize log"
    if ! resize2fs /dev/store/log 24M || ! lvresize -f -L 24M /dev/store/log
    then
        cleanup "error resizing log partition"
    fi

    echo "check update"
    e2fsck.e2fsprogs -f -p -v /dev/mapper/store-update
    check_result $? update

    echo "resize update"
    if ! resize2fs /dev/store/update 16M || \
        ! lvresize -f -L 16M /dev/store/update
    then
        cleanup "error resizing update partition"
    fi

    # resize swap before creating new partitions
    echo "resize swap"
    # pixie needs more swap space than other devices.
    # Name of pixie kernel is uImage-...-chuck
    pixie=0
    ls $ROOT/boot/*chuck
    if [ $? -eq 0 ]
    then
        pixie=1
    fi
    if [ $pixie -eq 0 ]
    then
        if ! lvresize -f -L 104M /dev/store/swap 
        then
            cleanup "error resizing swap"
        fi
    else
        if ! lvresize -f -L 168M /dev/store/swap 
        then
            cleanup "error resizing swap"
        fi
    fi
    if ! mkswap.util-linux-ng /dev/store/swap
    then
        cleanup "mkswap error"
    fi
    
    echo "create filecache"
    if ! lvcreate -L 136M -n filecache store || \
        ! mke2fs.e2fsprogs -I 256 -j /dev/store/filecache
    then
        lvs
        vgs
        cleanup "error creating filecache partition"
    fi

    echo "check filecache"
    e2fsck.e2fsprogs -f -p -v /dev/mapper/store-filecache
    check_result $? filecache

    echo "create mojodb"
    if ! lvcreate -L 144M -n mojodb store || \
        ! mke2fs.e2fsprogs -j /dev/store/mojodb
    then
        lvs
        vgs
        cleanup "error creating mojodb partition"
    fi

    echo "check mojodb"
    e2fsck.e2fsprogs -f -p -v /dev/mapper/store-mojodb
    check_result $? mojodb
fi

if ! mount -o rw /dev/mapper/store-var $ROOT/var
then
    cleanup "var mount failed"
fi
ln -s /tmp $ROOT/var/tmp

if ! mount -o rw /dev/mapper/store-log $ROOT/var/log
then
    cleanup "log mount failed"
fi

if ! mount -o rw /dev/mapper/store-media $ROOT/media/internal
then
    cleanup "media mount failed"
fi

mkdir -p $ROOT/var/file-cache
if ! mount -o rw,user_xattr /dev/store/filecache $ROOT/var/file-cache
then
    cleanup "filecache mount failed"
fi

mkdir -p $ROOT/var/db
if ! mount -o rw /dev/store/mojodb $ROOT/var/db
then
    cleanup "mojodb mount failed"
fi

if [ -x $ROOT$MIGRATION_SCRIPT ]
then
    echo "call datamigration_ota"
    
    STEPS=`expr $START_STEPS + $PARTITION_STEPS`
    echo "migration progress begins at $STEPS"
    /usr/bin/killall fbprogress
    /usr/bin/fbprogress -p /tmp/progress -f restoring -s $STEPS &
    
    chroot $ROOT $MIGRATION_SCRIPT
    if [ $? -ne 0 ]
    then
        # return -4 when there is a datamigration error
        PROGRESS=-4
        cleanup "datamigration_ota error"
    fi
else
    PROGRESS=-4
    cleanup "datamigration_ota script not found"
fi

echo "post-update completed"

exit 0
