forked from amir73il/xfstests
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Quotasync may livelock if others tasks generate enough dirty dquots in parallel This test case pefrorm fchown to produce dirty quotas This test known to detect livelock non-journaled quota for kernels prior to v5.4
- Loading branch information
Dmitry Monakhov
committed
Oct 31, 2019
1 parent
b2b1f60
commit b10ad23
Showing
5 changed files
with
205 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// | ||
// Copyright (c) 2019 YANDEX LLC. All Rights Reserved. | ||
// Author: Dmitry Monakhov <dmtrmonakhov@yandex-team.ru> | ||
|
||
#include <unistd.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <time.h> | ||
#include <sys/time.h> | ||
#include <fcntl.h> | ||
#include <limits.h> | ||
|
||
char *progname; | ||
|
||
void usage(void) | ||
{ | ||
printf("Usage %s: [-b uid] [-e uid] [-g] [-P] [-t timeout] FNAME\n", progname); | ||
printf("\t\t -b: begin of uid range\n"); | ||
printf("\t\t -e: length of uid range\n"); | ||
printf("\t\t -g: change group uid\n"); | ||
printf("\t\t -t: loop timeout\n"); | ||
printf("\t\t -P: Do not run chowner loop, only prepare files\n"); | ||
exit(1); | ||
} | ||
int main(int argc, char *const *argv) | ||
{ | ||
char *filename; | ||
int fd; | ||
int c; | ||
uid_t begin = 2000; | ||
uid_t end = 12000; | ||
unsigned int timeout = 10; | ||
struct timeval start, now, delta = { 0, 0 }; | ||
uid_t uid; | ||
gid_t gid = getegid(); | ||
int do_group = 0; | ||
int do_prepare = 0; | ||
|
||
progname = argv[0]; | ||
while ((c = getopt(argc, argv, "b:e:gPt:")) != -1) { | ||
switch (c) { | ||
case 'b': | ||
begin = atoi(optarg); | ||
break; | ||
case 'e': | ||
end = atoi(optarg); | ||
break; | ||
case 'g': | ||
do_group = 1; | ||
break; | ||
case 'P': | ||
do_prepare = 1; | ||
break; | ||
case 't': | ||
timeout = atoi(optarg); | ||
break; | ||
default: | ||
usage(); | ||
} | ||
} | ||
if (optind == argc-1) | ||
filename = argv[optind]; | ||
else | ||
usage(); | ||
if (do_prepare) { | ||
char path[PATH_MAX]; | ||
for (uid = begin; uid < end;uid++) { | ||
sprintf(path, "%s.%d", filename, uid); | ||
fd = open(path, O_RDWR|O_CREAT, 0666); | ||
if (fd < 0) { | ||
perror("open"); | ||
exit(1); | ||
} | ||
if (do_group) | ||
gid = uid; | ||
if (fchown(fd, uid, gid)) { | ||
perror("chown"); | ||
exit(1); | ||
} | ||
close(fd); | ||
} | ||
return 0; | ||
} | ||
fd = open(filename, O_RDWR|O_CREAT, 0666); | ||
if (fd < 0) { | ||
perror("open"); | ||
exit(1); | ||
} | ||
gettimeofday(&start, NULL); | ||
|
||
while (1) { | ||
for (uid = begin; uid < end;uid++) { | ||
if (do_group) | ||
gid = uid; | ||
if (fchown(fd, uid, gid)) { | ||
perror("chown"); | ||
exit(1); | ||
} | ||
} | ||
gettimeofday(&now, NULL); | ||
timersub(&now, &start, &delta); | ||
if (delta.tv_sec >= timeout) | ||
break; | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#! /bin/bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
# Copyright (c) 2019 YANDEX LLC. All Rights Reserved. | ||
# | ||
# FS QA Test 585 | ||
# | ||
# Check livelock during quota-sync while other tasks dirty quotas in parallel. | ||
# Run fchown(2) in a loop is the fastest way to produce dirty quotas | ||
# | ||
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.* | ||
} | ||
# get standard environment, filters and checks | ||
. ./common/rc | ||
. ./common/filter | ||
. ./common/quota | ||
|
||
|
||
begin=2000 | ||
end=10000 | ||
nr_proc=$((16 * LOAD_FACTOR)) | ||
deadline=$((100 * TIME_FACTOR)) | ||
|
||
_workout() | ||
{ | ||
for ((i=0; i < nr_proc; i++)) | ||
do | ||
# Spread files to isolated dirs to minimize locking contention | ||
mkdir -p $SCRATCH_MNT/chowner/$i | ||
$here/src/chowner $SCRATCH_MNT/chowner/$i/test -b $begin -e $end \ | ||
-t $((deadline + 10)) & | ||
pids="$pids $!" | ||
done | ||
# Let chowners warm up ... | ||
sleep 5 | ||
start=$(date +%s) | ||
for ((i=0;i<3;i++)) | ||
do | ||
s=$(date +%s) | ||
# In normal situation command should finish in ~1sec, | ||
# but in case of livelock it will spin until chowners exits | ||
$* | ||
e=$(date +%s) | ||
echo "loop $i: $* runtime: $((e-s))" >> $seqres.full | ||
sleep 2 | ||
done | ||
end=$(date +%s) | ||
runtime=$((end-start)) | ||
echo "DONE: $* total runtime: $runtime" >> $seqres.full | ||
kill -TERM $pids 2> /dev/null | ||
wait $pids | ||
|
||
[ $runtime -le $deadline ] || \ | ||
_fail "Live lock detected, $* runtime: $runtime, deadline: $deadline" | ||
} | ||
|
||
# real QA test starts here | ||
_supported_fs generic | ||
_supported_os Linux | ||
_require_quota | ||
#_require_user | ||
_require_scratch | ||
_require_command "$KILLALL_PROG" killall | ||
|
||
rm -f $seqres.full | ||
_scratch_mkfs_sized $((512 * 1024 * 1024)) >> $seqres.full 2>&1 | ||
_scratch_mount "-o quota,user" | ||
chmod 777 $SCRATCH_MNT | ||
quotacheck -u $SCRATCH_MNT 2>/dev/null | ||
quotaon -v -u $SCRATCH_MNT >> $seqres.full 2>&1 | ||
|
||
# Preparation step: Create all files with uid in range | ||
# to cache quota in kernel memory | ||
mkdir -p $SCRATCH_MNT/q | ||
$here/src/chowner $SCRATCH_MNT/q -b $begin -e $end -P | ||
|
||
_workout quotasync $SCRATCH_MNT | ||
_workout sync | ||
|
||
echo "Silence is golden" | ||
# success, all done | ||
status=0 | ||
exit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
QA output created by 585 | ||
Silence is golden |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -587,3 +587,4 @@ | |
582 auto quick encrypt | ||
583 auto quick encrypt | ||
584 auto quick encrypt | ||
585 auto quota rw stress |