#!/bin/sh
# Mount cgroups. Default: unified (cgroup v2). Hybrid/legacy v1 mounts fail on
# kernels that only expose cgroup2 ("Unknown subsys name 'cpuset'|'memory'").
exec 2>&1

CONF=/etc/s6-rc/config/mount-cgroups.conf
[ -f "$CONF" ] || CONF=/etc/s6-rc/config/mount-cgroups.conf
if [ -f "$CONF" ]; then
	# shellcheck disable=SC1090
	. "$CONF"
fi

CGROUP_OPTS=${CGROUP_OPTS:-nodev,noexec,nosuid}
CGROUP_MODE=${CGROUP_MODE:-unified}
CGROUP_CONTROLLERS=${CGROUP_CONTROLLERS:-none}
HAVE_CONTROLLER1_GROUPS=${HAVE_CONTROLLER1_GROUPS:-false}

# Kernel already on pure cgroup2 at /sys/fs/cgroup → force unified.
if [ -f /sys/fs/cgroup/cgroup.controllers ] || \
   grep -qw 'cgroup2' /proc/filesystems && ! grep -qw 'cgroup$' /proc/filesystems; then
	CGROUP_MODE=unified
	HAVE_CONTROLLER1_GROUPS=false
fi
# cmdline cgroup_no_v1=all / systemd.unified_cgroup_hierarchy=1
if grep -Eq '(^|[[:space:]])(systemd\.)?unified_cgroup_hierarchy=1($|[[:space:]])' /proc/cmdline 2>/dev/null || \
   grep -Eq '(^|[[:space:]])cgroup_no_v1=all($|[[:space:]])' /proc/cmdline 2>/dev/null; then
	CGROUP_MODE=unified
	HAVE_CONTROLLER1_GROUPS=false
fi

if [ "$CGROUP_CONTROLLERS" = "none" ]; then
	CGROUP_CONTROLLERS=""
fi

cgroup2_find_path() {
	grep -qw cgroup2 /proc/filesystems || return 0
	case "${CGROUP_MODE}" in
		hybrid) printf "/sys/fs/cgroup/unified" ;;
		unified) printf "/sys/fs/cgroup" ;;
	esac
}

cgroup1_base() {
	grep -qw cgroup /proc/filesystems || return 0
	# Do not clobber an existing cgroup2 mount on /sys/fs/cgroup.
	if mountpoint -q /sys/fs/cgroup; then
		if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
			return 0
		fi
	else
		opts="${CGROUP_OPTS},mode=755,size=${rc_cgroupsize:-10m}"
		mount -n -t tmpfs -o "${opts}" cgroup_root /sys/fs/cgroup || return 0
	fi

	if ! mountpoint -q /sys/fs/cgroup/s6-rc; then
		mkdir -p /sys/fs/cgroup/s6-rc
		agent=/etc/s6-rc/sv/mount-cgroups/cgroup-release-agent.sh
		[ -x "$agent" ] || agent=/etc/s6-rc/sv/mount-cgroups/cgroup-release-agent.sh
		mount -n -t cgroup -o none,${CGROUP_OPTS},name=s6-rc${agent:+,release_agent=$agent} \
			s6-rc /sys/fs/cgroup/s6-rc 2>/dev/null || true
		[ -f /sys/fs/cgroup/s6-rc/notify_on_release ] && printf 1 > /sys/fs/cgroup/s6-rc/notify_on_release
	fi
}

cgroup1_controllers() {
	case "${HAVE_CONTROLLER1_GROUPS}" in
		true|yes|1) ;;
		*) return 0 ;;
	esac
	[ -e /proc/cgroups ] && grep -qw cgroup /proc/filesystems || return 0
	# hybrid + empty controller list: do not mount leftover v1 groups
	if [ -z "${CGROUP_CONTROLLERS}" ] && [ "${CGROUP_MODE}" != legacy ]; then
		return 0
	fi
	# Already unified at root — v1 named mounts will fail
	[ -f /sys/fs/cgroup/cgroup.controllers ] && return 0

	while read -r name _ _ enabled _; do
		case "${enabled}" in
			1)
				mountpoint -q "/sys/fs/cgroup/${name}" && continue
				for x in $CGROUP_CONTROLLERS; do
					[ "${name}" = "blkio" ] && [ "${x}" = "io" ] && continue 2
					[ "${name}" = "${x}" ] && continue 2
				done
				mkdir -p "/sys/fs/cgroup/${name}"
				# Tolerate missing v1 subsys (unified-only kernels).
				mount -n -t cgroup -o "${CGROUP_OPTS},${name}" \
					"${name}" "/sys/fs/cgroup/${name}" 2>/dev/null || \
					rmdir "/sys/fs/cgroup/${name}" 2>/dev/null || true
				;;
		esac
	done < /proc/cgroups
}

cgroup2_base() {
	grep -qw cgroup2 /proc/filesystems || return 0
	base="$(cgroup2_find_path)"
	[ -n "$base" ] || return 0
	mkdir -p "${base}"
	if ! mountpoint -q "${base}"; then
		mount -t cgroup2 none -o "${CGROUP_OPTS},nsdelegate" "${base}" 2>/dev/null ||
			mount -t cgroup2 none -o "${CGROUP_OPTS}" "${base}" 2>/dev/null || true
	fi
}

cgroup2_controllers() {
	grep -qw cgroup2 /proc/filesystems || return 0
	cgroup_path="$(cgroup2_find_path)"
	[ -z "${cgroup_path}" ] && return 0
	[ -e "${cgroup_path}/cgroup.controllers" ] && read -r active < "${cgroup_path}/cgroup.controllers"
	for x in ${CGROUP_CONTROLLERS}; do
		for y in ${active}; do
			if [ "$x" = "$y" ] && [ -e "${cgroup_path}/cgroup.subtree_control" ]; then
				echo "+${x}" > "${cgroup_path}/cgroup.subtree_control" 2>/dev/null || true
			fi
		done
	done
}

case "${CGROUP_MODE}" in
	hybrid)
		cgroup1_base
		cgroup2_base
		cgroup2_controllers
		cgroup1_controllers
		;;
	legacy)
		cgroup1_base
		cgroup1_controllers
		;;
	unified|*)
		cgroup2_base
		cgroup2_controllers
		;;
esac
exit 0
