Repository: opencontainers/runc
File: tests/rootless.sh (Shell)

Code before:

	return 0
}

function cleanup() {
	if [ -v AUX_DIR ]; then
		rmdir "$AUX_DIR"
		unset AUX_DIX
	fi
}

# FEATURE: Opportunistic cgroups support, allowing a rootless container to set
#          resource limits on condition that cgroupsPath is set to a path the
#          rootless user has permissions on.

# List of cgroups. We handle name= cgroups as well as combined
# (comma-separated) cgroups and correctly split and/or strip them.
# shellcheck disable=SC2207
ALL_CGROUPS=($(cut -d: -f2 </proc/self/cgroup | sed -E '{s/^name=//;s/,/\n/;/^$/D}'))
CGROUP_MOUNT="/sys/fs/cgroup"
CGROUP_PATH="/runc-cgroups-integration-test"
SID=-1

function enable_cgroup() {
	sleep inf &
	SID=$!
	# Set up cgroups for use in rootless containers.
	for cg in "${ALL_CGROUPS[@]}"; do
		echo "$CGROUP_MOUNT/$cg$CGROUP_PATH"
		mkdir -p "$CGROUP_MOUNT/$cg$CGROUP_PATH"
		ls "$CGROUP_MOUNT/$cg$CGROUP_PATH" -alh
		echo "$SID" >"$CGROUP_MOUNT/$cg$CGROUP_PATH/cgroup.procs" || true
		# We only need to allow write access to {cgroup.procs,tasks} and the
		# directory. Rather than changing the owner entirely, we just change
		# the group and then allow write access to the group (in order to
		# further limit the possible DAC permissions that runc could use).
		chown root:rootless "$CGROUP_MOUNT/$cg$CGROUP_PATH/"{,cgroup.procs,tasks}
		chmod g+rwx "$CGROUP_MOUNT/$cg$CGROUP_PATH/"{,cgroup.procs,tasks}
		# Due to cpuset's semantics we need to give extra permissions to allow
		# for runc to set up the hierarchy. XXX: This really shouldn't be
		# necessary, and might actually be a bug in our impl of cgroup
		# handling.
		[ "$cg" = "cpuset" ] && chown rootless:rootless "$CGROUP_MOUNT/$cg$CGROUP_PATH/cpuset."{cpus,mems}
		# The following is required by "update rt period and runtime".
		if [ "$cg" = "cpu" ]; then
			if [[ -e "$CGROUP_MOUNT/$cg$CGROUP_PATH/cpu.rt_period_us" ]]; then
				chown rootless:rootless "$CGROUP_MOUNT/$cg$CGROUP_PATH/cpu.rt_period_us"
			fi
			if [[ -e "$CGROUP_MOUNT/$cg$CGROUP_PATH/cpu.rt_runtime_us" ]]; then
				chown rootless:rootless "$CGROUP_MOUNT/$cg$CGROUP_PATH/cpu.rt_runtime_us"
			fi

Review comment (suggestion):
It would be nice to have a (short) comment explaining what this is for, and `SID` should be a little more descriptive like `CGROUP_PIN_PID` or something.

Code after:

	return 0
}

function cleanup() {
	if [ -v AUX_DIR ]; then
		rmdir "$AUX_DIR"
		unset AUX_DIX
	fi
}

# FEATURE: Opportunistic cgroups support, allowing a rootless container to set
#          resource limits on condition that cgroupsPath is set to a path the
#          rootless user has permissions on.

# List of cgroups. We handle name= cgroups as well as combined
# (comma-separated) cgroups and correctly split and/or strip them.
# shellcheck disable=SC2207
ALL_CGROUPS=($(cut -d: -f2 </proc/self/cgroup | sed -E '{s/^name=//;s/,/\n/;/^$/D}'))
CGROUP_MOUNT="/sys/fs/cgroup"
CGROUP_PATH="/runc-cgroups-integration-test"
CGROUP_PIN_PID=-1

function enable_cgroup() {
	# cgroup v2
	if [[ -e "$CGROUP_MOUNT/cgroup.controllers" ]]; then
		# Enable controllers. Some controller (e.g. memory) may fail on containerized environment.
		set -x
		# shellcheck disable=SC2013
		for f in $(cat "$CGROUP_MOUNT/cgroup.controllers"); do echo "+$f" >"$CGROUP_MOUNT/cgroup.subtree_control"; done
		set +x
		# Create the cgroup.
		mkdir -p "$CGROUP_MOUNT/$CGROUP_PATH"
		# chown/chmod dir + cgroup.subtree_control + cgroup.procs + parent's cgroup.procs.
		# See https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#delegation-containment
		chown root:rootless "$CGROUP_MOUNT/$CGROUP_PATH" "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.subtree_control" "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.procs" "$CGROUP_MOUNT/cgroup.procs"
		chmod g+rwx "$CGROUP_MOUNT/$CGROUP_PATH"
		chmod g+rw "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.subtree_control" "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.procs" "$CGROUP_MOUNT/cgroup.procs"
	else
		# On some systems (e.g., AlmaLinux 8), systemd automatically removes cgroup paths
		# when they become empty (i.e., contain no processes). To prevent this, we spawn
		# a dummy process to pin the cgroup in place.
		# See: https://github.com/opencontainers/runc/issues/5003
		sleep inf &
		CGROUP_PIN_PID=$!
		# Set up cgroups for use in rootless containers.
		for cg in "${ALL_CGROUPS[@]}"; do
			mkdir -p "$CGROUP_MOUNT/$cg$CGROUP_PATH"
			# TODO: Consider retrying on "No space left on device" errors.
			echo "$CGROUP_PIN_PID" >"$CGROUP_MOUNT/$cg$CGROUP_PATH/cgroup.procs" || true
			# We only need to allow write access to {cgroup.procs,tasks} and the