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

. ${EXAGEAR_CORE_CONF}
. ${EXAGEAR_GUEST_CONF}
#NOTE: 8200 == 8192 (default value of hifd-reserve of ubt) - 8 (count of reserved fds for hifd)
if [ `ulimit -Hn` -lt 8200 ] #Limit is too low.
then
    if ! ulimit -Hn 8200 2>/dev/null   # Try to rise it
    then
        if [ `ulimit -Hn` -lt 32 ]
        then
            echo "Exagear:  Fatal error: ulimit (NOFILE) must be > 32"
            exit 1
        fi

        # Failed to rise, put fd limit lower (static area will be placed on lower fd numbers)
        EXAGEAR_FD_HARD_LIMIT=$((`ulimit -Hn` - 16))
    fi
fi

. /opt/exagear/shared/ubt-make-opt-cmdline

IMAGE_DIR=/opt/exagear/images/${EXAGEAR_GUEST_IMAGE_NAME}
VPATHS_LIST="${IMAGE_DIR}/.exagear/vpaths-list"
OPATHS_LIST="${IMAGE_DIR}/.exagear/opaths-list"
UTMP_LIST="${IMAGE_DIR}/.exagear/utmp-list"

if [ "${EXAGEAR_USE_OPT}" == "y" ]
then
    if [ ! -z "${EXAGEAR_OPT_SOCKET}" -a \( -z "${EXAGEAR_IN_CONTAINER}" -o "${EXAGEAR_IN_CONTAINER}" == "n" \) ]
    then
        if [ ! -S "${EXAGEAR_OPT_SOCKET}" ]
        then
            echo "ExaGear optimizer socket ${EXAGEAR_OPT_SOCKET} doesn't exist! Enable optimizer service or disable optimizer in config."
            exit 1
        fi
    else
        if [ ! -f "${EXAGEAR_OPT_BINARY}" ]
        then
            echo "ExaGear optimizer binary ${EXAGEAR_OPT_BINARY} doesn't exist! Reinstall ExaGear or disable optimizer in config."
            exit 1
        fi
    fi
fi

if exagear-manage binfmt_misc ${EXAGEAR_GUEST_ARCH_NAME} status
then
    SUGID_EXEC_METHOD="--use-binfmt-misc"
fi

C=''
for i in "$@"; do
    i="${i//\\/\\\\}"
    C="$C \"${i//\"/\\\"}\""
done
CMDLINE_OPTS=`exagear_make_opt_cmdline`


if [ `cat /proc/sys/kernel/perf_event_paranoid` -ge 3 ]
then
    echo "Failed to start exagear. /proc/sys/kernel/perf_event_paranoid == $(cat /proc/sys/kernel/perf_event_paranoid) but it must be <= 2."
    exit 1
fi

if [ "${EXAGEAR_IN_CONTAINER}" == "y" ]
then
    # In this mode we make flat rootfs by combining guest image and parts of host rootfs
    # using bwrap and run UBT in resulting container.

    if ! command -v bwrap 2>&1 >/dev/null; then
        echo -e "\nBubblewrap (bwrap) is required to run ExaGear in container mode."
        echo "Please install Bubblewrap package."
        exit 1
    fi

    EXAGEAR_UBT_BINARY=`realpath "${EXAGEAR_UBT_BINARY}"`
    EXAGEAR_BIN_PATH=`dirname "${EXAGEAR_UBT_BINARY}"`
    EXAGEAR_RUN_PATH=`dirname "${EXAGEAR_OPT_SOCKET}"`

    EXAGEAR_CONT_BIN="/.exagear/bin"
    EXAGEAR_CONT_RUN="/.exagear/run"

    if [ ! -e "${IMAGE_DIR}${EXAGEAR_CONT_BIN}" ]; then
        echo -e "\nDirectory ${IMAGE_DIR}${EXAGEAR_CONT_BIN} doesn't exist, probably you're using old guest image."
        echo "Please create ${IMAGE_DIR}${EXAGEAR_CONT_BIN} or install latest guest image."
        exit 1
    fi
    if [ ! -e "${IMAGE_DIR}${EXAGEAR_CONT_RUN}" ]; then
        echo -e "\nDirectory ${IMAGE_DIR}${EXAGEAR_CONT_RUN} doesn't exist, probably you're using old guest image."
        echo "Please create ${IMAGE_DIR}${EXAGEAR_CONT_RUN} or install latest guest image."
        exit 1
    fi

    # Path to main UBT binary in rootfs
    EXAGEAR_UBT_BINARY="${EXAGEAR_CONT_BIN}/`basename ${EXAGEAR_UBT_BINARY}`"

    CMDLINE_OPTS=$(sed "s#${EXAGEAR_BIN_PATH}#${EXAGEAR_CONT_BIN}#g" <<< ${CMDLINE_OPTS})
    CMDLINE_OPTS=$(sed "s#${EXAGEAR_RUN_PATH}#${EXAGEAR_CONT_RUN}#g" <<< ${CMDLINE_OPTS})

    # Bind guest image as rootfs
    BIND_ARGS="--bind ${IMAGE_DIR} /"
    # Bind ExaGear's 'bin' dir to ${EXAGEAR_CONT_BIN}
    BIND_ARGS+=" --ro-bind ${EXAGEAR_BIN_PATH} ${EXAGEAR_CONT_BIN}"
    BIND_ARGS+=" --ro-bind ${EXAGEAR_RUN_PATH} ${EXAGEAR_CONT_RUN}"

    # Bind everything from vpaths_list to rootfs
    while read p
    do
    if [ -e "$p" ]; then
        BIND_ARGS+=" --bind $p $p"
    fi
    done < ${VPATHS_LIST}

    # Make bwrap command, add /proc and /dev mounts
    BWRAP_PREFIX="bwrap ${BIND_ARGS} --proc /proc --dev /dev -- "

    CMDLINE_OPTS+=" --vfs-kind host-first"

    # Run UBT in container
    exec ${BWRAP_PREFIX} ${EXAGEAR_UBT_BINARY} ${CMDLINE_OPTS} -- /bin/bash -c  "${C}"
fi

exec ${EXAGEAR_UBT_BINARY} --path-prefix ${IMAGE_DIR} --utmp-paths-list ${UTMP_LIST} --vpaths-list ${VPATHS_LIST} --opaths-list ${OPATHS_LIST} ${SUGID_EXEC_METHOD} ${CMDLINE_OPTS} -- \
/bin/bash -c  "${C}"
