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

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 /opt/exagear/shared/exagear-${GUEST_ARCH}.conf ]
    then
        echo "Unknown guest arch: ${GUEST_ARCH}"
        exit 1
    fi

    . /opt/exagear/shared/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="/opt/exagear/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
elif [ "${CMD}" == "binfmt_misc_optimizer_aux" ]
then
    GUEST_ARCH="${1}"
    if [ ! -e /opt/exagear/shared/exagear-${GUEST_ARCH}.conf ]
    then
        echo "Unknown guest arch: ${GUEST_ARCH}"
        exit 1
    fi

    . /opt/exagear/shared/exagear-${GUEST_ARCH}.conf

    BINFMT_PREFIX="/proc/sys/fs/binfmt_misc"
    BINFMT_DESC="exagear optimizer aux"
    BINFMT_NAME="${EXAGEAR_GUEST_ARCH_NAME}_exagear_optimizer_aux"
    BINFMT_PREFIX="/proc/sys/fs/binfmt_misc"
    BINFMT_OPTIONS="F"
    BINFMT_CONTROL="${BINFMT_PREFIX}/${BINFMT_NAME}"
    BINFMT_INTERPRETER="${EXAGEAR_OPT_BINARY}"
    EXAGEAR_GUEST_ELF_MAGIC="${EXAGEAR_OPTIMIZER_AUX_MAGIC}"
    EXAGEAR_GUEST_ELF_MASK="${EXAGEAR_OPTIMIZER_AUX_MASK}"

    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
