aboutsummaryrefslogtreecommitdiffstats
path: root/testing/libcgroup/cgconfig.initd
blob: ae64ae1611c27e5857ce83dea24100f942ca833f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/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/cgconfig.conf"}
MOUNTS_FILE="/proc/mounts"
RULES_FILE="/etc/cgrules.conf"

# Support multiple mount points
MOUNT_POINTS=

move_all_to_init_class() {
	local i
	for i in $MOUNT_POINTS; do
		local mount_point=${i%:*}
		cd ${mount_point}

		if grep -qw "${mount_point}" ${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 echo ${CGROUP_FS} | grep -q ${device}; then
			MOUNT_POINTS="${MOUNT_POINTS} ${mount_point}:${options}"
		fi
	done < ${MOUNTS_FILE}
}

umount_fs() {
	local i
	for i in ${MOUNT_POINTS}; do
		umount ${i%:*}
		rmdir ${i%:*}
	done
}

depend() {
	need local
}

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
		default_cgroup=$(awk '$1 == "*" {print $3; exit}' ${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 $MOUNT_POINTS; do
		local mount_point=${i%:*}
		local mount_options=${i#*:}
		# Ignore if directory already exists
		mkdir -p ${mount_point}/${default_cgroup}
		find ${mount_point}/ -name tasks | xargs  chmod a+rw
		chmod go-w ${mount_point}/tasks

		# Special rule for cpusets
		if echo ${mount_options} | grep -qw cpuset; then
			cat ${mount_point}/cpuset.cpus > ${mount_point}/${default_cgroup}/cpuset.cpus
			cat ${mount_point}/cpuset.mems > ${mount_point}/${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_point}/${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
}