#!/sbin/openrc-run # # Control Groups Configuration Startup # # This script runs the cgconfigparser utility to parse and setup # the control group filesystem. It uses ${CONFIG_FILE} # and parses the configuration specified in there. # CGCONFIGPARSER="/usr/sbin/cgconfigparser" CGROUP_FS="cgroup" CONFIG_FILE=${CONFIG_FILE:-"/etc/cgroup/cgconfig.conf"} MOUNTS_FILE="/proc/mounts" RULES_FILE="/etc/cgroup/cgrules.conf" # Support multiple mount points MAX_INDEX=0 declare -a MOUNT_POINTS MOUNT_OPTIONS move_all_to_init_class() { local i for i in $(seq 1 ${MAX_INDEX}); do cd ${MOUNT_POINTS[$i]} if grep -qw ${MOUNT_POINTS[$i]} ${MOUNTS_FILE}; then local directory for directory in $(find . -depth -type d); do if [[ ${directory} != "." ]]; then # cat fails with "Argument list too long" error sed -nu p < ${directory}/tasks > tasks rmdir ${directory} fi done else ewarn "Resource control filesystem not mounted" fi cd - >/dev/null done } parse_mounts() { local device mount_point fs_type options other while read device mount_point fs_type options other; do if grep -q ${device} <<< ${CGROUP_FS}; then let MAX_INDEX++ MOUNT_POINTS[${MAX_INDEX}]=${mount_point} MOUNT_OPTIONS[${MAX_INDEX}]=${options} fi done < ${MOUNTS_FILE} } umount_fs() { local i for i in $(seq 1 ${MAX_INDEX}); do umount ${MOUNT_POINTS[$i]} rmdir ${MOUNT_POINTS[$i]} done } start() { ebegin "Starting cgconfig service" # Mount filesystem and create cgroups if ! ${CGCONFIGPARSER} -l ${CONFIG_FILE} >/dev/null; then eend 1 "Failed to parse ${CONFIG_FILE}" return 1 fi parse_mounts # Find default cgroup name in rules file local default_cgroup if [[ -f ${RULES_FILE} ]]; then local user controller read user controller default_cgroup <<< $(grep -m1 '^\*\s' ${RULES_FILE}) if [[ $default_cgroup == "*" ]]; then ewarn "${RULES_FILE} incorrect" ewarn "Overriding it" default_cgroup= fi fi # Use predefined name if none was found if [[ -z ${default_cgroup} ]]; then default_cgroup=sysdefault fi # Create a default cgroup for tasks to return back to local i for i in $(seq 1 ${MAX_INDEX}); do # Ignore if directory already exists mkdir -p ${MOUNT_POINTS[$i]}/${default_cgroup} find ${MOUNT_POINTS[$i]}/ -name tasks | xargs chmod a+rw chmod go-w ${MOUNT_POINTS[$i]}/tasks # Special rule for cpusets if grep -qw cpuset <<< ${MOUNT_OPTIONS[$i]}; then cat ${MOUNT_POINTS[$i]}/cpuset.cpus > ${MOUNT_POINTS[$i]}/${default_cgroup}/cpuset.cpus cat ${MOUNT_POINTS[$i]}/cpuset.mems > ${MOUNT_POINTS[$i]}/${default_cgroup}/cpuset.mems fi # Classify everything to default cgroup local j for j in $(ps --no-headers -eL o tid); do echo $j > ${MOUNT_POINTS[$i]}/${default_cgroup}/tasks 2>/dev/null done done eend 0 } stop() { ebegin "Stopping cgconfig service" parse_mounts move_all_to_init_class umount_fs eend 0 }