#!/bin/sh
# Prepare cgroup v2 so a nested container manager can create its own cgroups.
#
# Move our whole process tree into a leaf, so the (namespaced) cgroup root has no
# member processes and can be delegated as a plain "domain"; then delegate every
# available controller to children. Without this the root stays populated and the
# first controller we enable converts it to "domain threaded", which then rejects
# the domain-only controllers (memory/io) and a nested kubelet cannot create
# /sys/fs/cgroup/kubepods.
#
# This is a POSIX sh script rather than an execline `up` on purpose: the drain
# must move pids with a *builtin* echo. An external echo (as execline uses) forks
# a helper process into the very cgroup we are trying to empty, so the root never
# drains. Any /bin/sh (dash/busybox/bash) has a builtin echo, so no bash needed.
CG=/sys/fs/cgroup

# Mount cgroup2 if not already mounted -- match on fstype, not the (arbitrary)
# source name. Options match systemd's unified hierarchy. Best-effort.
[ "$(stat -fc %T "$CG" 2>/dev/null)" = cgroup2fs ] ||
  mount -t cgroup2 -o nsdelegate,memory_recursiveprot,nosuid,nodev,noexec cgroup2 "$CG" 2>/dev/null

# cgroup v2 only; nothing to do otherwise (or if the mount failed).
[ -e "$CG/cgroup.controllers" ] || exit 0

# Leaf for our own process tree. Move PID 1 (s6-svscan) in first so newly-spawned
# services land in the leaf and the root cannot refill while we sweep the rest.
mkdir -p "$CG/init"
echo 1 > "$CG/init/cgroup.procs" 2>/dev/null || :

# Sweep every remaining process out of the root into the leaf, until the root
# reads empty. Emptiness is checked by reading cgroup.procs, not its stat size
# (kernfs always reports size 0). Bounded so a pathological race can't hang boot.
i=0
while [ "$i" -lt 20 ]; do
  while read -r pid; do echo "$pid" > "$CG/init/cgroup.procs" 2>/dev/null || :; done < "$CG/cgroup.procs"
  [ -n "$(cat "$CG/cgroup.procs" 2>/dev/null)" ] || break
  i=$((i + 1))
done

# Root is empty now -> every controller delegates and the root stays a domain.
# Best-effort per controller: some (e.g. cpu with RT tasks) may refuse.
for c in $(cat "$CG/cgroup.controllers"); do
  echo "+$c" > "$CG/cgroup.subtree_control" 2>/dev/null || :
done

exit 0
