#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-only
#
# Start/Stop the workload manager
#
# Copyright IBM Corporation. 2008
#
# Authors:     Balbir Singh <balbir@linux.vnet.ibm.com>
#
# cgconfig Control Groups Configuration Startup
# chkconfig: - 5 95
# description: This script runs the cgconfigparser utility to parse and setup
#              the control group filesystem. It uses /etc/cgconfig.conf
#              and parses the configuration specified in there.

### BEGIN INIT INFO
# Provides:             cgconfig
# Required-Start:
# Required-Stop:
# Should-Start:         ypbind
# Should-Stop:          ypbind
# Short-Description:    Create and setup control group filesystem(s)
# Description:          Create and setup control group filesystem(s)
### END INIT INFO

# get correct location of binaries from configure
sbindir=/usr/sbin
CGCONFIGPARSER_BIN=$sbindir/cgconfigparser
CONFIG_FILE=/etc/cgconfig.conf
CONFIG_DIR=/etc/cgconfig.d
servicename=cgconfig


lockfile=/run/lock/subsys/$servicename
#
# Source LSB routines
#
SYSLIBFILE=/lib/lsb/init-functions
OLDSYSLIBFILE=/etc/init.d/functions
if [[ -x  $SYSLIBFILE ]] ; then
  # shellcheck disable=SC1090
  source $SYSLIBFILE
elif  [[ -x $OLDSYSLIBFILE ]] ; then
  # shellcheck disable=SC1090
  source $OLDSYSLIBFILE
  log_warning_msg() ( warning "$@" ; printf "\n" 1>&2 ; )
  log_failure_msg() ( failure "$@" ; printf "\n" 1>&2 ; )
  log_success_msg() ( success "$@" ; printf "\n" 1>&2 ; )
else
  log_warning_msg() ( printf "warning:%s\n" "$@" 1>&2 ;)
  log_failure_msg() ( printf "failure:%s\n" "$@" 1>&2 ;)
  log_success_msg() ( printf "success:%s\n" "$@" 1>&2 ;)
fi

# read the config
CREATE_DEFAULT=yes
if [ -e /etc/sysconfig/cgconfig ]; then
	# shellcheck disable=SC1091
        source /etc/sysconfig/cgconfig
fi

lockfiledir=$(dirname "$lockfile")

create_default_groups() {
	defaultcgroup=

        if [ -f /etc/cgrules.conf ]; then
	    # shellcheck disable=SC2034
	    read -r user ctrl defaultcgroup <<< \
		    "$(grep -m1 '^\*[[:space:]]\+' /etc/cgrules.conf)"
           if [[ ( -n "$defaultcgroup" ) && ( "$defaultcgroup" = "*" ) ]]; then
                log_warning_msg "/etc/cgrules.conf incorrect"
                log_warning_msg "Overriding it"
                defaultcgroup=
            fi
        fi

        if [[ -z "$defaultcgroup" ]]
        then
            defaultcgroup=sysdefault/
        fi

        #
        # Find all mounted subsystems and create comma-separated list
        # of controllers.
        #
        controllers=$(lssubsys 2>/dev/null | tr '\n' ',' | sed s/.$//)

        #
        # Create the default group, ignore errors when the default group
        # already exists.
        #
        cgcreate -f 664 -d 775 -g "$controllers":"$defaultcgroup" 2>/dev/null

        #
        # special rule for cpusets
        #
        if echo "$controllers" | grep -q -w cpuset; then
                cpus=$(cgget -nv -r cpuset.cpus /)
                cgset -r cpuset.cpus="$cpus $defaultcgroup"
                mems=$(cgget -nv -r cpuset.mems /)
                cgset -r cpuset.mems="$mems $defaultcgroup"
        fi

        #
        # Classify everything to default cgroup. Ignore errors, some processes
        # may exit after ps is run and before cgclassify moves them.
        #
        cgclassify -g "$controllers:$defaultcgroup $(ps --no-headers -eL o tid)" \
                 2>/dev/null || :
}

start() {
        printf "Starting %s service: " "$servicename"
	if [[ -f "$lockfile" ]]; then
            log_warning_msg "lock file already exists"
            return 0
        fi

        if [[ ! -s "$CONFIG_FILE" ]]; then
          log_failure_msg $CONFIG_FILE "is not configured"
          return 6
        fi


        if ! "$CGCONFIGPARSER_BIN" -l "$CONFIG_FILE" -L "$CONFIG_DIR"
        then
          log_failure_msg "Failed to parse " "$CONFIG_FILE" "or" "$CONFIG_DIR"'/*'
          return 1
        fi

        if [ $CREATE_DEFAULT = "yes" ]; then
                create_default_groups
        fi

        if ! mkdir -p "$lockfiledir" ; then
          log_failure_msg "Failed to mkdir $lockfiledir directory"
          return 1
        fi


        if ! touch "$lockfile" ; then
            log_failure_msg "Failed to touch $lockfile"
            return 1
        fi
        log_success_msg "Started $servicename"
        return 0
}

stop() {
    printf "Stopping %s service is not supported!: " "$servicename"
    log_failure_msg "Failed to stop $servicename"
    return 1
}

trapped() {
    #
    # Do nothing
    #
    true
}

usage() {
    echo "$0 <start|stop|restart|condrestart|status>"
    exit 2
}

common() {
    #
    # main script work done here
    #
    trap "trapped ABRT" ABRT
    trap "trapped QUIT" QUIT
    trap "trapped TERM" TERM
    trap "trapped INT"   INT
}

restart() {
	common
	stop
	start
}

RETVAL=0

case $1 in
    'stop')
        common
        stop
        RETVAL=$?
        ;;
    'start')
        common
        start
        RETVAL=$?
        ;;
    'restart'|'reload')
	restart
        RETVAL=$?
        ;;
    'condrestart')
        if [[ -f "$lockfile" ]]; then
            restart
            RETVAL=$?
        fi
        ;;
    'status')
        if [ -f "$lockfile" ]; then
            echo "Running"
            exit 0
        else
            echo "Stopped"
            exit 3
        fi
	;;
    *)
        usage
        ;;
esac

exit $RETVAL
