#!/bin/sh

__rctl_limits () {
    local _name _fulluuid _dataset _value _limit _action _prop _failed _rlimits

    _failed=0
    _name=$1
    _dataset="$(__find_jail ${_name})" || exit $?
    _fulluuid="$(__check_name ${_name} ${_dataset})"

    _rlimits="$(__get_jail_prop rlimits ${_fulluuid} ${_dataset})"

    if [ ${_rlimits} = "on" ] ; then
        echo -n "  + Applying resource limits"
        for _prop in ${CONF_RCTL} ; do
            _value="$(__get_jail_prop ${_prop} ${_fulluuid} ${_dataset})"
            _limit=$(echo ${_value} | awk 'BEGIN { FS = ":" } ; { print $1 }')
            _action=$(echo ${_value} | awk 'BEGIN { FS = ":" } ; { print $2 }')

            if [ ${_limit} = "off" ] ; then
                continue
            else
                if [ -z "${_limit}" ] || [ -z "${_action}" ] ; then
                    echo -n "  ERROR: incorrect resource limit: ${_limit} action: "
                    echo "${_action} for property: ${_prop}"
                    echo "  HINT : check man page for syntax."
                else
                    rctl -a jail:ioc-${_fulluuid}:${_prop}:${_action}=${_limit}
                    if [ $? -eq 1 ] ; then
                        echo "    FAILED to apply ${_prop}=${_action}:${_limit}"
                        _failed=1
                    fi
                fi
            fi
        done
        if [ ${_failed} -ne 1 ] ; then
            echo " OK"
        fi
    fi
}

__rctl_list () {
    local _name _fulluuid _dataset _jid _limits _limit

    _name="$1"

    if [ -z "${_name}" ] ; then
        echo "* All active limits:"
        rctl | grep jail
    else
        _dataset="$(__find_jail ${_name})" || exit $?
        _fulluuid="$(__check_name ${_name} ${_dataset})"
        _jid="$(jls -j ioc-${_fulluuid} jid)"
        _limits="$(rctl -h | grep ${_fulluuid})"

        echo "* Active limits for jail: ${_fulluuid}"

        for _i in ${_limits} ; do
            _limit=$(echo ${_i} | cut -f 3,4 -d:)
            echo "  - ${_limit}"
        done

        if [ ! -z "${_jid}" ] ; then
            echo "* CPU set: $(cpuset -g -j ${_jid} | cut -f2 -d:)"
        fi
    fi
}

__rctl_uncap () {
    local _name _fulluuid _dataset

    _name="$1"

    if [ -z ${_name} ] ; then
        __die "missing UUID!"
    fi

    _dataset="$(__find_jail ${_name})" || exit $?
    _fulluuid="$(__check_name ${_name} ${_dataset})"

    echo "  Releasing resource limits.."
    rctl -r jail:ioc-${_fulluuid}
    echo "  Listing active rules for jail:"
    rctl | grep ${_fulluuid}
}


__rctl_inuse () {
    local _name _dataset _fulluuid

    _name="$1"

    if [ -z ${_name} ] ; then
        __rctl_inuse_all
        exit 0
    fi

    _dataset="$(__find_jail ${_name})" || exit $?

    if [ -z ${_dataset} ] ; then
        __die "${_name} not found!"
    fi

    _fulluuid="$(__check_name ${_name} ${_dataset})"

    echo "Consumed resources:"
    echo "-------------------"
    rctl -hu jail:ioc-${_fulluuid}
}

__rctl_inuse_all () {
    local _jails _fulluuid _tag _print_head\
          _line _res _jail _header

    _jails=$(__find_jail ALL | \
            awk 'BEGIN { FS = "/" } ; { if (length($NF)==36) { print }}')
    _print_head=1

    for _jail in $(echo ${_jails}) ; do
        # _jail is actually a dataset, so fulluuid needs to be faked.
        _fulluuid="$(__check_name "name" ${_jail} 2> /dev/null)"
        _tag="$(__get_jail_prop tag ${_fulluuid} ${_jail})"
        _resources="$(rctl -hu jail:ioc-${_fulluuid})"
        _state="$(__is_running ${_fulluuid})"

        for _res in $(echo ${_resources}) ; do
            _value="$(echo ${_res}|cut -f2 -d=)"
            _header="$(echo ${_res}|cut -f1 -d=)"
            _line="${_line},${_value}"
        done

        if [ ${_print_head} -eq 1 ] ; then
            echo -n "UUID,TAG,cputime,datasize,stacksize,coredumpsize,memoryuse,"
            echo -n "memorylocked,maxproc,openfiles,vmemoryuse,pseudoterminals,"
            echo -n "swapuse,nthr,msgqqueued,msgqsize,nmsgq,nsem,nsemop,nshm,"
            echo    "shmsize,wallclock,pcpu"
            _print_head=0
        fi

        if [ ! -z ${_state} ] ; then
            echo "${_fulluuid},${_tag}${_line}"
        fi

        unset _line
    done
}
