#!/bin/bash
# Copyright (c) 2019 Huawei Technologies Co., Ltd. All rights reserved.

EXAGEAR_ROOT_DIR="$(dirname "$(realpath "${BASH_SOURCE}")")"/..
EXAGEAR_ROOT_DIR="$(realpath "${EXAGEAR_ROOT_DIR}")"

function print_usage_and_exit()
{
        echo "Usage: ${0} <cmd> [<args-specific-to-command>]"
        exit 1
}

function binfmt_misc_enable()
{
    if [ ! -d "${BINFMT_PREFIX}" ]
    then
        echo "binfmt_misc is not available on this host"
        exit 1
    fi

    if [ -e "${BINFMT_CONTROL}" ] 
    then
	    if [ "${NO_DISABLE_BINFMT_MISC}" == "y" ]
	    then
		    # If NO_DISABLE_BINFMT_MISC, we must not disable binfmt_misc even on a little time, because there may be race condition with exagear running in other containers.
		    exit 0
	    else
		    echo '-1' > "${BINFMT_CONTROL}"	
	    fi
    fi

    echo ":${BINFMT_NAME}:M::${EXAGEAR_GUEST_ELF_MAGIC}:${EXAGEAR_GUEST_ELF_MASK}:${BINFMT_INTERPRETER}:${BINFMT_OPTIONS}" > ${BINFMT_PREFIX}/register
    exit $?
}

function binfmt_misc_disable()
{
    if [ "${NO_DISABLE_BINFMT_MISC}" == "y" ]
    then
        echo "Disable of binfmt_misc handler for exagear is disabled."
        exit 0
    fi

    if [ ! -d "${BINFMT_PREFIX}" ]
    then
        echo "binfmt_misc is not available on this host"
        exit 1
    fi

    [ -e ${BINFMT_CONTROL} ] && echo -1 > ${BINFMT_CONTROL}

    if [ -e ${BINFMT_CONTROL} ] ; then
        exit 1
    else
        exit 0
    fi
}

function binfmt_misc_status()
{
    if [ ! -d "${BINFMT_PREFIX}" ]
    then
        echo "binfmt_misc is not available on this host"
        exit 1
    fi

    if [ -e "${BINFMT_CONTROL}" ]
    then
        exit 0
    else
        exit 1
    fi
}

if [ -z "${1}" ]
then
        print_usage_and_exit
fi

CMD="${1}"
shift

if [ "${CMD}" == "binfmt_misc" ]
then
    GUEST_ARCH="${1}"    
    if [ ! -e ${EXAGEAR_ROOT_DIR}/etc/exagear-${GUEST_ARCH}.conf ]
    then
        echo "Unknown guest arch: ${GUEST_ARCH}"
        exit 1
    fi

    . ${EXAGEAR_ROOT_DIR}/etc/exagear-${GUEST_ARCH}.conf

    BINFMT_PREFIX="/proc/sys/fs/binfmt_misc"
    BINFMT_DESC="exagear"
    BINFMT_NAME="${EXAGEAR_GUEST_ARCH_NAME}_exagear_guest"
    BINFMT_PREFIX="/proc/sys/fs/binfmt_misc"
    BINFMT_OPTIONS="${EXAGEAR_BINFMT_OPTIONS}"
    BINFMT_CONTROL="${BINFMT_PREFIX}/${BINFMT_NAME}"
    BINFMT_INTERPRETER="${EXAGEAR_ROOT_DIR}/bin/ubt_binfmt_misc_wrapper_${EXAGEAR_GUEST_ARCH_NAME}"
    shift

    SUBCMD="${1}"
    if [ "${SUBCMD}" == "enable" ] ; then
        binfmt_misc_enable
    elif [ "${SUBCMD}" == "disable" ] ;then
        binfmt_misc_disable
    elif [ "${SUBCMD}" == "status" ] ;then
        binfmt_misc_status
    else
        print_usage_and_exit
    fi
fi
