From f4d52cb8db9b408dfee387242ab9adf7f076b986 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 --- distrib/sets/lists/minix/mi | 1 + test/Makefile | 2 +- test/test70.c | 78 +++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 test/test70.c diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index 1a702bff3..46a8c344a 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -4623,6 +4623,7 @@ ./usr/tests/minix-posix/test67 minix-sys ./usr/tests/minix-posix/test68 minix-sys ./usr/tests/minix-posix/test69 minix-sys +./usr/tests/minix-posix/test70 minix-sys ./usr/tests/minix-posix/test7 minix-sys ./usr/tests/minix-posix/test8 minix-sys ./usr/tests/minix-posix/test9 minix-sys diff --git a/test/Makefile b/test/Makefile index 4ded59455..34bee7480 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/test70.c b/test/test70.c new file mode 100644 index 000000000..6058ea71a --- /dev/null +++ b/test/test70.c @@ -0,0 +1,78 @@ +/* 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 + +#define MAX_ERROR 2 + +#include "common.c" + +#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 10000 + 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 */ +} +