mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
d57433fc99
If a system configuration tool such as systemd sets up the io cgroup controller for its own purposes, it's possible that the last line of this test will not be able to remove the io controller from the system configuration. This causes the test to fail even though the inability to tear down systemd should not be considered (in this case) a failure. Change this test to set the "io" component of subtree control back to whatever it was when the test started. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
156 lines
4.1 KiB
Bash
Executable File
156 lines
4.1 KiB
Bash
Executable File
#! /bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (c) 2019 Red Hat, Inc. All Rights Reserved.
|
|
#
|
|
# FS QA Test No. 563
|
|
#
|
|
# This test verifies that cgroup aware writeback properly accounts I/Os in
|
|
# various scenarios. We perform reads/writes from different combinations of
|
|
# cgroups and verify that pages are accounted against the group that brought
|
|
# them into cache.
|
|
#
|
|
|
|
seq=`basename $0`
|
|
seqres=$RESULT_DIR/$seq
|
|
echo "QA output created by $seq"
|
|
|
|
here=`pwd`
|
|
tmp=/tmp/$$
|
|
status=1 # failure is the default!
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
_cleanup()
|
|
{
|
|
cd /
|
|
rm -f $tmp.*
|
|
|
|
echo $$ > $cgdir/cgroup.procs
|
|
rmdir $cgdir/$seq-cg* > /dev/null 2>&1
|
|
umount $SCRATCH_MNT > /dev/null 2>&1
|
|
_destroy_loop_device $LOOP_DEV > /dev/null 2>&1
|
|
}
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/cgroup2
|
|
|
|
# remove previous $seqres.full before test
|
|
rm -f $seqres.full
|
|
|
|
# real QA test starts here
|
|
|
|
# Modify as appropriate.
|
|
_supported_fs generic
|
|
_require_scratch_nocheck
|
|
_require_cgroup2 io
|
|
_require_loop
|
|
|
|
# cgroup v2 writeback is only support on block devices so far
|
|
_require_block_device $SCRATCH_DEV
|
|
|
|
cgdir=$CGROUP2_PATH
|
|
iosize=$((1024 * 1024 * 8))
|
|
|
|
# Check cgroup read/write charges against expected values. Allow for some
|
|
# tolerance as different filesystems seem to account slightly differently.
|
|
check_cg()
|
|
{
|
|
cgroot=$1
|
|
cgname=$(basename $cgroot)
|
|
expectedread=$2
|
|
expectedwrite=$3
|
|
rbytes=0
|
|
wbytes=0
|
|
|
|
iobytes=`cat $cgroot/io.stat | grep $smajor:$sminor`
|
|
if [ $? == 0 ]; then
|
|
rbytes=`echo $iobytes | awk '{ print $2 }' | \
|
|
awk -F = '{ print $2 }'`
|
|
wbytes=`echo $iobytes | awk '{ print $3 }' | \
|
|
awk -F = '{ print $2 }'`
|
|
fi
|
|
|
|
_within_tolerance "read" $rbytes $expectedread 5% -v
|
|
_within_tolerance "write" $wbytes $expectedwrite 5% -v
|
|
}
|
|
|
|
# Move current process to another cgroup.
|
|
switch_cg()
|
|
{
|
|
mkdir -p $1
|
|
echo $$ > $1/cgroup.procs
|
|
}
|
|
|
|
# Reset cgroup state for a new test.
|
|
reset()
|
|
{
|
|
echo $$ > $cgdir/cgroup.procs
|
|
rmdir $cgdir/$seq-cg* > /dev/null 2>&1
|
|
$XFS_IO_PROG -fc "pwrite 0 $iosize" $SCRATCH_MNT/file \
|
|
>> $seqres.full 2>&1
|
|
umount $SCRATCH_MNT || _fail "umount failed"
|
|
_mount $LOOP_DEV $SCRATCH_MNT || _fail "mount failed"
|
|
stat $SCRATCH_MNT/file > /dev/null
|
|
}
|
|
|
|
# cgroup I/O accounting doesn't work on partitions. Use a loop device to rule
|
|
# that out.
|
|
LOOP_DEV=$(_create_loop_device $SCRATCH_DEV)
|
|
smajor=$((0x`stat -L -c %t $LOOP_DEV`))
|
|
sminor=$((0x`stat -L -c %T $LOOP_DEV`))
|
|
|
|
_mkfs_dev $LOOP_DEV >> $seqres.full 2>&1
|
|
_mount $LOOP_DEV $SCRATCH_MNT || _fail "mount failed"
|
|
|
|
drop_io_cgroup=
|
|
grep -q -w io $cgdir/cgroup.subtree_control || drop_io_cgroup=1
|
|
|
|
echo "+io" > $cgdir/cgroup.subtree_control || _fail "subtree control"
|
|
|
|
# Read and write from a single group.
|
|
echo "read/write"
|
|
reset
|
|
switch_cg $cgdir/$seq-cg
|
|
$XFS_IO_PROG -c "pread 0 $iosize" -c "pwrite 0 $iosize" -c fsync \
|
|
$SCRATCH_MNT/file >> $seqres.full 2>&1
|
|
switch_cg $cgdir
|
|
$XFS_IO_PROG -c fsync $SCRATCH_MNT/file
|
|
check_cg $cgdir/$seq-cg $iosize $iosize
|
|
|
|
# Write from one cgroup then read and write from a second. Writes are charged to
|
|
# the first group and nothing to the second.
|
|
echo "write -> read/write"
|
|
reset
|
|
switch_cg $cgdir/$seq-cg
|
|
$XFS_IO_PROG -c "pwrite 0 $iosize" $SCRATCH_MNT/file >> $seqres.full 2>&1
|
|
switch_cg $cgdir/$seq-cg-2
|
|
$XFS_IO_PROG -c "pread 0 $iosize" -c "pwrite 0 $iosize" $SCRATCH_MNT/file \
|
|
>> $seqres.full 2>&1
|
|
switch_cg $cgdir
|
|
$XFS_IO_PROG -c fsync $SCRATCH_MNT/file
|
|
check_cg $cgdir/$seq-cg 0 $iosize
|
|
check_cg $cgdir/$seq-cg-2 0 0
|
|
|
|
# Read from one cgroup, read & write from a second. Both reads and writes are
|
|
# charged to the first group and nothing to the second.
|
|
echo "read -> read/write"
|
|
reset
|
|
switch_cg $cgdir/$seq-cg
|
|
$XFS_IO_PROG -c "pread 0 $iosize" $SCRATCH_MNT/file >> $seqres.full 2>&1
|
|
switch_cg $cgdir/$seq-cg-2
|
|
$XFS_IO_PROG -c "pread 0 $iosize" -c "pwrite 0 $iosize" $SCRATCH_MNT/file \
|
|
>> $seqres.full 2>&1
|
|
switch_cg $cgdir
|
|
$XFS_IO_PROG -c fsync $SCRATCH_MNT/file
|
|
check_cg $cgdir/$seq-cg $iosize $iosize
|
|
check_cg $cgdir/$seq-cg-2 0 0
|
|
|
|
if [ "$drop_io_cgroup" = 1 ]; then
|
|
echo "-io" > $cgdir/cgroup.subtree_control || _fail "subtree control"
|
|
fi
|
|
|
|
# success, all done
|
|
status=0
|
|
exit
|