#!/bin/sh
. test.sh
cpu_string="`cat /sys/devices/system/cpu/online`"
NR_CPUS=`tst_ncpus`
if [ -f "/sys/devices/system/node/has_high_memory" ]; then
mem_string="`cat /sys/devices/system/node/has_high_memory`"
else
mem_string="`cat /sys/devices/system/node/has_normal_memory`"
fi
N_NODES="`echo $mem_string | tr ',' ' '`"
count=0
final_node=0
for item in $N_NODES; do
delta=1
if [ "${item#*-*}" != "$item" ]; then
delta=$((${item#*-*} - ${item%*-*} + 1))
fi
final_node=${item#*-*}
count=$((count + $delta))
done
final_node=$((final_node + 1))
N_NODES=$count
final_cpu=0
N_CPUS="`echo $cpu_string | tr ',' ' '`"
for item in $N_CPUS; do
final_cpu=${item#*-*}
done
final_cpu=$((final_cpu + 1))
CPUSET="/dev/cpuset"
CPUSET_TMP="/tmp/cpuset_tmp"
CLONE_CHILDREN="/dev/cpuset/cgroup.clone_children"
CHILDREN_VALUE="0"
HOTPLUG_CPU="1"
SCHED_LB="/dev/cpuset/cpuset.sched_load_balance"
SCHED_LB_VALUE="0"
cpuset_log()
{
tst_resm TINFO "$*"
}
cpuset_log_error()
{
local error_message=
while read error_message
do
cpuset_log "$error_message"
done < "$1"
}
ncpus_check()
{
if [ $NR_CPUS -lt $1 ]; then
tst_brkm TCONF "The total of CPUs is less than $1"
fi
if [ $final_cpu -eq $NR_CPUS ]; then
tst_resm TINFO "CPUs are numbered continuously starting at 0 ($cpu_string)"
else
tst_brkm TCONF "CPUs are not numbered continuously starting at 0 ($cpu_string)"
fi
}
nnodes_check()
{
if [ $N_NODES -lt $1 ]; then
tst_brkm TCONF "The total of nodes is less than $1"
fi
if [ $final_node -eq $N_NODES ]; then
tst_resm TINFO "Nodes are numbered continuously starting at 0 ($mem_string)"
else
tst_brkm TCONF "Nodes are not numbered continuously starting at 0 ($mem_string)"
fi
}
user_check()
{
if [ $(id -u) != 0 ]; then
tst_brkm TCONF "Test must be run as root"
fi
}
cpuset_check()
{
if [ -f /proc/cgroups ]; then
CPUSET_CONTROLLER=`grep -w cpuset /proc/cgroups | cut -f1`
CPUSET_CONTROLLER_VALUE=`grep -w cpuset /proc/cgroups | cut -f4`
if [ "$CPUSET_CONTROLLER" = "cpuset" ] && [ "$CPUSET_CONTROLLER_VALUE" = "1" ]
then
return 0
fi
fi
tst_brkm TCONF "Cpuset is not supported"
}
machine_check()
{
if tst_virt_hyperv; then
tst_brkm TCONF "Microsoft Hyper-V detected, no support for CPU hotplug"
fi
}
check()
{
user_check
cpuset_check
ncpus_check ${1:-2}
nnodes_check ${2:-2}
machine_check
}
setup()
{
if [ -e "$CPUSET" ]
then
tst_resm TWARN "$CPUSET already exist.. overwriting"
cleanup || tst_brkm TFAIL "Can't cleanup... Exiting"
fi
mkdir -p "$CPUSET_TMP"
mkdir "$CPUSET"
mount -t cgroup -o cpuset cpuset "$CPUSET" 2> /dev/null
if [ $? -ne 0 ]; then
cleanup
tst_brkm TCONF "Could not mount cgroup filesystem with cpuset on $CPUSET"
fi
CHILDREN_VALUE="`cat $CLONE_CHILDREN`"
SCHED_LB_VALUE="`cat $SCHED_LB`"
}
cleanup()
{
grep "$CPUSET" /proc/mounts >/dev/null 2>&1 || {
rm -rf "$CPUSET" >/dev/null 2>&1
return 0
}
echo $CHILDREN_VALUE > $CLONE_CHILDREN
echo $SCHED_LB_VALUE > $SCHED_LB
find "$CPUSET" -type d | sort | sed -n '2,$p' | tac | while read -r subdir
do
while read pid
do
/bin/kill -9 $pid > /dev/null 2>&1
if [ $? -ne 0 ]; then
tst_brkm TFAIL "Couldn't kill task - "\
"$pid in the cpuset"
fi
done < "$subdir/tasks"
rmdir "$subdir"
if [ $? -ne 0 ]; then
tst_brkm TFAIL "Couldn't remove subdir - $subdir in the cpuset"
fi
done
umount "$CPUSET"
if [ $? -ne 0 ]; then
tst_brkm TFAIL "Couldn't umount cgroup filesystem with"\
" cpuset on $CPUSET..Exiting test"
fi
rmdir "$CPUSET" > /dev/null 2>&1
rm -rf "$CPUSET_TMP" > /dev/null 2>&1
}
cpuset_set()
{
local path="$1"
mkdir -p "$path"
if [ $? -ne 0 ]; then
return 1
fi
local cpus="$2"
local mems="$3"
local load_balance="$4"
if [ "$path" != "$CPUSET" ]; then
if [ "$cpus" != "-" ]; then
/bin/echo $cpus > $path/cpuset.cpus
if [ $? -ne 0 ]; then
return 1
fi
fi
/bin/echo $mems > $path/cpuset.mems
if [ $? -ne 0 ]; then
return 1
fi
fi
/bin/echo $load_balance > $path/cpuset.sched_load_balance
if [ $? -ne 0 ]; then
return 1
fi
}
cpu_hotplug()
{
if [ "$2" = "online" ]; then
/bin/echo 1 > "/sys/devices/system/cpu/cpu$1/online"
if [ $? -ne 0 ]; then
return 1
fi
elif [ "$2" = "offline" ]; then
/bin/echo 0 > "/sys/devices/system/cpu/cpu$1/online"
if [ $? -ne 0 ]; then
return 1
fi
fi
}
setup_test_environment()
{
if [ "$1" = "online" ]; then
cpu_hotplug $HOTPLUG_CPU offline
if [ $? -ne 0 ]; then
return 1
fi
fi
}
cpu_hotplug_cleanup()
{
local cpus_array="$(seq -s' ' 1 $((NR_CPUS-1)))"
local cpuid=
for cpuid in $cpus_array
do
local file="/sys/devices/system/cpu/cpu$cpuid/online"
local offline="$(cat $file)"
if [ $offline -eq 0 ]; then
cpu_hotplug $cpuid "online"
fi
done
}