From 9afa452b59b6962f22371eef0d3b012721e37f5d Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Fri, 12 Apr 2013 20:54:42 +0000 Subject: [PATCH] test70: regression test for vfs race condition Change-Id: I68681cdc5ed70491a08f5ddc86890fb2743c839d --- test/Makefile | 2 +- test/run | 2 +- test/test70.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 test/test70.c diff --git a/test/Makefile b/test/Makefile index ceea1188e..cd65794b3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -36,7 +36,7 @@ MINIX_TESTS= \ 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 48 49 50 52 53 54 55 56 58 59 60 \ -61 64 65 66 67 68 69 +61 64 65 66 67 68 69 70 .if ${MACHINE_ARCH} == "i386" MINIX_TESTS+= \ diff --git a/test/run b/test/run index bac932156..f90ac1c49 100755 --- a/test/run +++ b/test/run @@ -18,7 +18,7 @@ setuids="test11 test33 test43 test44 test46 test56 test60 test61 test65 \ tests=" 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\ + 61 62 63 64 65 66 67 68 69 70 \ sh1.sh sh2.sh interp.sh" tests_no=`expr 0` diff --git a/test/test70.c b/test/test70.c new file mode 100644 index 000000000..11c7ecb97 --- /dev/null +++ b/test/test70.c @@ -0,0 +1,76 @@ +/* Test 70 + * Regression test for vfs overwriting m_out fields by competing threads. + * lseek() uses one of these fields too so this test performs concurrent + * lseek()s to trigger this situation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#define SEEKWINDOW 1000 + +static int +doseeks(int seekbase) +{ + char template[30] = "tempfile.XXXXXXXX"; + int iteration, fd = mkstemp(template); + int limit = seekbase + SEEKWINDOW; + + /* make a temporary file, unlink it so it's always gone + * afterwards, and make it the size we need. + */ + if(fd < 0) { perror("mkstemp"); e(2); return 1; } + if(unlink(template) < 0) { perror("unlink"); e(3); return 1; } + if(ftruncate(fd, limit) < 0) { perror("ftruncate"); e(4); return 1; } + + /* try lseek() lots of times with different arguments and make + * sure we get the right return value back, while this happens + * in a concurrent process too. + */ +#define ITERATIONS 50000 + for(iteration = 0; iteration < ITERATIONS; iteration++) { + int o; + for(o = seekbase; o < limit; o++) { + int r; + if((r=lseek(fd, o, SEEK_SET)) != o) { + if(r < 0) perror("lseek"); + fprintf(stderr, "%d/%d %d != %d\n", + iteration, ITERATIONS, r, o); + e(5); + return 1; + } + } + } + + return 0; +} + +int +main() +{ + start(70); + pid_t f; + int result; + + if((f=fork()) < 0) { e(1); quit(); } + + if(f == 0) { exit(doseeks(0)); } + + if(doseeks(SEEKWINDOW)) { e(10); } + + if (waitpid(f, &result, 0) == -1) e(11); + if (WEXITSTATUS(result) != 0) e(12); + + quit(); + + return(-1); /* impossible */ +} +