minix/test/test70.c
Ben Gras 32a4e0d84d many new tests
. test70: regression test for m_out vfs race condition

The following tests use testcache.c to generate test i/o
patterns, generate random write data and verify the reads.

	. test71: blackbox full-stack test of FS operation, testing
	  using the regular VFS interface crazy i/o patterns
	  with various working set sizes, triggering only
	  primary cache, also secondary cache, and finally
	  disk i/o and verifying contents all the time
	. test72: unit test of libminixfs, implementing
	  functions it needs from -lsys and -lblockdriver
	  and the client in order to simulate a working
	  cache client and backend environment.
	. test73: blackbox test of secondary vm cache in isolation

Change-Id: I1287e9753182b8719e634917ad158e3c1e079ceb
2013-04-19 16:21:48 +00:00

85 lines
2 KiB
C

/* Test 70 - regression test for m_out vfs race condition.
*
* 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.
*
* The program consists of 2 processes, each seeking to different ranges in
* a test file. The bug would return the wrong value in one of the messaeg
* fields so the lseek() return value would be wrong sometimes.
*
* The first instance seeks from 0 to SEEKWINDOW, the other instance seeks
* from SEEKWINDOW to SEEKWINDOW+SEEKWINDOW.
*/
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#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 */
}