 32a4e0d84d
			
		
	
	
		32a4e0d84d
		
	
	
	
	
		
			
			. 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
		
			
				
	
	
		
			85 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			2.0 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 */
 | |
| }
 | |
| 
 |