162306a36Sopenharmony_ci#!/bin/bash
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci#
462306a36Sopenharmony_ci# Test for cpuset v2 partition root state (PRS)
562306a36Sopenharmony_ci#
662306a36Sopenharmony_ci# The sched verbose flag is set, if available, so that the console log
762306a36Sopenharmony_ci# can be examined for the correct setting of scheduling domain.
862306a36Sopenharmony_ci#
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciskip_test() {
1162306a36Sopenharmony_ci	echo "$1"
1262306a36Sopenharmony_ci	echo "Test SKIPPED"
1362306a36Sopenharmony_ci	exit 4 # ksft_skip
1462306a36Sopenharmony_ci}
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci[[ $(id -u) -eq 0 ]] || skip_test "Test must be run as root!"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci# Get wait_inotify location
2062306a36Sopenharmony_ciWAIT_INOTIFY=$(cd $(dirname $0); pwd)/wait_inotify
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci# Find cgroup v2 mount point
2362306a36Sopenharmony_ciCGROUP2=$(mount -t cgroup2 | head -1 | awk -e '{print $3}')
2462306a36Sopenharmony_ci[[ -n "$CGROUP2" ]] || skip_test "Cgroup v2 mount point not found!"
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciCPUS=$(lscpu | grep "^CPU(s):" | sed -e "s/.*:[[:space:]]*//")
2762306a36Sopenharmony_ci[[ $CPUS -lt 8 ]] && skip_test "Test needs at least 8 cpus available!"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci# Set verbose flag and delay factor
3062306a36Sopenharmony_ciPROG=$1
3162306a36Sopenharmony_ciVERBOSE=
3262306a36Sopenharmony_ciDELAY_FACTOR=1
3362306a36Sopenharmony_ciSCHED_DEBUG=
3462306a36Sopenharmony_ciwhile [[ "$1" = -* ]]
3562306a36Sopenharmony_cido
3662306a36Sopenharmony_ci	case "$1" in
3762306a36Sopenharmony_ci		-v) VERBOSE=1
3862306a36Sopenharmony_ci		    # Enable sched/verbose can slow thing down
3962306a36Sopenharmony_ci		    [[ $DELAY_FACTOR -eq 1 ]] &&
4062306a36Sopenharmony_ci			DELAY_FACTOR=2
4162306a36Sopenharmony_ci		    break
4262306a36Sopenharmony_ci		    ;;
4362306a36Sopenharmony_ci		-d) DELAY_FACTOR=$2
4462306a36Sopenharmony_ci		    shift
4562306a36Sopenharmony_ci		    break
4662306a36Sopenharmony_ci		    ;;
4762306a36Sopenharmony_ci		*)  echo "Usage: $PROG [-v] [-d <delay-factor>"
4862306a36Sopenharmony_ci		    exit
4962306a36Sopenharmony_ci		    ;;
5062306a36Sopenharmony_ci	esac
5162306a36Sopenharmony_ci	shift
5262306a36Sopenharmony_cidone
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci# Set sched verbose flag if available when "-v" option is specified
5562306a36Sopenharmony_ciif [[ -n "$VERBOSE" && -d /sys/kernel/debug/sched ]]
5662306a36Sopenharmony_cithen
5762306a36Sopenharmony_ci	# Used to restore the original setting during cleanup
5862306a36Sopenharmony_ci	SCHED_DEBUG=$(cat /sys/kernel/debug/sched/verbose)
5962306a36Sopenharmony_ci	echo Y > /sys/kernel/debug/sched/verbose
6062306a36Sopenharmony_cifi
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cicd $CGROUP2
6362306a36Sopenharmony_ciecho +cpuset > cgroup.subtree_control
6462306a36Sopenharmony_ci[[ -d test ]] || mkdir test
6562306a36Sopenharmony_cicd test
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cicleanup()
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	online_cpus
7062306a36Sopenharmony_ci	rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
7162306a36Sopenharmony_ci	cd ..
7262306a36Sopenharmony_ci	rmdir test > /dev/null 2>&1
7362306a36Sopenharmony_ci	[[ -n "$SCHED_DEBUG" ]] &&
7462306a36Sopenharmony_ci		echo "$SCHED_DEBUG" > /sys/kernel/debug/sched/verbose
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci# Pause in ms
7862306a36Sopenharmony_cipause()
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci	DELAY=$1
8162306a36Sopenharmony_ci	LOOP=0
8262306a36Sopenharmony_ci	while [[ $LOOP -lt $DELAY_FACTOR ]]
8362306a36Sopenharmony_ci	do
8462306a36Sopenharmony_ci		sleep $DELAY
8562306a36Sopenharmony_ci		((LOOP++))
8662306a36Sopenharmony_ci	done
8762306a36Sopenharmony_ci	return 0
8862306a36Sopenharmony_ci}
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ciconsole_msg()
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	MSG=$1
9362306a36Sopenharmony_ci	echo "$MSG"
9462306a36Sopenharmony_ci	echo "" > /dev/console
9562306a36Sopenharmony_ci	echo "$MSG" > /dev/console
9662306a36Sopenharmony_ci	pause 0.01
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_citest_partition()
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	EXPECTED_VAL=$1
10262306a36Sopenharmony_ci	echo $EXPECTED_VAL > cpuset.cpus.partition
10362306a36Sopenharmony_ci	[[ $? -eq 0 ]] || exit 1
10462306a36Sopenharmony_ci	ACTUAL_VAL=$(cat cpuset.cpus.partition)
10562306a36Sopenharmony_ci	[[ $ACTUAL_VAL != $EXPECTED_VAL ]] && {
10662306a36Sopenharmony_ci		echo "cpuset.cpus.partition: expect $EXPECTED_VAL, found $EXPECTED_VAL"
10762306a36Sopenharmony_ci		echo "Test FAILED"
10862306a36Sopenharmony_ci		exit 1
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_citest_effective_cpus()
11362306a36Sopenharmony_ci{
11462306a36Sopenharmony_ci	EXPECTED_VAL=$1
11562306a36Sopenharmony_ci	ACTUAL_VAL=$(cat cpuset.cpus.effective)
11662306a36Sopenharmony_ci	[[ "$ACTUAL_VAL" != "$EXPECTED_VAL" ]] && {
11762306a36Sopenharmony_ci		echo "cpuset.cpus.effective: expect '$EXPECTED_VAL', found '$EXPECTED_VAL'"
11862306a36Sopenharmony_ci		echo "Test FAILED"
11962306a36Sopenharmony_ci		exit 1
12062306a36Sopenharmony_ci	}
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci# Adding current process to cgroup.procs as a test
12462306a36Sopenharmony_citest_add_proc()
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	OUTSTR="$1"
12762306a36Sopenharmony_ci	ERRMSG=$((echo $$ > cgroup.procs) |& cat)
12862306a36Sopenharmony_ci	echo $ERRMSG | grep -q "$OUTSTR"
12962306a36Sopenharmony_ci	[[ $? -ne 0 ]] && {
13062306a36Sopenharmony_ci		echo "cgroup.procs: expect '$OUTSTR', got '$ERRMSG'"
13162306a36Sopenharmony_ci		echo "Test FAILED"
13262306a36Sopenharmony_ci		exit 1
13362306a36Sopenharmony_ci	}
13462306a36Sopenharmony_ci	echo $$ > $CGROUP2/cgroup.procs	# Move out the task
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#
13862306a36Sopenharmony_ci# Testing the new "isolated" partition root type
13962306a36Sopenharmony_ci#
14062306a36Sopenharmony_citest_isolated()
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	echo 2-3 > cpuset.cpus
14362306a36Sopenharmony_ci	TYPE=$(cat cpuset.cpus.partition)
14462306a36Sopenharmony_ci	[[ $TYPE = member ]] || echo member > cpuset.cpus.partition
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	console_msg "Change from member to root"
14762306a36Sopenharmony_ci	test_partition root
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	console_msg "Change from root to isolated"
15062306a36Sopenharmony_ci	test_partition isolated
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	console_msg "Change from isolated to member"
15362306a36Sopenharmony_ci	test_partition member
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	console_msg "Change from member to isolated"
15662306a36Sopenharmony_ci	test_partition isolated
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	console_msg "Change from isolated to root"
15962306a36Sopenharmony_ci	test_partition root
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	console_msg "Change from root to member"
16262306a36Sopenharmony_ci	test_partition member
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	#
16562306a36Sopenharmony_ci	# Testing partition root with no cpu
16662306a36Sopenharmony_ci	#
16762306a36Sopenharmony_ci	console_msg "Distribute all cpus to child partition"
16862306a36Sopenharmony_ci	echo +cpuset > cgroup.subtree_control
16962306a36Sopenharmony_ci	test_partition root
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	mkdir A1
17262306a36Sopenharmony_ci	cd A1
17362306a36Sopenharmony_ci	echo 2-3 > cpuset.cpus
17462306a36Sopenharmony_ci	test_partition root
17562306a36Sopenharmony_ci	test_effective_cpus 2-3
17662306a36Sopenharmony_ci	cd ..
17762306a36Sopenharmony_ci	test_effective_cpus ""
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	console_msg "Moving task to partition test"
18062306a36Sopenharmony_ci	test_add_proc "No space left"
18162306a36Sopenharmony_ci	cd A1
18262306a36Sopenharmony_ci	test_add_proc ""
18362306a36Sopenharmony_ci	cd ..
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	console_msg "Shrink and expand child partition"
18662306a36Sopenharmony_ci	cd A1
18762306a36Sopenharmony_ci	echo 2 > cpuset.cpus
18862306a36Sopenharmony_ci	cd ..
18962306a36Sopenharmony_ci	test_effective_cpus 3
19062306a36Sopenharmony_ci	cd A1
19162306a36Sopenharmony_ci	echo 2-3 > cpuset.cpus
19262306a36Sopenharmony_ci	cd ..
19362306a36Sopenharmony_ci	test_effective_cpus ""
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	# Cleaning up
19662306a36Sopenharmony_ci	console_msg "Cleaning up"
19762306a36Sopenharmony_ci	echo $$ > $CGROUP2/cgroup.procs
19862306a36Sopenharmony_ci	[[ -d A1 ]] && rmdir A1
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci#
20262306a36Sopenharmony_ci# Cpuset controller state transition test matrix.
20362306a36Sopenharmony_ci#
20462306a36Sopenharmony_ci# Cgroup test hierarchy
20562306a36Sopenharmony_ci#
20662306a36Sopenharmony_ci# test -- A1 -- A2 -- A3
20762306a36Sopenharmony_ci#      \- B1
20862306a36Sopenharmony_ci#
20962306a36Sopenharmony_ci#  P<v> = set cpus.partition (0:member, 1:root, 2:isolated, -1:root invalid)
21062306a36Sopenharmony_ci#  C<l> = add cpu-list
21162306a36Sopenharmony_ci#  S<p> = use prefix in subtree_control
21262306a36Sopenharmony_ci#  T    = put a task into cgroup
21362306a36Sopenharmony_ci#  O<c>-<v> = Write <v> to CPU online file of <c>
21462306a36Sopenharmony_ci#
21562306a36Sopenharmony_ciSETUP_A123_PARTITIONS="C1-3:P1:S+ C2-3:P1:S+ C3:P1"
21662306a36Sopenharmony_ciTEST_MATRIX=(
21762306a36Sopenharmony_ci	# test  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate
21862306a36Sopenharmony_ci	# ----  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------
21962306a36Sopenharmony_ci	"  S+    C0-1     .      .    C2-3    S+    C4-5     .      .     0 A2:0-1"
22062306a36Sopenharmony_ci	"  S+    C0-1     .      .    C2-3    P1      .      .      .     0 "
22162306a36Sopenharmony_ci	"  S+    C0-1     .      .    C2-3   P1:S+ C0-1:P1   .      .     0 "
22262306a36Sopenharmony_ci	"  S+    C0-1     .      .    C2-3   P1:S+  C1:P1    .      .     0 "
22362306a36Sopenharmony_ci	"  S+   C0-1:S+   .      .    C2-3     .      .      .     P1     0 "
22462306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .    C2-3    S+     C1      .      .     0 "
22562306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .    C2-3    S+    C1:P1    .      .     0 "
22662306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .    C2-3    S+    C1:P1    .     P1     0 "
22762306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .    C2-3   C4-5     .      .      .     0 A1:4-5"
22862306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .    C2-3  S+:C4-5   .      .      .     0 A1:4-5"
22962306a36Sopenharmony_ci	"  S+    C0-1     .      .   C2-3:P1   .      .      .     C2     0 "
23062306a36Sopenharmony_ci	"  S+    C0-1     .      .   C2-3:P1   .      .      .    C4-5    0 B1:4-5"
23162306a36Sopenharmony_ci	"  S+ C0-3:P1:S+ C2-3:P1 .      .      .      .      .      .     0 A1:0-1,A2:2-3"
23262306a36Sopenharmony_ci	"  S+ C0-3:P1:S+ C2-3:P1 .      .     C1-3    .      .      .     0 A1:1,A2:2-3"
23362306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .     C3      .      .      .     0 A1:,A2:3 A1:P1,A2:P1"
23462306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .     C3      P0     .      .     0 A1:3,A2:3 A1:P1,A2:P0"
23562306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C2:P1  .      .     C2-4    .      .      .     0 A1:3-4,A2:2"
23662306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .     C3      .      .     C0-2   0 A1:,B1:0-2 A1:P1,A2:P1"
23762306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .     C2-3    .      .      .     0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	# CPU offlining cases:
24062306a36Sopenharmony_ci	"  S+    C0-1     .      .    C2-3    S+    C4-5     .     O2-0   0 A1:0-1,B1:3"
24162306a36Sopenharmony_ci	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O2-0    .      .      .     0 A1:0-1,A2:3"
24262306a36Sopenharmony_ci	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O2-0   O2-1    .      .     0 A1:0-1,A2:2-3"
24362306a36Sopenharmony_ci	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O1-0    .      .      .     0 A1:0,A2:2-3"
24462306a36Sopenharmony_ci	"  S+ C0-3:P1:S+ C2-3:P1 .      .     O1-0   O1-1    .      .     0 A1:0-1,A2:2-3"
24562306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .     O3-0   O3-1    .      .     0 A1:2,A2:3 A1:P1,A2:P1"
24662306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P2  .      .     O3-0   O3-1    .      .     0 A1:2,A2:3 A1:P1,A2:P2"
24762306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .     O2-0   O2-1    .      .     0 A1:2,A2:3 A1:P1,A2:P1"
24862306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P2  .      .     O2-0   O2-1    .      .     0 A1:2,A2:3 A1:P1,A2:P2"
24962306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .     O2-0    .      .      .     0 A1:,A2:3 A1:P1,A2:P1"
25062306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .     O3-0    .      .      .     0 A1:2,A2: A1:P1,A2:P1"
25162306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .    T:O2-0   .      .      .     0 A1:3,A2:3 A1:P1,A2:P-1"
25262306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .      .    T:O3-0   .      .     0 A1:2,A2:2 A1:P1,A2:P-1"
25362306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .     O1-0    .      .      .     0 A1:,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
25462306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .     O2-0    .      .      .     0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1"
25562306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .     O3-0    .      .      .     0 A1:1,A2:2,A3: A1:P1,A2:P1,A3:P1"
25662306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .    T:O1-0   .      .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
25762306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .      .    T:O2-0   .      .     0 A1:1,A2:3,A3:3 A1:P1,A2:P1,A3:P-1"
25862306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .      .      .    T:O3-0   .     0 A1:1,A2:2,A3:2 A1:P1,A2:P1,A3:P-1"
25962306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .    T:O1-0  O1-1    .      .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
26062306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .      .    T:O2-0  O2-1    .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
26162306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .      .      .    T:O3-0  O3-1   0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
26262306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .    T:O1-0  O2-0   O1-1    .     0 A1:1,A2:,A3:3 A1:P1,A2:P1,A3:P1"
26362306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .    T:O1-0  O2-0   O2-1    .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	# test  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate
26662306a36Sopenharmony_ci	# ----  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------
26762306a36Sopenharmony_ci	#
26862306a36Sopenharmony_ci	# Incorrect change to cpuset.cpus invalidates partition root
26962306a36Sopenharmony_ci	#
27062306a36Sopenharmony_ci	# Adding CPUs to partition root that are not in parent's
27162306a36Sopenharmony_ci	# cpuset.cpus is allowed, but those extra CPUs are ignored.
27262306a36Sopenharmony_ci	"  S+ C2-3:P1:S+ C3:P1   .      .      .     C2-4    .      .     0 A1:,A2:2-3 A1:P1,A2:P1"
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	# Taking away all CPUs from parent or itself if there are tasks
27562306a36Sopenharmony_ci	# will make the partition invalid.
27662306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .      T     C2-3    .      .     0 A1:2-3,A2:2-3 A1:P1,A2:P-1"
27762306a36Sopenharmony_ci	"  S+  C3:P1:S+    C3    .      .      T      P1     .      .     0 A1:3,A2:3 A1:P1,A2:P-1"
27862306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .    T:C2-3   .      .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
27962306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    . T:C2-3:C1-3 .      .      .     0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	# Changing a partition root to member makes child partitions invalid
28262306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .      P0     .      .      .     0 A1:2-3,A2:3 A1:P0,A2:P-1"
28362306a36Sopenharmony_ci	"  S+ $SETUP_A123_PARTITIONS    .     C2-3    P0     .      .     0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P0,A3:P-1"
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	# cpuset.cpus can contains cpus not in parent's cpuset.cpus as long
28662306a36Sopenharmony_ci	# as they overlap.
28762306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  .      .      .      .   C3-4:P1   .      .     0 A1:2,A2:3 A1:P1,A2:P1"
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	# Deletion of CPUs distributed to child cgroup is allowed.
29062306a36Sopenharmony_ci	"  S+ C0-1:P1:S+ C1      .    C2-3   C4-5     .      .      .     0 A1:4-5,A2:4-5"
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	# To become a valid partition root, cpuset.cpus must overlap parent's
29362306a36Sopenharmony_ci	# cpuset.cpus.
29462306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .    C2-3    S+   C4-5:P1   .      .     0 A1:0-1,A2:0-1 A1:P1,A2:P-1"
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	# Enabling partition with child cpusets is allowed
29762306a36Sopenharmony_ci	"  S+   C0-1:S+  C1      .    C2-3    P1      .      .      .     0 A1:0-1,A2:1 A1:P1"
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	# A partition root with non-partition root parent is invalid, but it
30062306a36Sopenharmony_ci	# can be made valid if its parent becomes a partition root too.
30162306a36Sopenharmony_ci	"  S+   C0-1:S+  C1      .    C2-3     .      P2     .      .     0 A1:0-1,A2:1 A1:P0,A2:P-2"
30262306a36Sopenharmony_ci	"  S+   C0-1:S+ C1:P2    .    C2-3     P1     .      .      .     0 A1:0,A2:1 A1:P1,A2:P2"
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	# A non-exclusive cpuset.cpus change will invalidate partition and its siblings
30562306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .    C2-3   C0-2     .      .      .     0 A1:0-2,B1:2-3 A1:P-1,B1:P0"
30662306a36Sopenharmony_ci	"  S+   C0-1:P1   .      .  P1:C2-3  C0-2   .      .      .     0 A1:0-2,B1:2-3 A1:P-1,B1:P-1"
30762306a36Sopenharmony_ci	"  S+    C0-1     .      .  P1:C2-3  C0-2   .      .      .     0 A1:0-2,B1:2-3 A1:P0,B1:P-1"
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	# test  old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate
31062306a36Sopenharmony_ci	# ----  ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------
31162306a36Sopenharmony_ci	# Failure cases:
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	# A task cannot be added to a partition with no cpu
31462306a36Sopenharmony_ci	"  S+ C2-3:P1:S+  C3:P1  .      .    O2-0:T   .      .      .     1 A1:,A2:3 A1:P1,A2:P1"
31562306a36Sopenharmony_ci)
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci#
31862306a36Sopenharmony_ci# Write to the cpu online file
31962306a36Sopenharmony_ci#  $1 - <c>-<v> where <c> = cpu number, <v> value to be written
32062306a36Sopenharmony_ci#
32162306a36Sopenharmony_ciwrite_cpu_online()
32262306a36Sopenharmony_ci{
32362306a36Sopenharmony_ci	CPU=${1%-*}
32462306a36Sopenharmony_ci	VAL=${1#*-}
32562306a36Sopenharmony_ci	CPUFILE=//sys/devices/system/cpu/cpu${CPU}/online
32662306a36Sopenharmony_ci	if [[ $VAL -eq 0 ]]
32762306a36Sopenharmony_ci	then
32862306a36Sopenharmony_ci		OFFLINE_CPUS="$OFFLINE_CPUS $CPU"
32962306a36Sopenharmony_ci	else
33062306a36Sopenharmony_ci		[[ -n "$OFFLINE_CPUS" ]] && {
33162306a36Sopenharmony_ci			OFFLINE_CPUS=$(echo $CPU $CPU $OFFLINE_CPUS | fmt -1 |\
33262306a36Sopenharmony_ci					sort | uniq -u)
33362306a36Sopenharmony_ci		}
33462306a36Sopenharmony_ci	fi
33562306a36Sopenharmony_ci	echo $VAL > $CPUFILE
33662306a36Sopenharmony_ci	pause 0.01
33762306a36Sopenharmony_ci}
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci#
34062306a36Sopenharmony_ci# Set controller state
34162306a36Sopenharmony_ci#  $1 - cgroup directory
34262306a36Sopenharmony_ci#  $2 - state
34362306a36Sopenharmony_ci#  $3 - showerr
34462306a36Sopenharmony_ci#
34562306a36Sopenharmony_ci# The presence of ":" in state means transition from one to the next.
34662306a36Sopenharmony_ci#
34762306a36Sopenharmony_ciset_ctrl_state()
34862306a36Sopenharmony_ci{
34962306a36Sopenharmony_ci	TMPMSG=/tmp/.msg_$$
35062306a36Sopenharmony_ci	CGRP=$1
35162306a36Sopenharmony_ci	STATE=$2
35262306a36Sopenharmony_ci	SHOWERR=${3}${VERBOSE}
35362306a36Sopenharmony_ci	CTRL=${CTRL:=$CONTROLLER}
35462306a36Sopenharmony_ci	HASERR=0
35562306a36Sopenharmony_ci	REDIRECT="2> $TMPMSG"
35662306a36Sopenharmony_ci	[[ -z "$STATE" || "$STATE" = '.' ]] && return 0
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	rm -f $TMPMSG
35962306a36Sopenharmony_ci	for CMD in $(echo $STATE | sed -e "s/:/ /g")
36062306a36Sopenharmony_ci	do
36162306a36Sopenharmony_ci		TFILE=$CGRP/cgroup.procs
36262306a36Sopenharmony_ci		SFILE=$CGRP/cgroup.subtree_control
36362306a36Sopenharmony_ci		PFILE=$CGRP/cpuset.cpus.partition
36462306a36Sopenharmony_ci		CFILE=$CGRP/cpuset.cpus
36562306a36Sopenharmony_ci		S=$(expr substr $CMD 1 1)
36662306a36Sopenharmony_ci		if [[ $S = S ]]
36762306a36Sopenharmony_ci		then
36862306a36Sopenharmony_ci			PREFIX=${CMD#?}
36962306a36Sopenharmony_ci			COMM="echo ${PREFIX}${CTRL} > $SFILE"
37062306a36Sopenharmony_ci			eval $COMM $REDIRECT
37162306a36Sopenharmony_ci		elif [[ $S = C ]]
37262306a36Sopenharmony_ci		then
37362306a36Sopenharmony_ci			CPUS=${CMD#?}
37462306a36Sopenharmony_ci			COMM="echo $CPUS > $CFILE"
37562306a36Sopenharmony_ci			eval $COMM $REDIRECT
37662306a36Sopenharmony_ci		elif [[ $S = P ]]
37762306a36Sopenharmony_ci		then
37862306a36Sopenharmony_ci			VAL=${CMD#?}
37962306a36Sopenharmony_ci			case $VAL in
38062306a36Sopenharmony_ci			0)  VAL=member
38162306a36Sopenharmony_ci			    ;;
38262306a36Sopenharmony_ci			1)  VAL=root
38362306a36Sopenharmony_ci			    ;;
38462306a36Sopenharmony_ci			2)  VAL=isolated
38562306a36Sopenharmony_ci			    ;;
38662306a36Sopenharmony_ci			*)
38762306a36Sopenharmony_ci			    echo "Invalid partition state - $VAL"
38862306a36Sopenharmony_ci			    exit 1
38962306a36Sopenharmony_ci			    ;;
39062306a36Sopenharmony_ci			esac
39162306a36Sopenharmony_ci			COMM="echo $VAL > $PFILE"
39262306a36Sopenharmony_ci			eval $COMM $REDIRECT
39362306a36Sopenharmony_ci		elif [[ $S = O ]]
39462306a36Sopenharmony_ci		then
39562306a36Sopenharmony_ci			VAL=${CMD#?}
39662306a36Sopenharmony_ci			write_cpu_online $VAL
39762306a36Sopenharmony_ci		elif [[ $S = T ]]
39862306a36Sopenharmony_ci		then
39962306a36Sopenharmony_ci			COMM="echo 0 > $TFILE"
40062306a36Sopenharmony_ci			eval $COMM $REDIRECT
40162306a36Sopenharmony_ci		fi
40262306a36Sopenharmony_ci		RET=$?
40362306a36Sopenharmony_ci		[[ $RET -ne 0 ]] && {
40462306a36Sopenharmony_ci			[[ -n "$SHOWERR" ]] && {
40562306a36Sopenharmony_ci				echo "$COMM"
40662306a36Sopenharmony_ci				cat $TMPMSG
40762306a36Sopenharmony_ci			}
40862306a36Sopenharmony_ci			HASERR=1
40962306a36Sopenharmony_ci		}
41062306a36Sopenharmony_ci		pause 0.01
41162306a36Sopenharmony_ci		rm -f $TMPMSG
41262306a36Sopenharmony_ci	done
41362306a36Sopenharmony_ci	return $HASERR
41462306a36Sopenharmony_ci}
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ciset_ctrl_state_noerr()
41762306a36Sopenharmony_ci{
41862306a36Sopenharmony_ci	CGRP=$1
41962306a36Sopenharmony_ci	STATE=$2
42062306a36Sopenharmony_ci	[[ -d $CGRP ]] || mkdir $CGRP
42162306a36Sopenharmony_ci	set_ctrl_state $CGRP $STATE 1
42262306a36Sopenharmony_ci	[[ $? -ne 0 ]] && {
42362306a36Sopenharmony_ci		echo "ERROR: Failed to set $2 to cgroup $1!"
42462306a36Sopenharmony_ci		exit 1
42562306a36Sopenharmony_ci	}
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cionline_cpus()
42962306a36Sopenharmony_ci{
43062306a36Sopenharmony_ci	[[ -n "OFFLINE_CPUS" ]] && {
43162306a36Sopenharmony_ci		for C in $OFFLINE_CPUS
43262306a36Sopenharmony_ci		do
43362306a36Sopenharmony_ci			write_cpu_online ${C}-1
43462306a36Sopenharmony_ci		done
43562306a36Sopenharmony_ci	}
43662306a36Sopenharmony_ci}
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci#
43962306a36Sopenharmony_ci# Return 1 if the list of effective cpus isn't the same as the initial list.
44062306a36Sopenharmony_ci#
44162306a36Sopenharmony_cireset_cgroup_states()
44262306a36Sopenharmony_ci{
44362306a36Sopenharmony_ci	echo 0 > $CGROUP2/cgroup.procs
44462306a36Sopenharmony_ci	online_cpus
44562306a36Sopenharmony_ci	rmdir A1/A2/A3 A1/A2 A1 B1 > /dev/null 2>&1
44662306a36Sopenharmony_ci	set_ctrl_state . S-
44762306a36Sopenharmony_ci	pause 0.01
44862306a36Sopenharmony_ci}
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_cidump_states()
45162306a36Sopenharmony_ci{
45262306a36Sopenharmony_ci	for DIR in A1 A1/A2 A1/A2/A3 B1
45362306a36Sopenharmony_ci	do
45462306a36Sopenharmony_ci		ECPUS=$DIR/cpuset.cpus.effective
45562306a36Sopenharmony_ci		PRS=$DIR/cpuset.cpus.partition
45662306a36Sopenharmony_ci		[[ -e $ECPUS ]] && echo "$ECPUS: $(cat $ECPUS)"
45762306a36Sopenharmony_ci		[[ -e $PRS   ]] && echo "$PRS: $(cat $PRS)"
45862306a36Sopenharmony_ci	done
45962306a36Sopenharmony_ci}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci#
46262306a36Sopenharmony_ci# Check effective cpus
46362306a36Sopenharmony_ci# $1 - check string, format: <cgroup>:<cpu-list>[,<cgroup>:<cpu-list>]*
46462306a36Sopenharmony_ci#
46562306a36Sopenharmony_cicheck_effective_cpus()
46662306a36Sopenharmony_ci{
46762306a36Sopenharmony_ci	CHK_STR=$1
46862306a36Sopenharmony_ci	for CHK in $(echo $CHK_STR | sed -e "s/,/ /g")
46962306a36Sopenharmony_ci	do
47062306a36Sopenharmony_ci		set -- $(echo $CHK | sed -e "s/:/ /g")
47162306a36Sopenharmony_ci		CGRP=$1
47262306a36Sopenharmony_ci		CPUS=$2
47362306a36Sopenharmony_ci		[[ $CGRP = A2 ]] && CGRP=A1/A2
47462306a36Sopenharmony_ci		[[ $CGRP = A3 ]] && CGRP=A1/A2/A3
47562306a36Sopenharmony_ci		FILE=$CGRP/cpuset.cpus.effective
47662306a36Sopenharmony_ci		[[ -e $FILE ]] || return 1
47762306a36Sopenharmony_ci		[[ $CPUS = $(cat $FILE) ]] || return 1
47862306a36Sopenharmony_ci	done
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci#
48262306a36Sopenharmony_ci# Check cgroup states
48362306a36Sopenharmony_ci#  $1 - check string, format: <cgroup>:<state>[,<cgroup>:<state>]*
48462306a36Sopenharmony_ci#
48562306a36Sopenharmony_cicheck_cgroup_states()
48662306a36Sopenharmony_ci{
48762306a36Sopenharmony_ci	CHK_STR=$1
48862306a36Sopenharmony_ci	for CHK in $(echo $CHK_STR | sed -e "s/,/ /g")
48962306a36Sopenharmony_ci	do
49062306a36Sopenharmony_ci		set -- $(echo $CHK | sed -e "s/:/ /g")
49162306a36Sopenharmony_ci		CGRP=$1
49262306a36Sopenharmony_ci		STATE=$2
49362306a36Sopenharmony_ci		FILE=
49462306a36Sopenharmony_ci		EVAL=$(expr substr $STATE 2 2)
49562306a36Sopenharmony_ci		[[ $CGRP = A2 ]] && CGRP=A1/A2
49662306a36Sopenharmony_ci		[[ $CGRP = A3 ]] && CGRP=A1/A2/A3
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci		case $STATE in
49962306a36Sopenharmony_ci			P*) FILE=$CGRP/cpuset.cpus.partition
50062306a36Sopenharmony_ci			    ;;
50162306a36Sopenharmony_ci			*)  echo "Unknown state: $STATE!"
50262306a36Sopenharmony_ci			    exit 1
50362306a36Sopenharmony_ci			    ;;
50462306a36Sopenharmony_ci		esac
50562306a36Sopenharmony_ci		VAL=$(cat $FILE)
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci		case "$VAL" in
50862306a36Sopenharmony_ci			member) VAL=0
50962306a36Sopenharmony_ci				;;
51062306a36Sopenharmony_ci			root)	VAL=1
51162306a36Sopenharmony_ci				;;
51262306a36Sopenharmony_ci			isolated)
51362306a36Sopenharmony_ci				VAL=2
51462306a36Sopenharmony_ci				;;
51562306a36Sopenharmony_ci			"root invalid"*)
51662306a36Sopenharmony_ci				VAL=-1
51762306a36Sopenharmony_ci				;;
51862306a36Sopenharmony_ci			"isolated invalid"*)
51962306a36Sopenharmony_ci				VAL=-2
52062306a36Sopenharmony_ci				;;
52162306a36Sopenharmony_ci		esac
52262306a36Sopenharmony_ci		[[ $EVAL != $VAL ]] && return 1
52362306a36Sopenharmony_ci	done
52462306a36Sopenharmony_ci	return 0
52562306a36Sopenharmony_ci}
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci#
52862306a36Sopenharmony_ci# Run cpuset state transition test
52962306a36Sopenharmony_ci#  $1 - test matrix name
53062306a36Sopenharmony_ci#
53162306a36Sopenharmony_ci# This test is somewhat fragile as delays (sleep x) are added in various
53262306a36Sopenharmony_ci# places to make sure state changes are fully propagated before the next
53362306a36Sopenharmony_ci# action. These delays may need to be adjusted if running in a slower machine.
53462306a36Sopenharmony_ci#
53562306a36Sopenharmony_cirun_state_test()
53662306a36Sopenharmony_ci{
53762306a36Sopenharmony_ci	TEST=$1
53862306a36Sopenharmony_ci	CONTROLLER=cpuset
53962306a36Sopenharmony_ci	CPULIST=0-6
54062306a36Sopenharmony_ci	I=0
54162306a36Sopenharmony_ci	eval CNT="\${#$TEST[@]}"
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci	reset_cgroup_states
54462306a36Sopenharmony_ci	echo $CPULIST > cpuset.cpus
54562306a36Sopenharmony_ci	echo root > cpuset.cpus.partition
54662306a36Sopenharmony_ci	console_msg "Running state transition test ..."
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	while [[ $I -lt $CNT ]]
54962306a36Sopenharmony_ci	do
55062306a36Sopenharmony_ci		echo "Running test $I ..." > /dev/console
55162306a36Sopenharmony_ci		eval set -- "\${$TEST[$I]}"
55262306a36Sopenharmony_ci		ROOT=$1
55362306a36Sopenharmony_ci		OLD_A1=$2
55462306a36Sopenharmony_ci		OLD_A2=$3
55562306a36Sopenharmony_ci		OLD_A3=$4
55662306a36Sopenharmony_ci		OLD_B1=$5
55762306a36Sopenharmony_ci		NEW_A1=$6
55862306a36Sopenharmony_ci		NEW_A2=$7
55962306a36Sopenharmony_ci		NEW_A3=$8
56062306a36Sopenharmony_ci		NEW_B1=$9
56162306a36Sopenharmony_ci		RESULT=${10}
56262306a36Sopenharmony_ci		ECPUS=${11}
56362306a36Sopenharmony_ci		STATES=${12}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci		set_ctrl_state_noerr .        $ROOT
56662306a36Sopenharmony_ci		set_ctrl_state_noerr A1       $OLD_A1
56762306a36Sopenharmony_ci		set_ctrl_state_noerr A1/A2    $OLD_A2
56862306a36Sopenharmony_ci		set_ctrl_state_noerr A1/A2/A3 $OLD_A3
56962306a36Sopenharmony_ci		set_ctrl_state_noerr B1       $OLD_B1
57062306a36Sopenharmony_ci		RETVAL=0
57162306a36Sopenharmony_ci		set_ctrl_state A1       $NEW_A1; ((RETVAL += $?))
57262306a36Sopenharmony_ci		set_ctrl_state A1/A2    $NEW_A2; ((RETVAL += $?))
57362306a36Sopenharmony_ci		set_ctrl_state A1/A2/A3 $NEW_A3; ((RETVAL += $?))
57462306a36Sopenharmony_ci		set_ctrl_state B1       $NEW_B1; ((RETVAL += $?))
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci		[[ $RETVAL -ne $RESULT ]] && {
57762306a36Sopenharmony_ci			echo "Test $TEST[$I] failed result check!"
57862306a36Sopenharmony_ci			eval echo \"\${$TEST[$I]}\"
57962306a36Sopenharmony_ci			dump_states
58062306a36Sopenharmony_ci			exit 1
58162306a36Sopenharmony_ci		}
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci		[[ -n "$ECPUS" && "$ECPUS" != . ]] && {
58462306a36Sopenharmony_ci			check_effective_cpus $ECPUS
58562306a36Sopenharmony_ci			[[ $? -ne 0 ]] && {
58662306a36Sopenharmony_ci				echo "Test $TEST[$I] failed effective CPU check!"
58762306a36Sopenharmony_ci				eval echo \"\${$TEST[$I]}\"
58862306a36Sopenharmony_ci				echo
58962306a36Sopenharmony_ci				dump_states
59062306a36Sopenharmony_ci				exit 1
59162306a36Sopenharmony_ci			}
59262306a36Sopenharmony_ci		}
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci		[[ -n "$STATES" ]] && {
59562306a36Sopenharmony_ci			check_cgroup_states $STATES
59662306a36Sopenharmony_ci			[[ $? -ne 0 ]] && {
59762306a36Sopenharmony_ci				echo "FAILED: Test $TEST[$I] failed states check!"
59862306a36Sopenharmony_ci				eval echo \"\${$TEST[$I]}\"
59962306a36Sopenharmony_ci				echo
60062306a36Sopenharmony_ci				dump_states
60162306a36Sopenharmony_ci				exit 1
60262306a36Sopenharmony_ci			}
60362306a36Sopenharmony_ci		}
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci		reset_cgroup_states
60662306a36Sopenharmony_ci		#
60762306a36Sopenharmony_ci		# Check to see if effective cpu list changes
60862306a36Sopenharmony_ci		#
60962306a36Sopenharmony_ci		pause 0.05
61062306a36Sopenharmony_ci		NEWLIST=$(cat cpuset.cpus.effective)
61162306a36Sopenharmony_ci		[[ $NEWLIST != $CPULIST ]] && {
61262306a36Sopenharmony_ci			echo "Effective cpus changed to $NEWLIST after test $I!"
61362306a36Sopenharmony_ci			exit 1
61462306a36Sopenharmony_ci		}
61562306a36Sopenharmony_ci		[[ -n "$VERBOSE" ]] && echo "Test $I done."
61662306a36Sopenharmony_ci		((I++))
61762306a36Sopenharmony_ci	done
61862306a36Sopenharmony_ci	echo "All $I tests of $TEST PASSED."
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci	echo member > cpuset.cpus.partition
62162306a36Sopenharmony_ci}
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci#
62462306a36Sopenharmony_ci# Wait for inotify event for the given file and read it
62562306a36Sopenharmony_ci# $1: cgroup file to wait for
62662306a36Sopenharmony_ci# $2: file to store the read result
62762306a36Sopenharmony_ci#
62862306a36Sopenharmony_ciwait_inotify()
62962306a36Sopenharmony_ci{
63062306a36Sopenharmony_ci	CGROUP_FILE=$1
63162306a36Sopenharmony_ci	OUTPUT_FILE=$2
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	$WAIT_INOTIFY $CGROUP_FILE
63462306a36Sopenharmony_ci	cat $CGROUP_FILE > $OUTPUT_FILE
63562306a36Sopenharmony_ci}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci#
63862306a36Sopenharmony_ci# Test if inotify events are properly generated when going into and out of
63962306a36Sopenharmony_ci# invalid partition state.
64062306a36Sopenharmony_ci#
64162306a36Sopenharmony_citest_inotify()
64262306a36Sopenharmony_ci{
64362306a36Sopenharmony_ci	ERR=0
64462306a36Sopenharmony_ci	PRS=/tmp/.prs_$$
64562306a36Sopenharmony_ci	[[ -f $WAIT_INOTIFY ]] || {
64662306a36Sopenharmony_ci		echo "wait_inotify not found, inotify test SKIPPED."
64762306a36Sopenharmony_ci		return
64862306a36Sopenharmony_ci	}
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci	pause 0.01
65162306a36Sopenharmony_ci	echo 1 > cpuset.cpus
65262306a36Sopenharmony_ci	echo 0 > cgroup.procs
65362306a36Sopenharmony_ci	echo root > cpuset.cpus.partition
65462306a36Sopenharmony_ci	pause 0.01
65562306a36Sopenharmony_ci	rm -f $PRS
65662306a36Sopenharmony_ci	wait_inotify $PWD/cpuset.cpus.partition $PRS &
65762306a36Sopenharmony_ci	pause 0.01
65862306a36Sopenharmony_ci	set_ctrl_state . "O1-0"
65962306a36Sopenharmony_ci	pause 0.01
66062306a36Sopenharmony_ci	check_cgroup_states ".:P-1"
66162306a36Sopenharmony_ci	if [[ $? -ne 0 ]]
66262306a36Sopenharmony_ci	then
66362306a36Sopenharmony_ci		echo "FAILED: Inotify test - partition not invalid"
66462306a36Sopenharmony_ci		ERR=1
66562306a36Sopenharmony_ci	elif [[ ! -f $PRS ]]
66662306a36Sopenharmony_ci	then
66762306a36Sopenharmony_ci		echo "FAILED: Inotify test - event not generated"
66862306a36Sopenharmony_ci		ERR=1
66962306a36Sopenharmony_ci		kill %1
67062306a36Sopenharmony_ci	elif [[ $(cat $PRS) != "root invalid"* ]]
67162306a36Sopenharmony_ci	then
67262306a36Sopenharmony_ci		echo "FAILED: Inotify test - incorrect state"
67362306a36Sopenharmony_ci		cat $PRS
67462306a36Sopenharmony_ci		ERR=1
67562306a36Sopenharmony_ci	fi
67662306a36Sopenharmony_ci	online_cpus
67762306a36Sopenharmony_ci	echo member > cpuset.cpus.partition
67862306a36Sopenharmony_ci	echo 0 > ../cgroup.procs
67962306a36Sopenharmony_ci	if [[ $ERR -ne 0 ]]
68062306a36Sopenharmony_ci	then
68162306a36Sopenharmony_ci		exit 1
68262306a36Sopenharmony_ci	else
68362306a36Sopenharmony_ci		echo "Inotify test PASSED"
68462306a36Sopenharmony_ci	fi
68562306a36Sopenharmony_ci}
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_citrap cleanup 0 2 3 6
68862306a36Sopenharmony_cirun_state_test TEST_MATRIX
68962306a36Sopenharmony_citest_isolated
69062306a36Sopenharmony_citest_inotify
69162306a36Sopenharmony_ciecho "All tests PASSED."
69262306a36Sopenharmony_cicd ..
69362306a36Sopenharmony_cirmdir test
694