#
# Copyright (c) 2015-2016 by Cisco Systems, Inc.
# All rights reserved.
#
# raw mount commands for accessing XR and Calvados File-systems from hostos
# useful when we need to examine a router after XR or Calvados fails to start

LOGVOL="latest"
verbose="1"
read_only=""


function usage
{
    echo Available commands are:
    echo bash /etc/init.d/raw_mount admin_var_log [LOGVOL]
    echo bash /etc/init.d/raw_mount admin_misc_config [LOGVOL]
    echo bash /etc/init.d/raw_mount admin_misc_scratch [LOGVOL]
    echo bash /etc/init.d/raw_mount admin_rootfs [LOGVOL]
    echo bash /etc/init.d/raw_mount admin_misc_disk1


    echo bash /etc/init.d/raw_mount xr_rootfs [LOGVOL]
    echo bash /etc/init.d/raw_mount xr_var_log [LOGVOL]
    echo bash /etc/init.d/raw_mount xr_misc_config [LOGVOL]
    echo bash /etc/init.d/raw_mount xr_misc_scratch [LOGVOL]
    echo bash /etc/init.d/raw_mount xr_misc_disk1
    echo LOGVOL is optional, defaults to highest lv
}
readonly -f usage

function find_fs_offset {
    local start=$(fdisk -u -l ${1} | grep "${1}${2}" | awk '{print $2}')
    if [ "${start}" == "*" ]; then
        start=$(fdisk -u -l ${1} | grep "${1}${2}" | awk '{print $3}')
    fi
    local offset=$(expr ${start} \* 512)
    echo ${offset}
}
readonly -f find_fs_offset

function find_fs_sizelimit {
    local result
    local sizelimit
    local start=$(fdisk -u -l ${1} | grep "${1}${2}" | awk '{print $2}')
    local endlimit=$(fdisk -u -l ${1} | grep "${1}${2}" | awk '{print $3}')

    if [ "${start}" == "*" ]; then
        start=$(fdisk -u -l ${1} | grep "${1}${2}" | awk '{print $3}')
        endlimit=$(fdisk -u -l ${1} | grep "${1}${2}" | awk '{print $4}')
    fi
    result=$((${endlimit} - ${start}))
    sizelimit=$(expr ${result} \* 512)
    echo ${sizelimit}
}
readonly -f find_fs_sizelimit

function latest_lv {
    local vg=$1
    local lv=$2
    local latest=$( ls /dev/mapper | grep ${vg}-${lv}_lv | tail -1 | sed -e "s;^.*_lv;lv;" )
    if [[ -z $latest ]]; then
        latest="lv0"
    fi
    echo $latest
}
readonly -f latest_lv

function do_raw_mount
{
    local vg=$1
    local lv=$2
    local part=$3
    local mnt
    local vol=$5

    if [[ $vol == "latest" ]]; then
        vol=$( latest_lv ${vg} ${lv} )
    fi

    local lvname="/dev/mapper/${vg}-${lv}_$vol"
    local mnt=$4_$vol
        
    if [[ -z ${lvname} || -z ${part} || -z ${mnt} ]]; then
        echo usage: do_raw_mount vg lv partition mntpt logvol
        echo example: do_raw_mount panini_vol_grp calvados p1 /admin_rootfs latest
        exit 1
    fi

    lvchange -ay ${lvname}
    sleep 1
    if [[ ! -b ${lvname} ]]; then
        echo Volume ${lvname} not present
        exit 1
    fi

    partcal_offset=$(find_fs_offset ${lvname} ${part})
    patcalo_szlmt=$(find_fs_sizelimit ${lvname} ${part})
    umount ${mnt} > /dev/null 2>&1
    mkdir -p ${mnt}
    if [[ $verbose == "1" ]]; then
        echo Mounting ${lvname} ${part} as ${mnt}
    fi
    mount ${read_only} -o discard  ${lvname} ${mnt} -o offset=${partcal_offset},sizelimit=${patcalo_szlmt}
    if [ $? -ne 0 ]; then
        echo Mount failed
        exit 1
    fi
    exit 0
    
}
readonly -f do_raw_mount

if [[ "$1" == "quiet" ]]; then
    verbose="0"
    shift
fi

if [[ "$1" == "ro" ]]; then
    read_only="-r"
    shift
fi

if [[ "$1" == "rw" ]]; then
    read_only=""
    shift
fi

if [[ $# > 1 ]]; then
    LOGVOL=$2
fi

case "$1" in
    admin_rootfs)
        do_raw_mount panini_vol_grp calvados p1 /admin_rootfs ${LOGVOL}
        ;;
        
    admin_var_log )
        do_raw_mount panini_vol_grp calvados_data p1 /admin_var_log ${LOGVOL}
        ;;
        
    admin_misc_config)
        do_raw_mount panini_vol_grp calvados_data p2 /admin_misc_config ${LOGVOL}
        ;;
        
    admin_misc_scratch)
        do_raw_mount panini_vol_grp calvados_data p3 /admin_misc_scratch ${LOGVOL}
        ;;
        
    admin_misc_disk1)
        if [ ! -b /dev/mapper/pci_disk1-ssd_disk1_calvados_1 ]; then
            echo No /misc/disk1 on a LC
            exit 1
        else
            mkdir -p /admin_misc_disk1
            mount ${read_only} -o loop /dev/mapper/pci_disk1-ssd_disk1_calvados_1 /admin_misc_disk1
        fi
        ;;

    xr_rootfs)
        do_raw_mount panini_vol_grp xr p1 /xr_rootfs ${LOGVOL}
        ;;
        
    xr_var_log)
        if [  ! -b /dev/sdb ]; then
            do_raw_mount panini_vol_grp xr_data p1 /xr_var_log ${LOGVOL}
        else
            do_raw_mount pci_disk1 xr_data p1 /xr_var_log ${LOGVOL}
        fi
        ;;
        
    xr_misc_config)
        if [ ! -b /dev/sdb ]; then
            do_raw_mount panini_vol_grp xr_data p2 /xr_misc_config ${LOGVOL}
        else
            do_raw_mount pci_disk1 xr_data p2 /xr_misc_config ${LOGVOL}
        fi
        ;;
        
    xr_misc_scratch)
        if [ ! -b /dev/sdb ]; then
            do_raw_mount panini_vol_grp xr_data p3 /xr_misc_scratch ${LOGVOL}
        else
            do_raw_mount pci_disk1 xr_data p3 /xr_misc_scratch ${LOGVOL}
        fi
        ;;
        
    xr_misc_disk1)
        if [  ! -b /dev/mapper/pci_disk1-ssd_disk1_xr_1 ]; then
            echo No /misc/disk1 on a LC
            exit 1
        else
            mkdir -p /xr_misc_disk1
            mount ${read_only} -o loop /dev/mapper/pci_disk1-ssd_disk1_xr_1 /xr_misc_disk1
        fi
        ;;
        
    *)
        echo No support to mount $1
        usage
        exit 1
        ;;  
esac
