xref: /onnv-gate/usr/src/cmd/avs/sdbc/sd_diag.c (revision 11576:b23c42c0c9d6)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
21*11576SSurya.Prakki@Sun.COM 
227836SJohn.Forte@Sun.COM /*
23*11576SSurya.Prakki@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
247836SJohn.Forte@Sun.COM  * Use is subject to license terms.
257836SJohn.Forte@Sun.COM  */
267836SJohn.Forte@Sun.COM 
277836SJohn.Forte@Sun.COM /* #include <version.h> SKK */
287836SJohn.Forte@Sun.COM #include <errno.h>
297836SJohn.Forte@Sun.COM #include <sys/types.h>
307836SJohn.Forte@Sun.COM #include <sys/time.h>
317836SJohn.Forte@Sun.COM #include <sys/param.h>
327836SJohn.Forte@Sun.COM #include <sys/inttypes.h>
337836SJohn.Forte@Sun.COM #include <stdio.h>
347836SJohn.Forte@Sun.COM #include <strings.h>
357836SJohn.Forte@Sun.COM #include <fcntl.h>
367836SJohn.Forte@Sun.COM #include <sys/shm.h>
377836SJohn.Forte@Sun.COM #include <sys/wait.h>
387836SJohn.Forte@Sun.COM #include <unistd.h>
397836SJohn.Forte@Sun.COM #include <nsctl.h>
407836SJohn.Forte@Sun.COM 
417836SJohn.Forte@Sun.COM #include <sys/nsctl/sd_cache.h>
427836SJohn.Forte@Sun.COM #include <sys/nsctl/sd_conf.h>
437836SJohn.Forte@Sun.COM 
447836SJohn.Forte@Sun.COM #include <stdlib.h>
457836SJohn.Forte@Sun.COM #include <thread.h>
467836SJohn.Forte@Sun.COM #include <synch.h>
477836SJohn.Forte@Sun.COM 
487836SJohn.Forte@Sun.COM #define	MAXPARTS	100	/* Max disks */
497836SJohn.Forte@Sun.COM #define	MAXBUF	65536	/* Max buffer size in long words */
507836SJohn.Forte@Sun.COM #define	DISKLIST	"disk_config"	/* Default config file */
517836SJohn.Forte@Sun.COM #define	DEF_SIZE	8192	/* Default buffer size */
527836SJohn.Forte@Sun.COM #define	DEF_LOOP	1000	/* Loops for test */
537836SJohn.Forte@Sun.COM #define	RAND_LOOPS	DEF_LOOP	/* # of random ios to do */
547836SJohn.Forte@Sun.COM 
557836SJohn.Forte@Sun.COM /*
567836SJohn.Forte@Sun.COM  *  >>>>>>>>> USER LEVEL SD CACHE DIAGNOSTICS <<<<<<<<<<
577836SJohn.Forte@Sun.COM  *
587836SJohn.Forte@Sun.COM  *  Write and read data blocks w/multiple processes
597836SJohn.Forte@Sun.COM  *  Starts one process for each partition specified in
607836SJohn.Forte@Sun.COM  *  the config file
617836SJohn.Forte@Sun.COM  */
627836SJohn.Forte@Sun.COM 
637836SJohn.Forte@Sun.COM int  buf1[MAXBUF];
647836SJohn.Forte@Sun.COM int  buf2[MAXBUF];
657836SJohn.Forte@Sun.COM char name[MAXPARTS][80];
667836SJohn.Forte@Sun.COM int  pattern[MAXPARTS];
677836SJohn.Forte@Sun.COM int  bufsize = DEF_SIZE;
687836SJohn.Forte@Sun.COM int  fba_num_bufsize;
697836SJohn.Forte@Sun.COM nsc_size_t  loops   = DEF_LOOP;
707836SJohn.Forte@Sun.COM nsc_size_t  r_loops   = RAND_LOOPS;
717836SJohn.Forte@Sun.COM int  fsize   = -1;
727836SJohn.Forte@Sun.COM int  readercount = 3;
737836SJohn.Forte@Sun.COM int  Rflag = O_EXCL;
747836SJohn.Forte@Sun.COM char config_file[32];
757836SJohn.Forte@Sun.COM 
767836SJohn.Forte@Sun.COM int
read_parts()777836SJohn.Forte@Sun.COM read_parts()
787836SJohn.Forte@Sun.COM {
797836SJohn.Forte@Sun.COM 	FILE *dfile;
807836SJohn.Forte@Sun.COM 	int   partitions = 0;
817836SJohn.Forte@Sun.COM 	int i;
827836SJohn.Forte@Sun.COM 
837836SJohn.Forte@Sun.COM 	dfile = fopen(config_file, "r");
847836SJohn.Forte@Sun.COM 	if (dfile == NULL) {
857836SJohn.Forte@Sun.COM 		(void) printf("cannot open file: %s\n", config_file);
867836SJohn.Forte@Sun.COM 		perror("fopen");
877836SJohn.Forte@Sun.COM 		exit(errno);
887836SJohn.Forte@Sun.COM 	}
897836SJohn.Forte@Sun.COM 	for (i = 0; i < MAXPARTS; i++) {
907836SJohn.Forte@Sun.COM 		if (fscanf(dfile, "%s %x", name[i], (uint_t *)&pattern[i]) ==
917836SJohn.Forte@Sun.COM 		    EOF) {
927836SJohn.Forte@Sun.COM 			break;
937836SJohn.Forte@Sun.COM 		} else
947836SJohn.Forte@Sun.COM 			if (name[i][0] == '#' || strchr(name[i], '/') == NULL) {
957836SJohn.Forte@Sun.COM 				i--;
967836SJohn.Forte@Sun.COM 				continue;
977836SJohn.Forte@Sun.COM 			}
987836SJohn.Forte@Sun.COM 		partitions++;
997836SJohn.Forte@Sun.COM 	}
1007836SJohn.Forte@Sun.COM 	(void) fclose(dfile);
1017836SJohn.Forte@Sun.COM 	(void) printf("No. of partitions listed in file '%s' = %d\n\n",
1027836SJohn.Forte@Sun.COM 			config_file, partitions);
1037836SJohn.Forte@Sun.COM 	return (partitions);
1047836SJohn.Forte@Sun.COM }
1057836SJohn.Forte@Sun.COM 
1067836SJohn.Forte@Sun.COM void
print_usage()1077836SJohn.Forte@Sun.COM print_usage()
1087836SJohn.Forte@Sun.COM {
1097836SJohn.Forte@Sun.COM 	(void) printf("Usage:\n");
1107836SJohn.Forte@Sun.COM 	(void) printf(
1117836SJohn.Forte@Sun.COM "sd_diag [-R] [-b <bufsize>] [-d <datasize>] [-l <loops>] [-r <readers>]\n");
1127836SJohn.Forte@Sun.COM 	(void) printf(
1137836SJohn.Forte@Sun.COM "        [-f <disk_config_file>] <test#>\n");
1147836SJohn.Forte@Sun.COM 	(void) printf(" test 1 = random read/write\n");
1157836SJohn.Forte@Sun.COM 	(void) printf("      2 = random read/write/verify, read after write\n");
1167836SJohn.Forte@Sun.COM 	(void) printf("      3 = random read/write/verify,");
1177836SJohn.Forte@Sun.COM 	(void) printf(" all reads after all writes\n");
1187836SJohn.Forte@Sun.COM 	(void) printf("      4 = sequential read/write\n");
1197836SJohn.Forte@Sun.COM 	(void) printf("      5 = sequential write/read/verify,");
1207836SJohn.Forte@Sun.COM 	(void) printf(" all reads after all writes\n");
1217836SJohn.Forte@Sun.COM 	(void) printf(
1227836SJohn.Forte@Sun.COM 	"      6 = altenating top/bottom sequential read/write/verify\n");
1237836SJohn.Forte@Sun.COM 	(void) printf("      7 = multiple readers/1 random writer\n");
1247836SJohn.Forte@Sun.COM 	(void) printf("      8 = random writes\n");
1257836SJohn.Forte@Sun.COM 	(void) printf("      9 = sequential write of known data\n");
1267836SJohn.Forte@Sun.COM 	(void) printf("      10 = sequential copy of datasize disk/verify\n");
1277836SJohn.Forte@Sun.COM 	(void) printf("      11 = sequential read/verify test 9 data -");
1287836SJohn.Forte@Sun.COM 	(void) printf(" then clear data with timestamp\n");
1297836SJohn.Forte@Sun.COM 	(void) printf("      12 = sequential read/verify test 9 data -");
1307836SJohn.Forte@Sun.COM 	(void) printf(" no clear data\n");
1317836SJohn.Forte@Sun.COM 	(void) printf("\n");
1327836SJohn.Forte@Sun.COM 	(void) printf("  <bufsize> in bytes (minimum is 512 bytes)\n");
1337836SJohn.Forte@Sun.COM 	(void) printf("  <datasize> in Mbytes per disk\n");
1347836SJohn.Forte@Sun.COM 	(void) printf("  <loops> is count of reads/writes,\n");
1357836SJohn.Forte@Sun.COM 	(void) printf("          loops = 0 tests entire datasize disk");
1367836SJohn.Forte@Sun.COM 	(void) printf(" for sequential tests.\n");
1377836SJohn.Forte@Sun.COM 	(void) printf("          loops = 0 performs %d I/Os for the random "
1387836SJohn.Forte@Sun.COM 	    "tests\n", RAND_LOOPS);
1397836SJohn.Forte@Sun.COM 	(void) printf("  <readers> is count of readers for test #7 (default "
1407836SJohn.Forte@Sun.COM 	    "is 3).\n");
1417836SJohn.Forte@Sun.COM 	(void) printf(" [ defaults: bufsize = %d bytes, loops = %d,",
1427836SJohn.Forte@Sun.COM 			DEF_SIZE, DEF_LOOP);
1437836SJohn.Forte@Sun.COM 	(void) printf(" datasize = disksize ]\n");
1447836SJohn.Forte@Sun.COM 	(void) printf("\n");
1457836SJohn.Forte@Sun.COM 	(void) printf("  -R : do nsc_reserve(), nsc_release(0 around each "
1467836SJohn.Forte@Sun.COM 	    "I/O\n");
1477836SJohn.Forte@Sun.COM }
1487836SJohn.Forte@Sun.COM 
1497836SJohn.Forte@Sun.COM void
parse_opts(int argc,char * argv[])1507836SJohn.Forte@Sun.COM parse_opts(int argc, char *argv[])
1517836SJohn.Forte@Sun.COM {
1527836SJohn.Forte@Sun.COM 	extern char *optarg;
1537836SJohn.Forte@Sun.COM 	int c;
1547836SJohn.Forte@Sun.COM 
1557836SJohn.Forte@Sun.COM 	while ((c = getopt(argc, argv, "b:d:l:r:Rf:")) != -1) {
1567836SJohn.Forte@Sun.COM 		switch (c) {
1577836SJohn.Forte@Sun.COM 			case 'f':
1587836SJohn.Forte@Sun.COM 			/* printf("\n%s", optarg); */
159*11576SSurya.Prakki@Sun.COM 			(void) strcpy(config_file, optarg);
1607836SJohn.Forte@Sun.COM 			break;
1617836SJohn.Forte@Sun.COM 		case 'b':
1627836SJohn.Forte@Sun.COM 			/* bufsize between 1*512 and 512*512 */
1637836SJohn.Forte@Sun.COM 			bufsize = strtol(optarg, 0, 0);
1647836SJohn.Forte@Sun.COM 			if (bufsize > (MAXBUF*4))
1657836SJohn.Forte@Sun.COM 				bufsize = MAXBUF*4;
1667836SJohn.Forte@Sun.COM 			else if (bufsize < FBA_SIZE(1))
1677836SJohn.Forte@Sun.COM 			    bufsize = FBA_SIZE(1);
1687836SJohn.Forte@Sun.COM 			break;
1697836SJohn.Forte@Sun.COM 		case 'd':
1707836SJohn.Forte@Sun.COM 			/* convert datasize from Mb's to fba */
1717836SJohn.Forte@Sun.COM 			fsize = strtol(optarg, 0, 0) *  FBA_NUM(1 << 20);
1727836SJohn.Forte@Sun.COM 			break;
1737836SJohn.Forte@Sun.COM 		case 'l':
1747836SJohn.Forte@Sun.COM 			loops = (nsc_size_t)strtoll(optarg, 0, 0);
1757836SJohn.Forte@Sun.COM 			break;
1767836SJohn.Forte@Sun.COM 		case 'r':
1777836SJohn.Forte@Sun.COM 			/* count of readers for test 7 */
1787836SJohn.Forte@Sun.COM 			readercount = strtol(optarg, 0, 0);
1797836SJohn.Forte@Sun.COM 			break;
1807836SJohn.Forte@Sun.COM 		case 'R':
1817836SJohn.Forte@Sun.COM 			/* do reserve, release on a per io basis */
1827836SJohn.Forte@Sun.COM 			Rflag = 0;
1837836SJohn.Forte@Sun.COM 			break;
1847836SJohn.Forte@Sun.COM 		case '?':
1857836SJohn.Forte@Sun.COM 			print_usage();
1867836SJohn.Forte@Sun.COM 			exit(0);
1877836SJohn.Forte@Sun.COM 		}
1887836SJohn.Forte@Sun.COM 	}
1897836SJohn.Forte@Sun.COM 	bufsize &= ~FBA_MASK; /* multiple of 512 bytes for SECTMODE I/O */
1907836SJohn.Forte@Sun.COM 	fba_num_bufsize = FBA_NUM(bufsize);
1917836SJohn.Forte@Sun.COM 
1927836SJohn.Forte@Sun.COM 	/*  set #ios for random io tests */
1937836SJohn.Forte@Sun.COM 	if (loops != 0)
1947836SJohn.Forte@Sun.COM 		r_loops = loops;
1957836SJohn.Forte@Sun.COM 
1967836SJohn.Forte@Sun.COM }
1977836SJohn.Forte@Sun.COM 
1987836SJohn.Forte@Sun.COM nsc_size_t
set_part_size(char * path,nsc_fd_t * sdfd)1997836SJohn.Forte@Sun.COM set_part_size(char *path, nsc_fd_t *sdfd)
2007836SJohn.Forte@Sun.COM {
2017836SJohn.Forte@Sun.COM 	nsc_size_t filesize;
2027836SJohn.Forte@Sun.COM 	int rc;
2037836SJohn.Forte@Sun.COM 
2047836SJohn.Forte@Sun.COM 	rc = nsc_partsize(sdfd, &filesize); /* partsize in FBAs (512 bytes) */
2057836SJohn.Forte@Sun.COM 	if (rc < 0 || filesize == 0) {
2067836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
2077836SJohn.Forte@Sun.COM 		    "set_part_size: cannot access partition size");
2087836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, " for %s\n", path);
2097836SJohn.Forte@Sun.COM 		(void) nsc_close(sdfd);
2107836SJohn.Forte@Sun.COM 		exit(1);
2117836SJohn.Forte@Sun.COM 	}
2127836SJohn.Forte@Sun.COM 
2137836SJohn.Forte@Sun.COM 	(void) printf("Partition %s, size:%" NSC_SZFMT " blocks\n", path,
2147836SJohn.Forte@Sun.COM 	    filesize);
2157836SJohn.Forte@Sun.COM 
2167836SJohn.Forte@Sun.COM 	if (fsize != -1 && fsize < filesize)
2177836SJohn.Forte@Sun.COM 		filesize = fsize;
2187836SJohn.Forte@Sun.COM 	filesize -= fba_num_bufsize;
2197836SJohn.Forte@Sun.COM 	if (filesize < fba_num_bufsize) {
2207836SJohn.Forte@Sun.COM 		(void) printf("ERROR: Max block size %" NSC_SZFMT "\n",
2217836SJohn.Forte@Sun.COM 		    filesize);
2227836SJohn.Forte@Sun.COM 		(void) nsc_close(sdfd);
2237836SJohn.Forte@Sun.COM 		exit(0);
2247836SJohn.Forte@Sun.COM 	}
2257836SJohn.Forte@Sun.COM 
2267836SJohn.Forte@Sun.COM 	return (filesize);
2277836SJohn.Forte@Sun.COM }
2287836SJohn.Forte@Sun.COM 
2297836SJohn.Forte@Sun.COM int
do_sdtest1(int fd,nsc_size_t loops,nsc_size_t filesize)2307836SJohn.Forte@Sun.COM do_sdtest1(int fd, nsc_size_t loops, nsc_size_t filesize)
2317836SJohn.Forte@Sun.COM {
2327836SJohn.Forte@Sun.COM 	nsc_off_t seekpos;
2337836SJohn.Forte@Sun.COM 	nsc_size_t i;
2347836SJohn.Forte@Sun.COM 	ssize_t r;
2357836SJohn.Forte@Sun.COM 
2367836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
2377836SJohn.Forte@Sun.COM 		seekpos = (
2387836SJohn.Forte@Sun.COM #ifdef NSC_MULTI_TERABYTE
2397836SJohn.Forte@Sun.COM 		    ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
2407836SJohn.Forte@Sun.COM #endif
2417836SJohn.Forte@Sun.COM 		    (rand() << 16) | rand()) % filesize;
2427836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT));
2437836SJohn.Forte@Sun.COM 		if (r <= 0) {
2447836SJohn.Forte@Sun.COM 			perror("Test1: write");
2457836SJohn.Forte@Sun.COM 			return (1);
2467836SJohn.Forte@Sun.COM 		}
2477836SJohn.Forte@Sun.COM 		seekpos = (
2487836SJohn.Forte@Sun.COM #ifdef NSC_MULTI_TERABYTE
2497836SJohn.Forte@Sun.COM 		    ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
2507836SJohn.Forte@Sun.COM #endif
2517836SJohn.Forte@Sun.COM 		    (rand() << 16) | rand()) % filesize;
2527836SJohn.Forte@Sun.COM 		r = pread(fd, buf2, bufsize, (off_t)(seekpos << SCTRSHFT));
2537836SJohn.Forte@Sun.COM 		if (r <= 0) {
2547836SJohn.Forte@Sun.COM 			perror("Test1: read");
2557836SJohn.Forte@Sun.COM 			return (1);
2567836SJohn.Forte@Sun.COM 		}
2577836SJohn.Forte@Sun.COM 	}
2587836SJohn.Forte@Sun.COM 	return (0);
2597836SJohn.Forte@Sun.COM }
2607836SJohn.Forte@Sun.COM 
2617836SJohn.Forte@Sun.COM void
gen_data(int * buffer,int size)2627836SJohn.Forte@Sun.COM gen_data(int *buffer, int size)
2637836SJohn.Forte@Sun.COM {
2647836SJohn.Forte@Sun.COM 	int i;
2657836SJohn.Forte@Sun.COM 
2667836SJohn.Forte@Sun.COM 	size /= 4;
2677836SJohn.Forte@Sun.COM 	for (i = 0; i < size; i++)
2687836SJohn.Forte@Sun.COM 		buffer[i] = rand() << 16 | rand();
2697836SJohn.Forte@Sun.COM }
2707836SJohn.Forte@Sun.COM 
2717836SJohn.Forte@Sun.COM int
do_sdtest2(int fd,nsc_size_t loops,nsc_size_t filesize,int h)2727836SJohn.Forte@Sun.COM do_sdtest2(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
2737836SJohn.Forte@Sun.COM {
2747836SJohn.Forte@Sun.COM 	nsc_off_t seekpos;
2757836SJohn.Forte@Sun.COM 	int err = 0;
2767836SJohn.Forte@Sun.COM 	ssize_t r;
2777836SJohn.Forte@Sun.COM 	nsc_size_t i;
2787836SJohn.Forte@Sun.COM 
2797836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
2807836SJohn.Forte@Sun.COM 		seekpos = (
2817836SJohn.Forte@Sun.COM #ifdef NSC_MULTI_TERABYTE
2827836SJohn.Forte@Sun.COM 		    ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
2837836SJohn.Forte@Sun.COM #endif
2847836SJohn.Forte@Sun.COM 		    (rand() << 16) | rand()) % filesize;
2857836SJohn.Forte@Sun.COM 		gen_data(buf1, bufsize);
2867836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT));
2877836SJohn.Forte@Sun.COM 		if (r <= 0) {
2887836SJohn.Forte@Sun.COM 			perror("Test2: write");
2897836SJohn.Forte@Sun.COM 			err++;
2907836SJohn.Forte@Sun.COM 			return (err);
2917836SJohn.Forte@Sun.COM 		}
2927836SJohn.Forte@Sun.COM 		r = pread(fd, buf2, bufsize, (off_t)(seekpos << SCTRSHFT));
2937836SJohn.Forte@Sun.COM 		if (r <= 0) {
2947836SJohn.Forte@Sun.COM 			perror("Test2: read");
2957836SJohn.Forte@Sun.COM 			err++;
2967836SJohn.Forte@Sun.COM 			return (err);
2977836SJohn.Forte@Sun.COM 		}
2987836SJohn.Forte@Sun.COM 		if (memcmp(buf1, buf2, bufsize)) {
2997836SJohn.Forte@Sun.COM 			(void) printf("Test2: Data corruption,"
3007836SJohn.Forte@Sun.COM 			    " fd:%s, fpos:%" PRId64 ", len:%d\n",
3017836SJohn.Forte@Sun.COM 			    name[h], (int64_t)(seekpos << SCTRSHFT),
3027836SJohn.Forte@Sun.COM 			    bufsize);
3037836SJohn.Forte@Sun.COM 			err++;
3047836SJohn.Forte@Sun.COM 		}
3057836SJohn.Forte@Sun.COM 	}
3067836SJohn.Forte@Sun.COM 	return (err);
3077836SJohn.Forte@Sun.COM }
3087836SJohn.Forte@Sun.COM 
3097836SJohn.Forte@Sun.COM int
do_sdtest3(int fd,nsc_size_t loops,nsc_size_t filesize,int h,nsc_fd_t * sdfd)3107836SJohn.Forte@Sun.COM do_sdtest3(int fd, nsc_size_t loops, nsc_size_t filesize, int h, nsc_fd_t *sdfd)
3117836SJohn.Forte@Sun.COM {
3127836SJohn.Forte@Sun.COM 	nsc_off_t *seekpos;
3137836SJohn.Forte@Sun.COM 	int err = 0;
3147836SJohn.Forte@Sun.COM 	nsc_size_t i;
3157836SJohn.Forte@Sun.COM 	ssize_t r;
3167836SJohn.Forte@Sun.COM 
3177836SJohn.Forte@Sun.COM 	seekpos = malloc(loops*sizeof (nsc_off_t));
3187836SJohn.Forte@Sun.COM 	if (seekpos == NULL) {
3197836SJohn.Forte@Sun.COM 		perror("Test3: malloc");
3207836SJohn.Forte@Sun.COM 		(void) nsc_close(sdfd);
3217836SJohn.Forte@Sun.COM 		exit(errno);
3227836SJohn.Forte@Sun.COM 	}
3237836SJohn.Forte@Sun.COM 	gen_data(buf1, bufsize);
3247836SJohn.Forte@Sun.COM 
3257836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
3267836SJohn.Forte@Sun.COM 		seekpos[i] = (
3277836SJohn.Forte@Sun.COM #ifdef NSC_MULTI_TERABYTE
3287836SJohn.Forte@Sun.COM 		    ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
3297836SJohn.Forte@Sun.COM #endif
3307836SJohn.Forte@Sun.COM 		    (rand() << 16) | rand()) % filesize;
3317836SJohn.Forte@Sun.COM 		seekpos[i] -= seekpos[i] % fba_num_bufsize;
3327836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (off_t)(seekpos[i] << SCTRSHFT));
3337836SJohn.Forte@Sun.COM 		if (r <= 0) {
3347836SJohn.Forte@Sun.COM 			perror("Test3: write");
3357836SJohn.Forte@Sun.COM 			err++;
3367836SJohn.Forte@Sun.COM 			goto cleanup;
3377836SJohn.Forte@Sun.COM 		}
3387836SJohn.Forte@Sun.COM 	}
3397836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
3407836SJohn.Forte@Sun.COM 		buf2[0] = '\0';	/* clear buf to make sure something is read */
3417836SJohn.Forte@Sun.COM 		r = pread(fd, buf2, bufsize, (off_t)(seekpos[i] << SCTRSHFT));
3427836SJohn.Forte@Sun.COM 		if (r <= 0) {
3437836SJohn.Forte@Sun.COM 			perror("Test3: read");
3447836SJohn.Forte@Sun.COM 			err++;
3457836SJohn.Forte@Sun.COM 			goto cleanup;
3467836SJohn.Forte@Sun.COM 		}
3477836SJohn.Forte@Sun.COM 		if (memcmp(buf1, buf2, bufsize)) {
3487836SJohn.Forte@Sun.COM 			(void) printf("Data corruption, fd:%s, fpos:%" PRId64
3497836SJohn.Forte@Sun.COM 			    ", len:%d\n", name[h],
3507836SJohn.Forte@Sun.COM 			    (int64_t)(seekpos[i] << SCTRSHFT), bufsize);
3517836SJohn.Forte@Sun.COM 			err++;
3527836SJohn.Forte@Sun.COM 		}
3537836SJohn.Forte@Sun.COM 	}
3547836SJohn.Forte@Sun.COM 
3557836SJohn.Forte@Sun.COM cleanup:
3567836SJohn.Forte@Sun.COM 	free(seekpos);
3577836SJohn.Forte@Sun.COM 	return (err);
3587836SJohn.Forte@Sun.COM }
3597836SJohn.Forte@Sun.COM 
3607836SJohn.Forte@Sun.COM int
do_sdtest4(int fd,nsc_size_t loops,nsc_size_t filesize)3617836SJohn.Forte@Sun.COM do_sdtest4(int fd, nsc_size_t loops, nsc_size_t filesize)
3627836SJohn.Forte@Sun.COM {
3637836SJohn.Forte@Sun.COM 	ssize_t r;
3647836SJohn.Forte@Sun.COM 	nsc_size_t i;
3657836SJohn.Forte@Sun.COM 
3667836SJohn.Forte@Sun.COM 	/*
3677836SJohn.Forte@Sun.COM 	 * Do sequential reads/writes for loops number
3687836SJohn.Forte@Sun.COM 	 * of bufsize chunks, unless loops == 0, then do
3697836SJohn.Forte@Sun.COM 	 * entire disk.
3707836SJohn.Forte@Sun.COM 	 * 1. sequential reads from the top down,
3717836SJohn.Forte@Sun.COM 	 * 2. sequential writes from the top down,
3727836SJohn.Forte@Sun.COM 	 * 3. sequential reads from the bottom up,
3737836SJohn.Forte@Sun.COM 	 * 4. sequential writes from the bottom up.
3747836SJohn.Forte@Sun.COM 	 */
3757836SJohn.Forte@Sun.COM 	if ((loops > (filesize / fba_num_bufsize)) || (!loops))
3767836SJohn.Forte@Sun.COM 	    loops = filesize / fba_num_bufsize; /* entire disk */
3777836SJohn.Forte@Sun.COM 
3787836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
3797836SJohn.Forte@Sun.COM 		r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
3807836SJohn.Forte@Sun.COM 		if (r <= 0) {
3817836SJohn.Forte@Sun.COM 			perror("Test4: read");
3827836SJohn.Forte@Sun.COM 			return (1);
3837836SJohn.Forte@Sun.COM 		}
3847836SJohn.Forte@Sun.COM 	}
3857836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
3867836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
3877836SJohn.Forte@Sun.COM 		if (r <= 0) {
3887836SJohn.Forte@Sun.COM 			perror("Test4: write");
3897836SJohn.Forte@Sun.COM 			return (1);
3907836SJohn.Forte@Sun.COM 		}
3917836SJohn.Forte@Sun.COM 	}
3927836SJohn.Forte@Sun.COM 	for (i = loops - 1; i + 1 > 0; i--) {
3937836SJohn.Forte@Sun.COM 		r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
3947836SJohn.Forte@Sun.COM 		if (r <= 0) {
3957836SJohn.Forte@Sun.COM 			perror("Test4: read");
3967836SJohn.Forte@Sun.COM 			return (1);
3977836SJohn.Forte@Sun.COM 		}
3987836SJohn.Forte@Sun.COM 	}
3997836SJohn.Forte@Sun.COM 	for (i = loops - 1; i + 1 > 0; i--) {
4007836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
4017836SJohn.Forte@Sun.COM 		if (r <= 0) {
4027836SJohn.Forte@Sun.COM 			perror("Test4: write");
4037836SJohn.Forte@Sun.COM 			return (1);
4047836SJohn.Forte@Sun.COM 		}
4057836SJohn.Forte@Sun.COM 	}
4067836SJohn.Forte@Sun.COM 	return (0);
4077836SJohn.Forte@Sun.COM }
4087836SJohn.Forte@Sun.COM 
4097836SJohn.Forte@Sun.COM int
do_sdtest5(int fd,nsc_size_t loops,nsc_size_t filesize,int h)4107836SJohn.Forte@Sun.COM do_sdtest5(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
4117836SJohn.Forte@Sun.COM {
4127836SJohn.Forte@Sun.COM 	int err = 0;
4137836SJohn.Forte@Sun.COM 	ssize_t r;
4147836SJohn.Forte@Sun.COM 	nsc_size_t i;
4157836SJohn.Forte@Sun.COM 
4167836SJohn.Forte@Sun.COM 	/*
4177836SJohn.Forte@Sun.COM 	 * Do sequential writes with verify reads for loops number
4187836SJohn.Forte@Sun.COM 	 * of bufsize chunks, unless loops == 0, then do
4197836SJohn.Forte@Sun.COM 	 * entire disk.
4207836SJohn.Forte@Sun.COM 	 * 1. sequential writes from the top down,
4217836SJohn.Forte@Sun.COM 	 * 2. sequential reads from the top down with verify,
4227836SJohn.Forte@Sun.COM 	 * 3. sequential writes from the bottom up,
4237836SJohn.Forte@Sun.COM 	 * 4. sequential reads from the bottom up with verify.
4247836SJohn.Forte@Sun.COM 	 */
4257836SJohn.Forte@Sun.COM 	if ((loops > (filesize / fba_num_bufsize)) || (!loops))
4267836SJohn.Forte@Sun.COM 	    loops = filesize / fba_num_bufsize; /* entire disk */
4277836SJohn.Forte@Sun.COM 
4287836SJohn.Forte@Sun.COM 	gen_data(buf1, bufsize);
4297836SJohn.Forte@Sun.COM 
4307836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
4317836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
4327836SJohn.Forte@Sun.COM 		if (r <= 0) {
4337836SJohn.Forte@Sun.COM 			perror("Test5: write");
4347836SJohn.Forte@Sun.COM 			err++;
4357836SJohn.Forte@Sun.COM 			return (err);
4367836SJohn.Forte@Sun.COM 		}
4377836SJohn.Forte@Sun.COM 	}
4387836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
4397836SJohn.Forte@Sun.COM 		buf2[0] = '\0';	/* clear buf to make sure something is read */
4407836SJohn.Forte@Sun.COM 		r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
4417836SJohn.Forte@Sun.COM 		if (r <= 0) {
4427836SJohn.Forte@Sun.COM 			perror("Test5: read");
4437836SJohn.Forte@Sun.COM 			err++;
4447836SJohn.Forte@Sun.COM 			return (err);
4457836SJohn.Forte@Sun.COM 		}
4467836SJohn.Forte@Sun.COM 		if (memcmp(buf1, buf2, bufsize)) {
4477836SJohn.Forte@Sun.COM 			(void) printf("Test5: Data corruption,"
4487836SJohn.Forte@Sun.COM 			    " fd:%s, fpos:%" NSC_SZFMT ", len:%d\n",
4497836SJohn.Forte@Sun.COM 			    name[h], i, bufsize);
4507836SJohn.Forte@Sun.COM 			err++;
4517836SJohn.Forte@Sun.COM 		}
4527836SJohn.Forte@Sun.COM 	}
4537836SJohn.Forte@Sun.COM 
4547836SJohn.Forte@Sun.COM 	gen_data(buf1, bufsize);
4557836SJohn.Forte@Sun.COM 
4567836SJohn.Forte@Sun.COM 	for (i = loops - 1; i + 1 > 0; i--) {
4577836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
4587836SJohn.Forte@Sun.COM 		if (r <= 0) {
4597836SJohn.Forte@Sun.COM 			perror("Test5: write");
4607836SJohn.Forte@Sun.COM 			err++;
4617836SJohn.Forte@Sun.COM 			return (err);
4627836SJohn.Forte@Sun.COM 		}
4637836SJohn.Forte@Sun.COM 	}
4647836SJohn.Forte@Sun.COM 	for (i = loops - 1; i + 1 > 0; i--) {
4657836SJohn.Forte@Sun.COM 		buf2[0] = '\0';	/* clear buf to make sure something is read */
4667836SJohn.Forte@Sun.COM 		r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT);
4677836SJohn.Forte@Sun.COM 		if (r <= 0) {
4687836SJohn.Forte@Sun.COM 			perror("Test5: read");
4697836SJohn.Forte@Sun.COM 			err++;
4707836SJohn.Forte@Sun.COM 			return (err);
4717836SJohn.Forte@Sun.COM 		}
4727836SJohn.Forte@Sun.COM 		if (memcmp(buf1, buf2, bufsize)) {
4737836SJohn.Forte@Sun.COM 			(void) printf("Test5: Data corruption,"
4747836SJohn.Forte@Sun.COM 			    " fd:%s, fpos:%" NSC_SZFMT ", len:%d\n",
4757836SJohn.Forte@Sun.COM 			    name[h], i, bufsize);
4767836SJohn.Forte@Sun.COM 			err++;
4777836SJohn.Forte@Sun.COM 		}
4787836SJohn.Forte@Sun.COM 	}
4797836SJohn.Forte@Sun.COM 	return (err);
4807836SJohn.Forte@Sun.COM }
4817836SJohn.Forte@Sun.COM 
4827836SJohn.Forte@Sun.COM 
4837836SJohn.Forte@Sun.COM int
do_sdtest6(int fd,nsc_size_t loops,nsc_size_t filesize,int h)4847836SJohn.Forte@Sun.COM do_sdtest6(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
4857836SJohn.Forte@Sun.COM {
4867836SJohn.Forte@Sun.COM 	int err = 0;
4877836SJohn.Forte@Sun.COM 	nsc_size_t i;
4887836SJohn.Forte@Sun.COM 	ssize_t r;
4897836SJohn.Forte@Sun.COM 	nsc_size_t endloop = filesize / fba_num_bufsize;
4907836SJohn.Forte@Sun.COM 	int  buf3[MAXBUF];
4917836SJohn.Forte@Sun.COM 	int  buf4[MAXBUF];
4927836SJohn.Forte@Sun.COM 	nsc_off_t  top_pos, bottom_pos;
4937836SJohn.Forte@Sun.COM 
4947836SJohn.Forte@Sun.COM 	/*
4957836SJohn.Forte@Sun.COM 	 * Do alternating top down and bottom up sequential writes
4967836SJohn.Forte@Sun.COM 	 * (working towards middle) and verify with reads
4977836SJohn.Forte@Sun.COM 	 * for loops number of bufsize chunks, unless loops == 0, then do
4987836SJohn.Forte@Sun.COM 	 * entire disk.
4997836SJohn.Forte@Sun.COM 	 */
5007836SJohn.Forte@Sun.COM 	if ((loops > (filesize / fba_num_bufsize)) || (!loops))
5017836SJohn.Forte@Sun.COM 	    loops = filesize / fba_num_bufsize; /* entire disk */
5027836SJohn.Forte@Sun.COM 
5037836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
5047836SJohn.Forte@Sun.COM 		gen_data(buf1, bufsize);
5057836SJohn.Forte@Sun.COM 		bottom_pos = i*fba_num_bufsize;
5067836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (off_t)(bottom_pos << SCTRSHFT));
5077836SJohn.Forte@Sun.COM 		if (r <= 0) {
5087836SJohn.Forte@Sun.COM 			perror("Test6: write");
5097836SJohn.Forte@Sun.COM 			err++;
5107836SJohn.Forte@Sun.COM 			return (err);
5117836SJohn.Forte@Sun.COM 		}
5127836SJohn.Forte@Sun.COM 		gen_data(buf2, bufsize);
5137836SJohn.Forte@Sun.COM 		top_pos = (endloop - i - 1)*fba_num_bufsize;
5147836SJohn.Forte@Sun.COM 
5157836SJohn.Forte@Sun.COM 		/* Make sure we don't collide in the middle */
5167836SJohn.Forte@Sun.COM 
5177836SJohn.Forte@Sun.COM 		if (abs(top_pos - bottom_pos) < fba_num_bufsize)
5187836SJohn.Forte@Sun.COM 			top_pos = bottom_pos + fba_num_bufsize;
5197836SJohn.Forte@Sun.COM 
5207836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf2, bufsize, (off_t)(top_pos << SCTRSHFT));
5217836SJohn.Forte@Sun.COM 		if (r <= 0) {
5227836SJohn.Forte@Sun.COM 			perror("Test6: write");
5237836SJohn.Forte@Sun.COM 			err++;
5247836SJohn.Forte@Sun.COM 			return (err);
5257836SJohn.Forte@Sun.COM 		}
5267836SJohn.Forte@Sun.COM 		r = pread(fd, buf3, bufsize, (off_t)(bottom_pos << SCTRSHFT));
5277836SJohn.Forte@Sun.COM 		if (r <= 0) {
5287836SJohn.Forte@Sun.COM 			perror("Test6: read");
5297836SJohn.Forte@Sun.COM 			err++;
5307836SJohn.Forte@Sun.COM 			return (err);
5317836SJohn.Forte@Sun.COM 		}
5327836SJohn.Forte@Sun.COM 		if (memcmp(buf1, buf3, bufsize)) {
5337836SJohn.Forte@Sun.COM 			(void) printf("Data corruption(1), fd:%s, fpos:%"
5347836SJohn.Forte@Sun.COM 			    PRId64 ", len:%d\n", name[h],
5357836SJohn.Forte@Sun.COM 			    (int64_t)(bottom_pos << SCTRSHFT), bufsize);
5367836SJohn.Forte@Sun.COM 			err++;
5377836SJohn.Forte@Sun.COM 		}
5387836SJohn.Forte@Sun.COM 		r = pread(fd, buf4, bufsize, (off_t)(top_pos << SCTRSHFT));
5397836SJohn.Forte@Sun.COM 		if (r <= 0) {
5407836SJohn.Forte@Sun.COM 			perror("Test6: read");
5417836SJohn.Forte@Sun.COM 			return (1);
5427836SJohn.Forte@Sun.COM 		}
5437836SJohn.Forte@Sun.COM 		if (memcmp(buf2, buf4, bufsize)) {
5447836SJohn.Forte@Sun.COM 			(void) printf("Test6: Data corruption(2),"
5457836SJohn.Forte@Sun.COM 			    " fd:%s, fpos:%" PRId64 ", len:%d\n",
5467836SJohn.Forte@Sun.COM 			    name[h], (int64_t)(top_pos << SCTRSHFT), bufsize);
5477836SJohn.Forte@Sun.COM 			err++;
5487836SJohn.Forte@Sun.COM 		}
5497836SJohn.Forte@Sun.COM 	}
5507836SJohn.Forte@Sun.COM 	return (err);
5517836SJohn.Forte@Sun.COM }
5527836SJohn.Forte@Sun.COM 
5537836SJohn.Forte@Sun.COM int shmid;
5547836SJohn.Forte@Sun.COM 
5557836SJohn.Forte@Sun.COM #define	MAXREADERS 32
5567836SJohn.Forte@Sun.COM 
5577836SJohn.Forte@Sun.COM struct shm_struct {
5587836SJohn.Forte@Sun.COM 	int writebuf[MAXBUF];
5597836SJohn.Forte@Sun.COM 	volatile nsc_off_t writepos;
5607836SJohn.Forte@Sun.COM 	int quit;
5617836SJohn.Forte@Sun.COM 	int err;
5627836SJohn.Forte@Sun.COM 	mutex_t err_mutex;
5637836SJohn.Forte@Sun.COM 	int rd_done[MAXREADERS];
5647836SJohn.Forte@Sun.COM 	int rd_done_mask[MAXREADERS];
5657836SJohn.Forte@Sun.COM } *shm;
5667836SJohn.Forte@Sun.COM 
5677836SJohn.Forte@Sun.COM #define	WRITEBUF (shm->writebuf)
5687836SJohn.Forte@Sun.COM #define	WRITEPOS (shm->writepos)
5697836SJohn.Forte@Sun.COM 
5707836SJohn.Forte@Sun.COM #define	QUIT	(shm->quit)
5717836SJohn.Forte@Sun.COM #define	ERR	(shm->err)
5727836SJohn.Forte@Sun.COM #define	ERRMUTEX (shm->err_mutex)
5737836SJohn.Forte@Sun.COM #define	RD_DONE (shm->rd_done)
5747836SJohn.Forte@Sun.COM #define	RD_DONE_MASK (shm->rd_done_mask)
5757836SJohn.Forte@Sun.COM 
5767836SJohn.Forte@Sun.COM #define	LOCKWRITE
5777836SJohn.Forte@Sun.COM #define	LOCKREAD(i)
5787836SJohn.Forte@Sun.COM 
5797836SJohn.Forte@Sun.COM /*  Clear RD_DONE and Set WRITEPOS  */
5807836SJohn.Forte@Sun.COM #define	FREEWRITE { \
5817836SJohn.Forte@Sun.COM 	bzero(RD_DONE, sizeof (RD_DONE)); \
5827836SJohn.Forte@Sun.COM 	WRITEPOS = wr_pos; }
5837836SJohn.Forte@Sun.COM 
5847836SJohn.Forte@Sun.COM /*  Reader i+1 marks himself as finished  */
5857836SJohn.Forte@Sun.COM #define	FREEREAD(i) (RD_DONE[(i)] = 1)
5867836SJohn.Forte@Sun.COM 
5877836SJohn.Forte@Sun.COM 
5887836SJohn.Forte@Sun.COM int
do_sdtest7read(int fd,int h,int which)5897836SJohn.Forte@Sun.COM do_sdtest7read(int fd, int h, int which)
5907836SJohn.Forte@Sun.COM {
5917836SJohn.Forte@Sun.COM 	int err;
5927836SJohn.Forte@Sun.COM 	ssize_t r_rd;
5937836SJohn.Forte@Sun.COM 	nsc_off_t curr_pos;
5947836SJohn.Forte@Sun.COM 	nsc_size_t loop_cnt;
5957836SJohn.Forte@Sun.COM 	err = 0; curr_pos = 0; loop_cnt = 0;
5967836SJohn.Forte@Sun.COM 	for (;;) {
5977836SJohn.Forte@Sun.COM 		/* Already read this? */
5987836SJohn.Forte@Sun.COM 		if (curr_pos == WRITEPOS) {
5997836SJohn.Forte@Sun.COM 			if (!QUIT) {
6007836SJohn.Forte@Sun.COM 				continue;
6017836SJohn.Forte@Sun.COM 			} else {
6027836SJohn.Forte@Sun.COM 				/*  Time to go!  */
6037836SJohn.Forte@Sun.COM 				/* printf("Quitting [%d]\n", which+1); */
6047836SJohn.Forte@Sun.COM 				break;
6057836SJohn.Forte@Sun.COM 			}
6067836SJohn.Forte@Sun.COM 		}
6077836SJohn.Forte@Sun.COM 
6087836SJohn.Forte@Sun.COM 		/* get location to read from */
6097836SJohn.Forte@Sun.COM 		curr_pos = WRITEPOS;
6107836SJohn.Forte@Sun.COM 
6117836SJohn.Forte@Sun.COM 		r_rd = pread(fd, buf1, bufsize, (curr_pos << SCTRSHFT));
6127836SJohn.Forte@Sun.COM 		loop_cnt += 1;
6137836SJohn.Forte@Sun.COM 		if (r_rd <= 0) {
6147836SJohn.Forte@Sun.COM 			FREEREAD(which);
6157836SJohn.Forte@Sun.COM 			perror("Test7: read");
6167836SJohn.Forte@Sun.COM 			err += 1;
6177836SJohn.Forte@Sun.COM 			continue;
6187836SJohn.Forte@Sun.COM 		}
6197836SJohn.Forte@Sun.COM 
6207836SJohn.Forte@Sun.COM 		if (memcmp(buf1, WRITEBUF, bufsize)) {
6217836SJohn.Forte@Sun.COM 			FREEREAD(which);
6227836SJohn.Forte@Sun.COM 			(void) printf("\nTest7: Data corruption, reader #%d, "
6237836SJohn.Forte@Sun.COM 			    "fd:%s, \
6247836SJohn.Forte@Sun.COM 				fpos:%" PRId64 ", len:%d\n", which + 1, name[h],
6257836SJohn.Forte@Sun.COM 				(int64_t)(curr_pos << SCTRSHFT), bufsize);
6267836SJohn.Forte@Sun.COM 			err += 1;
6277836SJohn.Forte@Sun.COM 			continue;
6287836SJohn.Forte@Sun.COM 		}
6297836SJohn.Forte@Sun.COM 
6307836SJohn.Forte@Sun.COM 		FREEREAD(which);
6317836SJohn.Forte@Sun.COM 	}
6327836SJohn.Forte@Sun.COM 
6337836SJohn.Forte@Sun.COM 	(void) printf(
6347836SJohn.Forte@Sun.COM 	    "Partition %s, Test 7, reader #%d:  %d errors %lld loops\n",
6357836SJohn.Forte@Sun.COM 		name[h], which+1, err, loop_cnt);
6367836SJohn.Forte@Sun.COM 
6377836SJohn.Forte@Sun.COM 	if (err > 0) {
6387836SJohn.Forte@Sun.COM 		(void) mutex_lock(&ERRMUTEX);
6397836SJohn.Forte@Sun.COM 		ERR += err;
6407836SJohn.Forte@Sun.COM 		(void) mutex_unlock(&ERRMUTEX);
6417836SJohn.Forte@Sun.COM 	}
6427836SJohn.Forte@Sun.COM 
6437836SJohn.Forte@Sun.COM 	if (err)
6447836SJohn.Forte@Sun.COM 		return (1);
6457836SJohn.Forte@Sun.COM 	else
6467836SJohn.Forte@Sun.COM 		return (0);
6477836SJohn.Forte@Sun.COM }
6487836SJohn.Forte@Sun.COM 
6497836SJohn.Forte@Sun.COM 
6507836SJohn.Forte@Sun.COM int
do_sdtest7write(int fd,nsc_size_t filesize,int h)6517836SJohn.Forte@Sun.COM do_sdtest7write(int fd, nsc_size_t filesize, int h)
6527836SJohn.Forte@Sun.COM {
6537836SJohn.Forte@Sun.COM 	int err = 0;
6547836SJohn.Forte@Sun.COM 	ssize_t r;
6557836SJohn.Forte@Sun.COM 	nsc_off_t wr_pos;
6567836SJohn.Forte@Sun.COM 
6577836SJohn.Forte@Sun.COM 	/*  Wait for readers to finish  */
6587836SJohn.Forte@Sun.COM 	while (memcmp(RD_DONE, RD_DONE_MASK, readercount*sizeof (int)))
6597836SJohn.Forte@Sun.COM 		;
6607836SJohn.Forte@Sun.COM 
6617836SJohn.Forte@Sun.COM 	gen_data(WRITEBUF, bufsize);
6627836SJohn.Forte@Sun.COM 	wr_pos = (
6637836SJohn.Forte@Sun.COM #ifdef NSC_MULTI_TERABYTE
6647836SJohn.Forte@Sun.COM 	    ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
6657836SJohn.Forte@Sun.COM #endif
6667836SJohn.Forte@Sun.COM 	    (rand() << 16) | rand()) % filesize;
6677836SJohn.Forte@Sun.COM 	r = pwrite(fd, WRITEBUF, bufsize, (off_t)(wr_pos << SCTRSHFT));
6687836SJohn.Forte@Sun.COM 	if (r <= 0) {
6697836SJohn.Forte@Sun.COM 		FREEWRITE;
6707836SJohn.Forte@Sun.COM 		perror("Test7: write");
6717836SJohn.Forte@Sun.COM 		return (1);
6727836SJohn.Forte@Sun.COM 	}
6737836SJohn.Forte@Sun.COM 	FREEWRITE;
6747836SJohn.Forte@Sun.COM 
6757836SJohn.Forte@Sun.COM 	/* verify write */
6767836SJohn.Forte@Sun.COM 	r = pread(fd, buf1, bufsize, (off_t)(wr_pos << SCTRSHFT));
6777836SJohn.Forte@Sun.COM 	if (r <= 0) {
6787836SJohn.Forte@Sun.COM 		perror("Test7: writer: read");
6797836SJohn.Forte@Sun.COM 		return (1);
6807836SJohn.Forte@Sun.COM 	}
6817836SJohn.Forte@Sun.COM 
6827836SJohn.Forte@Sun.COM 
6837836SJohn.Forte@Sun.COM 	if (memcmp(buf1, WRITEBUF, bufsize)) {
6847836SJohn.Forte@Sun.COM 		(void) printf("\nTest7: Data corruption in writer,"
6857836SJohn.Forte@Sun.COM 		    " fd:%s, fpos:%" PRId64 ", len:%d\n",
6867836SJohn.Forte@Sun.COM 		    name[h], (int64_t)(wr_pos << SCTRSHFT), bufsize);
6877836SJohn.Forte@Sun.COM 		err++;
6887836SJohn.Forte@Sun.COM 	}
6897836SJohn.Forte@Sun.COM 
6907836SJohn.Forte@Sun.COM 
6917836SJohn.Forte@Sun.COM 	return (err);
6927836SJohn.Forte@Sun.COM }
6937836SJohn.Forte@Sun.COM 
6947836SJohn.Forte@Sun.COM void
init_shm()6957836SJohn.Forte@Sun.COM init_shm()
6967836SJohn.Forte@Sun.COM {
6977836SJohn.Forte@Sun.COM 	int i;
6987836SJohn.Forte@Sun.COM 
6997836SJohn.Forte@Sun.COM 	/*  Clear out everything  */
7007836SJohn.Forte@Sun.COM 	bzero(shm, sizeof (struct shm_struct));
7017836SJohn.Forte@Sun.COM 
7027836SJohn.Forte@Sun.COM 	(void) mutex_init(&ERRMUTEX, USYNC_PROCESS, NULL);
7037836SJohn.Forte@Sun.COM 
7047836SJohn.Forte@Sun.COM 	/*   Set up mask (constant) to test reader doneness  */
7057836SJohn.Forte@Sun.COM 	for (i = 0; i < readercount; i++)
7067836SJohn.Forte@Sun.COM 		RD_DONE_MASK[i] = 1;
7077836SJohn.Forte@Sun.COM 
7087836SJohn.Forte@Sun.COM 	/* Mark all readers done - so writer can start  */
7097836SJohn.Forte@Sun.COM 	for (i = 0; i < readercount; i++)
7107836SJohn.Forte@Sun.COM 		RD_DONE[i] = 1;
7117836SJohn.Forte@Sun.COM }
7127836SJohn.Forte@Sun.COM 
7137836SJohn.Forte@Sun.COM int
do_sdtest7(int fd,nsc_size_t loops,nsc_size_t filesize,int h,nsc_fd_t * sdfd)7147836SJohn.Forte@Sun.COM do_sdtest7(int fd, nsc_size_t loops, nsc_size_t filesize, int h, nsc_fd_t *sdfd)
7157836SJohn.Forte@Sun.COM {
7167836SJohn.Forte@Sun.COM 	int r, i, err;
7177836SJohn.Forte@Sun.COM 	nsc_size_t j;
7187836SJohn.Forte@Sun.COM 
7197836SJohn.Forte@Sun.COM 	if ((shmid = shmget(IPC_PRIVATE, sizeof (struct shm_struct),
7207836SJohn.Forte@Sun.COM 				IPC_CREAT | 0666)) < 0) {
7217836SJohn.Forte@Sun.COM 		perror("shmget error: ");
7227836SJohn.Forte@Sun.COM 		(void) nsc_close(sdfd);
7237836SJohn.Forte@Sun.COM 		exit(1);
7247836SJohn.Forte@Sun.COM 	}
7257836SJohn.Forte@Sun.COM 
7267836SJohn.Forte@Sun.COM 	shm = (struct shm_struct *)shmat(shmid, NULL, 0);
7277836SJohn.Forte@Sun.COM 	if (shm == (struct shm_struct *)-1) {
7287836SJohn.Forte@Sun.COM 		perror("shmat error: ");
7297836SJohn.Forte@Sun.COM 		(void) nsc_close(sdfd);
7307836SJohn.Forte@Sun.COM 		exit(1); /* cleanup exits */
7317836SJohn.Forte@Sun.COM 	}
7327836SJohn.Forte@Sun.COM 
7337836SJohn.Forte@Sun.COM 	init_shm();
7347836SJohn.Forte@Sun.COM 
7357836SJohn.Forte@Sun.COM 	/*  Start Readers  */
7367836SJohn.Forte@Sun.COM 	for (i = 0; i < readercount; i++) {
7377836SJohn.Forte@Sun.COM 		r = fork();
7387836SJohn.Forte@Sun.COM 		if (r == 0) { /* child */
7397836SJohn.Forte@Sun.COM 			(void) do_sdtest7read(fd, h, i);
7407836SJohn.Forte@Sun.COM 			(void) nsc_close(sdfd);
7417836SJohn.Forte@Sun.COM 			exit(0);
7427836SJohn.Forte@Sun.COM 		} else
7437836SJohn.Forte@Sun.COM 			continue;
7447836SJohn.Forte@Sun.COM 	}
7457836SJohn.Forte@Sun.COM 
7467836SJohn.Forte@Sun.COM 	/*  Start Writer  */
7477836SJohn.Forte@Sun.COM 	srand(getpid()); err = 0;
7487836SJohn.Forte@Sun.COM 	for (j = 0; j < loops; j++) {
7497836SJohn.Forte@Sun.COM 		err += do_sdtest7write(fd, filesize, h);
7507836SJohn.Forte@Sun.COM 	}
7517836SJohn.Forte@Sun.COM 	QUIT = 1;
7527836SJohn.Forte@Sun.COM 
7537836SJohn.Forte@Sun.COM 	(void) printf("\n\nPartition %s, Test 7, writer:  %d errors\n",
7547836SJohn.Forte@Sun.COM 	    name[h], err);
7557836SJohn.Forte@Sun.COM 
7567836SJohn.Forte@Sun.COM 	for (i = 0; i < readercount; i++)
757*11576SSurya.Prakki@Sun.COM 		(void) wait(0);
7587836SJohn.Forte@Sun.COM 
7597836SJohn.Forte@Sun.COM 	/*  No lock needed here - everybody's finished  */
7607836SJohn.Forte@Sun.COM 	err += ERR;
7617836SJohn.Forte@Sun.COM 
7627836SJohn.Forte@Sun.COM 	(void) mutex_destroy(&ERRMUTEX);
763*11576SSurya.Prakki@Sun.COM 	(void) shmctl(shmid, IPC_RMID, 0);
7647836SJohn.Forte@Sun.COM 	return (err);
7657836SJohn.Forte@Sun.COM }
7667836SJohn.Forte@Sun.COM 
7677836SJohn.Forte@Sun.COM int
do_sdtest8(int fd,nsc_size_t loops,nsc_size_t filesize)7687836SJohn.Forte@Sun.COM do_sdtest8(int fd, nsc_size_t loops, nsc_size_t filesize)
7697836SJohn.Forte@Sun.COM {
7707836SJohn.Forte@Sun.COM 	nsc_off_t seekpos;
7717836SJohn.Forte@Sun.COM 	int err = 0;
7727836SJohn.Forte@Sun.COM 	ssize_t r;
7737836SJohn.Forte@Sun.COM 	nsc_size_t i;
7747836SJohn.Forte@Sun.COM 
7757836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
7767836SJohn.Forte@Sun.COM 		seekpos = (
7777836SJohn.Forte@Sun.COM #ifdef NSC_MULTI_TERABYTE
7787836SJohn.Forte@Sun.COM 		    ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) |
7797836SJohn.Forte@Sun.COM #endif
7807836SJohn.Forte@Sun.COM 		    (rand() << 16) | rand()) % filesize;
7817836SJohn.Forte@Sun.COM 		gen_data(buf1, bufsize);
7827836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT));
7837836SJohn.Forte@Sun.COM 		if (r <= 0) {
7847836SJohn.Forte@Sun.COM 			perror("Test8: write");
7857836SJohn.Forte@Sun.COM 			err++;
7867836SJohn.Forte@Sun.COM 			return (err);
7877836SJohn.Forte@Sun.COM 		}
7887836SJohn.Forte@Sun.COM 	}
7897836SJohn.Forte@Sun.COM 	return (err);
7907836SJohn.Forte@Sun.COM }
7917836SJohn.Forte@Sun.COM 
7927836SJohn.Forte@Sun.COM void
gen_data_known(int * buffer,int size,int data)7937836SJohn.Forte@Sun.COM gen_data_known(int *buffer, int size, int data)
7947836SJohn.Forte@Sun.COM {
7957836SJohn.Forte@Sun.COM 	int i;
7967836SJohn.Forte@Sun.COM 
7977836SJohn.Forte@Sun.COM 	size /= 4;
7987836SJohn.Forte@Sun.COM 	for (i = 0; i < size; i++)
7997836SJohn.Forte@Sun.COM 		buffer[i] = data;
8007836SJohn.Forte@Sun.COM }
8017836SJohn.Forte@Sun.COM 
8027836SJohn.Forte@Sun.COM int
do_sdtest9(int fd,nsc_size_t loops,nsc_size_t filesize,int h)8037836SJohn.Forte@Sun.COM do_sdtest9(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
8047836SJohn.Forte@Sun.COM {
8057836SJohn.Forte@Sun.COM 	int err = 0;
8067836SJohn.Forte@Sun.COM 	ssize_t r;
8077836SJohn.Forte@Sun.COM 	nsc_off_t fba_offset;
8087836SJohn.Forte@Sun.COM 	nsc_size_t i, wrapval;
8097836SJohn.Forte@Sun.COM 
8107836SJohn.Forte@Sun.COM 	/*
8117836SJohn.Forte@Sun.COM 	 * Test 9 will write a given pattern over and over Test 11 or
8127836SJohn.Forte@Sun.COM 	 * Test 12 will read same pattern.
8137836SJohn.Forte@Sun.COM 	 */
8147836SJohn.Forte@Sun.COM 	/* Large loop value that would cause write overflow will wrap */
8157836SJohn.Forte@Sun.COM 
8167836SJohn.Forte@Sun.COM 	gen_data_known(buf1, bufsize, pattern[h]);
8177836SJohn.Forte@Sun.COM 
8187836SJohn.Forte@Sun.COM 	wrapval = filesize / fba_num_bufsize;
8197836SJohn.Forte@Sun.COM 
8207836SJohn.Forte@Sun.COM 	if (loops == 0)
8217836SJohn.Forte@Sun.COM 		loops = wrapval;  /* entire disk */
8227836SJohn.Forte@Sun.COM 
8237836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
8247836SJohn.Forte@Sun.COM 		fba_offset = i % wrapval;
8257836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf1, bufsize,
8267836SJohn.Forte@Sun.COM 		    (off_t)(fba_offset * fba_num_bufsize) << SCTRSHFT);
8277836SJohn.Forte@Sun.COM 		if (r <= 0) {
8287836SJohn.Forte@Sun.COM 			perror("Test9: write");
8297836SJohn.Forte@Sun.COM 			err++;
8307836SJohn.Forte@Sun.COM 			return (err);
8317836SJohn.Forte@Sun.COM 		}
8327836SJohn.Forte@Sun.COM 	}
8337836SJohn.Forte@Sun.COM 	return (err);
8347836SJohn.Forte@Sun.COM }
8357836SJohn.Forte@Sun.COM 
8367836SJohn.Forte@Sun.COM int
do_sdtest10(int fd1,int fd2,nsc_size_t loops,nsc_size_t filesize1,nsc_size_t filesize2,int h)8377836SJohn.Forte@Sun.COM do_sdtest10(int fd1, int fd2, nsc_size_t loops, nsc_size_t filesize1,
8387836SJohn.Forte@Sun.COM     nsc_size_t filesize2, int h)
8397836SJohn.Forte@Sun.COM {
8407836SJohn.Forte@Sun.COM 	nsc_size_t filesize;
8417836SJohn.Forte@Sun.COM 	int err = 0;
8427836SJohn.Forte@Sun.COM 	nsc_size_t i;
8437836SJohn.Forte@Sun.COM 	ssize_t r;
8447836SJohn.Forte@Sun.COM 
8457836SJohn.Forte@Sun.COM 	/*
8467836SJohn.Forte@Sun.COM 	 * Do sequential copy of disk1 to disk2 for loops number
8477836SJohn.Forte@Sun.COM 	 * of bufsize chunks, unless loops == 0, then copy size of
8487836SJohn.Forte@Sun.COM 	 * the smaller disk.
8497836SJohn.Forte@Sun.COM 	 * Go back and verify that the two disks are identical.
8507836SJohn.Forte@Sun.COM 	 */
8517836SJohn.Forte@Sun.COM 
8527836SJohn.Forte@Sun.COM 	filesize = (filesize1 < filesize2) ? filesize1 : filesize2;
8537836SJohn.Forte@Sun.COM 	if ((loops > (filesize / fba_num_bufsize)) || (!loops))
8547836SJohn.Forte@Sun.COM 	    loops = filesize / fba_num_bufsize;
8557836SJohn.Forte@Sun.COM 
8567836SJohn.Forte@Sun.COM 	/* copy disk1 to to disk2 */
8577836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
8587836SJohn.Forte@Sun.COM 		r = pread(fd1, buf1, bufsize,
8597836SJohn.Forte@Sun.COM 		    (off_t)(i*fba_num_bufsize) << SCTRSHFT);
8607836SJohn.Forte@Sun.COM 		if (r <= 0) {
8617836SJohn.Forte@Sun.COM 			perror("Test10: read");
8627836SJohn.Forte@Sun.COM 			return (1);
8637836SJohn.Forte@Sun.COM 		}
8647836SJohn.Forte@Sun.COM 		r = pwrite(fd2, buf1, bufsize,
8657836SJohn.Forte@Sun.COM 		    (off_t)(i*fba_num_bufsize) << SCTRSHFT);
8667836SJohn.Forte@Sun.COM 		if (r <= 0) {
8677836SJohn.Forte@Sun.COM 			perror("Test10: write");
8687836SJohn.Forte@Sun.COM 			return (1);
8697836SJohn.Forte@Sun.COM 		}
8707836SJohn.Forte@Sun.COM 	}
8717836SJohn.Forte@Sun.COM 
8727836SJohn.Forte@Sun.COM 	/* verify disks are identical */
8737836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
8747836SJohn.Forte@Sun.COM 		buf1[0] = '\0';	/* clear buf to make sure something is read */
8757836SJohn.Forte@Sun.COM 		r = pread(fd1, buf1, bufsize,
8767836SJohn.Forte@Sun.COM 		    (off_t)(i * fba_num_bufsize) << SCTRSHFT);
8777836SJohn.Forte@Sun.COM 		if (r <= 0) {
8787836SJohn.Forte@Sun.COM 			perror("Test10: read");
8797836SJohn.Forte@Sun.COM 			return (1);
8807836SJohn.Forte@Sun.COM 		}
8817836SJohn.Forte@Sun.COM 		buf2[0] = 'x';	/* make sure something is read */
8827836SJohn.Forte@Sun.COM 		r = pread(fd2, buf2, bufsize,
8837836SJohn.Forte@Sun.COM 		    (off_t)(i * fba_num_bufsize) << SCTRSHFT);
8847836SJohn.Forte@Sun.COM 		if (r <= 0) {
8857836SJohn.Forte@Sun.COM 			perror("Test10: read");
8867836SJohn.Forte@Sun.COM 			return (1);
8877836SJohn.Forte@Sun.COM 		}
8887836SJohn.Forte@Sun.COM 		if (memcmp(buf1, buf2, bufsize)) {
8897836SJohn.Forte@Sun.COM 			(void) printf("Test10: Data corruption,"
8907836SJohn.Forte@Sun.COM 			    " fd1:%s, fd2:%s fpos:%" NSC_SZFMT ", len:%d\n",
8917836SJohn.Forte@Sun.COM 			    name[2*h], name[2*h+1], i, bufsize);
8927836SJohn.Forte@Sun.COM 			err++;
8937836SJohn.Forte@Sun.COM 		}
8947836SJohn.Forte@Sun.COM 	}
8957836SJohn.Forte@Sun.COM 	return (err);
8967836SJohn.Forte@Sun.COM }
8977836SJohn.Forte@Sun.COM 
8987836SJohn.Forte@Sun.COM int
buffcmp(int * b1,int * b2,int size)8997836SJohn.Forte@Sun.COM buffcmp(int *b1, int *b2, int size)
9007836SJohn.Forte@Sun.COM {
9017836SJohn.Forte@Sun.COM 	int i;
9027836SJohn.Forte@Sun.COM 
9037836SJohn.Forte@Sun.COM 	for (i = 0; i < size/4; i++) {
9047836SJohn.Forte@Sun.COM 		if (b1[i] != b2[i]) {
9057836SJohn.Forte@Sun.COM 			(void) printf("Word %d does not match b1=0x%x, "
9067836SJohn.Forte@Sun.COM 			    "b2=0x%x\n", i, b1[i], b2[i]);
9077836SJohn.Forte@Sun.COM 			return (1);
9087836SJohn.Forte@Sun.COM 		}
9097836SJohn.Forte@Sun.COM 	}
9107836SJohn.Forte@Sun.COM 	return (0);
9117836SJohn.Forte@Sun.COM 
9127836SJohn.Forte@Sun.COM }
9137836SJohn.Forte@Sun.COM 
9147836SJohn.Forte@Sun.COM int
do_sdtest11(int fd,nsc_size_t loops,nsc_size_t filesize,int h)9157836SJohn.Forte@Sun.COM do_sdtest11(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
9167836SJohn.Forte@Sun.COM {
9177836SJohn.Forte@Sun.COM 	int err = 0;
9187836SJohn.Forte@Sun.COM 	nsc_size_t i;
9197836SJohn.Forte@Sun.COM 	ssize_t r;
9207836SJohn.Forte@Sun.COM 	int buf3[MAXBUF];
9217836SJohn.Forte@Sun.COM 	int buf4[MAXBUF];
9227836SJohn.Forte@Sun.COM 	int timestamp;
9237836SJohn.Forte@Sun.COM 	time_t clock;
9247836SJohn.Forte@Sun.COM 	struct tm *tm;
9257836SJohn.Forte@Sun.COM 
9267836SJohn.Forte@Sun.COM 
9277836SJohn.Forte@Sun.COM 	/*
9287836SJohn.Forte@Sun.COM 	 * Test 9 will write a given pattern over and over Test 11 will read
9297836SJohn.Forte@Sun.COM 	 * same pattern and clear with timestamp data (MM:SS).
9307836SJohn.Forte@Sun.COM 	 */
9317836SJohn.Forte@Sun.COM 
9327836SJohn.Forte@Sun.COM 	clock = time(NULL);
9337836SJohn.Forte@Sun.COM 	tm  = localtime(&clock);
9347836SJohn.Forte@Sun.COM 	(void) ascftime((char *)&timestamp, "%M""%S", tm);
9357836SJohn.Forte@Sun.COM 
9367836SJohn.Forte@Sun.COM 	gen_data_known(buf1, bufsize, pattern[h]);
9377836SJohn.Forte@Sun.COM 	gen_data_known(buf4, bufsize, timestamp);
9387836SJohn.Forte@Sun.COM 	if ((loops > filesize / fba_num_bufsize) || (!loops))
9397836SJohn.Forte@Sun.COM 		loops = filesize / fba_num_bufsize;  /* entire disk */
9407836SJohn.Forte@Sun.COM 
9417836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
9427836SJohn.Forte@Sun.COM 		r = pread(fd, buf3, bufsize,
9437836SJohn.Forte@Sun.COM 		    (off_t)(i*fba_num_bufsize) << SCTRSHFT);
9447836SJohn.Forte@Sun.COM 		if (r <= 0) {
9457836SJohn.Forte@Sun.COM 			perror("Test11: read");
9467836SJohn.Forte@Sun.COM 			err++;
9477836SJohn.Forte@Sun.COM 			return (err);
9487836SJohn.Forte@Sun.COM 		}
9497836SJohn.Forte@Sun.COM 		if (buffcmp(buf1, buf3, bufsize)) {
9507836SJohn.Forte@Sun.COM 			(void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT
9517836SJohn.Forte@Sun.COM 			", len:%d\n", name[h], i, bufsize);
9527836SJohn.Forte@Sun.COM 			err++;
9537836SJohn.Forte@Sun.COM 			return (err);
9547836SJohn.Forte@Sun.COM 		}
9557836SJohn.Forte@Sun.COM 		r = pwrite(fd, buf4, bufsize,
9567836SJohn.Forte@Sun.COM 		    (off_t)(i*fba_num_bufsize) << SCTRSHFT);
9577836SJohn.Forte@Sun.COM 		if (r <= 0) {
9587836SJohn.Forte@Sun.COM 			perror("Test11: write");
9597836SJohn.Forte@Sun.COM 			err++;
9607836SJohn.Forte@Sun.COM 			return (err);
9617836SJohn.Forte@Sun.COM 		}
9627836SJohn.Forte@Sun.COM 	}
9637836SJohn.Forte@Sun.COM 	return (err);
9647836SJohn.Forte@Sun.COM }
9657836SJohn.Forte@Sun.COM 
9667836SJohn.Forte@Sun.COM int
do_sdtest12(int fd,nsc_size_t loops,nsc_size_t filesize,int h)9677836SJohn.Forte@Sun.COM do_sdtest12(int fd, nsc_size_t loops, nsc_size_t filesize, int h)
9687836SJohn.Forte@Sun.COM {
9697836SJohn.Forte@Sun.COM 	int err = 0;
9707836SJohn.Forte@Sun.COM 	nsc_size_t i;
9717836SJohn.Forte@Sun.COM 	ssize_t r;
9727836SJohn.Forte@Sun.COM 	int buf3[MAXBUF];
9737836SJohn.Forte@Sun.COM 
9747836SJohn.Forte@Sun.COM 	/*
9757836SJohn.Forte@Sun.COM 	 * Test 9 will write a given pattern over and over Test 12 will read
9767836SJohn.Forte@Sun.COM 	 * same pattern
9777836SJohn.Forte@Sun.COM 	 */
9787836SJohn.Forte@Sun.COM 
9797836SJohn.Forte@Sun.COM 	gen_data_known(buf1, bufsize, pattern[h]);
9807836SJohn.Forte@Sun.COM 	if ((loops > filesize / fba_num_bufsize) || (!loops))
9817836SJohn.Forte@Sun.COM 		loops = filesize / fba_num_bufsize;  /* entire disk */
9827836SJohn.Forte@Sun.COM 
9837836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
9847836SJohn.Forte@Sun.COM 		r = pread(fd, buf3, bufsize,
9857836SJohn.Forte@Sun.COM 		    (off_t)(i*fba_num_bufsize) << SCTRSHFT);
9867836SJohn.Forte@Sun.COM 		if (r <= 0) {
9877836SJohn.Forte@Sun.COM 			perror("Test12: read");
9887836SJohn.Forte@Sun.COM 			err++;
9897836SJohn.Forte@Sun.COM 			return (err);
9907836SJohn.Forte@Sun.COM 		}
9917836SJohn.Forte@Sun.COM 		if (buffcmp(buf1, buf3, bufsize)) {
9927836SJohn.Forte@Sun.COM 			(void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT
9937836SJohn.Forte@Sun.COM 			", len:%d\n", name[h], i, bufsize);
9947836SJohn.Forte@Sun.COM 			err++;
9957836SJohn.Forte@Sun.COM 			return (err);
9967836SJohn.Forte@Sun.COM 		}
9977836SJohn.Forte@Sun.COM 	}
9987836SJohn.Forte@Sun.COM 	return (err);
9997836SJohn.Forte@Sun.COM }
10007836SJohn.Forte@Sun.COM 
10017836SJohn.Forte@Sun.COM #ifdef lint
10027836SJohn.Forte@Sun.COM int
sd_diag_lintmain(int argc,char * argv[])10037836SJohn.Forte@Sun.COM sd_diag_lintmain(int argc, char *argv[])
10047836SJohn.Forte@Sun.COM #else
10057836SJohn.Forte@Sun.COM int
10067836SJohn.Forte@Sun.COM main(int argc, char *argv[])
10077836SJohn.Forte@Sun.COM #endif
10087836SJohn.Forte@Sun.COM {
10097836SJohn.Forte@Sun.COM 	int procs;
10107836SJohn.Forte@Sun.COM 	nsc_size_t filesize, filesize2;
10117836SJohn.Forte@Sun.COM 	int fd, fd2, r, id, h, i;
10127836SJohn.Forte@Sun.COM 	nsc_fd_t *sdfd, *sdfd2;
10137836SJohn.Forte@Sun.COM 
10147836SJohn.Forte@Sun.COM 	if (argc < 2) {
10157836SJohn.Forte@Sun.COM 		print_usage();
10167836SJohn.Forte@Sun.COM 		exit(0);
10177836SJohn.Forte@Sun.COM 	}
1018*11576SSurya.Prakki@Sun.COM 	(void) strcpy(config_file, DISKLIST);
10197836SJohn.Forte@Sun.COM 	parse_opts(argc, argv);
10207836SJohn.Forte@Sun.COM 
10217836SJohn.Forte@Sun.COM 	_nsc_nocheck();
10227836SJohn.Forte@Sun.COM 	if ((procs = read_parts()) == 0)
10237836SJohn.Forte@Sun.COM 		exit(0);
10247836SJohn.Forte@Sun.COM 
10257836SJohn.Forte@Sun.COM 	id = strtol(argv[optind], 0, 0);
10267836SJohn.Forte@Sun.COM 	if (id == 10) {
10277836SJohn.Forte@Sun.COM 		/*
10287836SJohn.Forte@Sun.COM 		 * each process gets 2 disks and copies disk1 to disk2,
10297836SJohn.Forte@Sun.COM 		 * then goes back and verifies that the two disks are
10307836SJohn.Forte@Sun.COM 		 * identical.
10317836SJohn.Forte@Sun.COM 		 */
10327836SJohn.Forte@Sun.COM 		if (procs < 2) {
10337836SJohn.Forte@Sun.COM 		(void) printf("%s requires having at least 2 disks for test "
10347836SJohn.Forte@Sun.COM 		    "#10.\n", config_file);
10357836SJohn.Forte@Sun.COM 		exit(0);
10367836SJohn.Forte@Sun.COM 		}
10377836SJohn.Forte@Sun.COM 
10387836SJohn.Forte@Sun.COM 	    for (h = 0; h < procs/2; h++) {
10397836SJohn.Forte@Sun.COM 		r = fork();
10407836SJohn.Forte@Sun.COM 		if (r == 0) {
10417836SJohn.Forte@Sun.COM 			srand(getpid());
10427836SJohn.Forte@Sun.COM 
10437836SJohn.Forte@Sun.COM 
10447836SJohn.Forte@Sun.COM 			if (!(sdfd = nsc_open(name[2*h], NSC_CACHE,
10457836SJohn.Forte@Sun.COM 					O_RDWR | Rflag))) {
10467836SJohn.Forte@Sun.COM 				(void) fprintf(stderr,
10477836SJohn.Forte@Sun.COM 				    "sd_diag: Error opening %s\n", name[2*h]);
10487836SJohn.Forte@Sun.COM 				exit(1);
10497836SJohn.Forte@Sun.COM 			}
10507836SJohn.Forte@Sun.COM 			fd = nsc_fileno(sdfd);
10517836SJohn.Forte@Sun.COM 			if (fd == -1) {
10527836SJohn.Forte@Sun.COM 				(void) fprintf(stderr,
10537836SJohn.Forte@Sun.COM 				    "sd_diag: Error opening %s\n", name[2*h]);
10547836SJohn.Forte@Sun.COM 				(void) nsc_close(sdfd);
10557836SJohn.Forte@Sun.COM 				exit(1);
10567836SJohn.Forte@Sun.COM 			}
10577836SJohn.Forte@Sun.COM 			filesize = set_part_size(name[2*h], sdfd);
10587836SJohn.Forte@Sun.COM 			if (!(sdfd2 = nsc_open(name[2*h+1], NSC_CACHE,
10597836SJohn.Forte@Sun.COM 					O_RDWR | Rflag))) {
10607836SJohn.Forte@Sun.COM 				(void) fprintf(stderr,
10617836SJohn.Forte@Sun.COM 				    "sd_diag: Error opening %s\n", name[2*h+1]);
10627836SJohn.Forte@Sun.COM 				exit(1);
10637836SJohn.Forte@Sun.COM 			}
10647836SJohn.Forte@Sun.COM 			fd2 = nsc_fileno(sdfd2);
10657836SJohn.Forte@Sun.COM 			if (fd2 == -1) {
10667836SJohn.Forte@Sun.COM 				(void) fprintf(stderr,
10677836SJohn.Forte@Sun.COM 				    "sd_diag: Error opening %s\n", name[2*h+1]);
10687836SJohn.Forte@Sun.COM 				(void) nsc_close(sdfd2);
10697836SJohn.Forte@Sun.COM 				exit(1);
10707836SJohn.Forte@Sun.COM 			}
10717836SJohn.Forte@Sun.COM 			filesize2 = set_part_size(name[2*h+1], sdfd2);
10727836SJohn.Forte@Sun.COM 			(void) sleep(2);
10737836SJohn.Forte@Sun.COM 			r = do_sdtest10(fd, fd2, loops, filesize, filesize2, h);
10747836SJohn.Forte@Sun.COM 
10757836SJohn.Forte@Sun.COM 			(void) printf("Partitions %s and %s, Test %d,"
10767836SJohn.Forte@Sun.COM 			    " Completed %d errors\n",
10777836SJohn.Forte@Sun.COM 			    name[2*h], name[2*h+1], id, r);
10787836SJohn.Forte@Sun.COM 			(void) nsc_close(sdfd);
10797836SJohn.Forte@Sun.COM 			(void) nsc_close(sdfd2);
10807836SJohn.Forte@Sun.COM 			exit(0);
10817836SJohn.Forte@Sun.COM 		} else if (r == -1) {
10827836SJohn.Forte@Sun.COM 			perror("fork");
10837836SJohn.Forte@Sun.COM 			break;
10847836SJohn.Forte@Sun.COM 		} else
10857836SJohn.Forte@Sun.COM 			continue;
10867836SJohn.Forte@Sun.COM 	    } /* for */
10877836SJohn.Forte@Sun.COM 	    for (i = 0; i < h; i++)
1088*11576SSurya.Prakki@Sun.COM 		(void) wait(0);
10897836SJohn.Forte@Sun.COM 	} else {
10907836SJohn.Forte@Sun.COM 
10917836SJohn.Forte@Sun.COM 	for (h = 0; h < procs; h++) {
10927836SJohn.Forte@Sun.COM 		r = fork();
10937836SJohn.Forte@Sun.COM 		if (r == 0) {
10947836SJohn.Forte@Sun.COM 			srand(getpid());
10957836SJohn.Forte@Sun.COM 
10967836SJohn.Forte@Sun.COM 			id = strtol(argv[optind], 0, 0);
10977836SJohn.Forte@Sun.COM 			if (!(sdfd = nsc_open(name[h], NSC_CACHE,
10987836SJohn.Forte@Sun.COM 					O_RDWR | Rflag))) {
10997836SJohn.Forte@Sun.COM 				(void) fprintf(stderr,
11007836SJohn.Forte@Sun.COM 				    "sd_diag: Error opening %s\n", name[h]);
11017836SJohn.Forte@Sun.COM 				exit(1);
11027836SJohn.Forte@Sun.COM 			}
11037836SJohn.Forte@Sun.COM 			fd = nsc_fileno(sdfd);
11047836SJohn.Forte@Sun.COM 
11057836SJohn.Forte@Sun.COM 			if (fd == -1) {
11067836SJohn.Forte@Sun.COM 				(void) fprintf(stderr,
11077836SJohn.Forte@Sun.COM 				    "sd_diag: Error opening %s\n", name[h]);
11087836SJohn.Forte@Sun.COM 				(void) nsc_close(sdfd);
11097836SJohn.Forte@Sun.COM 				exit(1);
11107836SJohn.Forte@Sun.COM 			}
11117836SJohn.Forte@Sun.COM 			filesize = set_part_size(name[h], sdfd);
11127836SJohn.Forte@Sun.COM 
11137836SJohn.Forte@Sun.COM 			(void) sleep(2);
11147836SJohn.Forte@Sun.COM 
11157836SJohn.Forte@Sun.COM 
11167836SJohn.Forte@Sun.COM 			switch (id) {
11177836SJohn.Forte@Sun.COM 			    case 1:
11187836SJohn.Forte@Sun.COM 				r = do_sdtest1(fd, r_loops, filesize);
11197836SJohn.Forte@Sun.COM 				break;
11207836SJohn.Forte@Sun.COM 			    case 2:
11217836SJohn.Forte@Sun.COM 				r = do_sdtest2(fd, r_loops, filesize, h);
11227836SJohn.Forte@Sun.COM 				break;
11237836SJohn.Forte@Sun.COM 			    case 3:
11247836SJohn.Forte@Sun.COM 				r = do_sdtest3(fd, r_loops, filesize, h, sdfd);
11257836SJohn.Forte@Sun.COM 				break;
11267836SJohn.Forte@Sun.COM 			    case 4:
11277836SJohn.Forte@Sun.COM 				r = do_sdtest4(fd, loops, filesize);
11287836SJohn.Forte@Sun.COM 				break;
11297836SJohn.Forte@Sun.COM 			    case 5:
11307836SJohn.Forte@Sun.COM 				r = do_sdtest5(fd, loops, filesize, h);
11317836SJohn.Forte@Sun.COM 				break;
11327836SJohn.Forte@Sun.COM 			    case 6:
11337836SJohn.Forte@Sun.COM 				r = do_sdtest6(fd, loops, filesize, h);
11347836SJohn.Forte@Sun.COM 				break;
11357836SJohn.Forte@Sun.COM 			    case 7:
11367836SJohn.Forte@Sun.COM 				r = do_sdtest7(fd, r_loops, filesize, h, sdfd);
11377836SJohn.Forte@Sun.COM 				break;
11387836SJohn.Forte@Sun.COM 			    case 8:
11397836SJohn.Forte@Sun.COM 				r = do_sdtest8(fd, r_loops, filesize);
11407836SJohn.Forte@Sun.COM 				break;
11417836SJohn.Forte@Sun.COM 			    case 9:
11427836SJohn.Forte@Sun.COM 				r = do_sdtest9(fd, loops, filesize, h);
11437836SJohn.Forte@Sun.COM 				break;
11447836SJohn.Forte@Sun.COM 			    case 11:
11457836SJohn.Forte@Sun.COM 				r = do_sdtest11(fd, loops, filesize, h);
11467836SJohn.Forte@Sun.COM 				break;
11477836SJohn.Forte@Sun.COM 			    case 12:
11487836SJohn.Forte@Sun.COM 				r = do_sdtest12(fd, loops, filesize, h);
11497836SJohn.Forte@Sun.COM 				break;
11507836SJohn.Forte@Sun.COM 			    default:
11517836SJohn.Forte@Sun.COM 				break;
11527836SJohn.Forte@Sun.COM 			}
11537836SJohn.Forte@Sun.COM 
11547836SJohn.Forte@Sun.COM 			(void) printf("Partition %s, Test %d, Completed %d "
11557836SJohn.Forte@Sun.COM 			    "errors\n", name[h], id, r);
11567836SJohn.Forte@Sun.COM 			(void) nsc_close(sdfd);
11577836SJohn.Forte@Sun.COM 			exit(r ? 1 : 0);
11587836SJohn.Forte@Sun.COM 		} else if (r == -1) {
11597836SJohn.Forte@Sun.COM 			perror("fork");
11607836SJohn.Forte@Sun.COM 			break;
11617836SJohn.Forte@Sun.COM 		} else
11627836SJohn.Forte@Sun.COM 			continue;
11637836SJohn.Forte@Sun.COM 	}
11647836SJohn.Forte@Sun.COM 	for (i = 0; i < h; i++)
1165*11576SSurya.Prakki@Sun.COM 		(void) wait(0);
11667836SJohn.Forte@Sun.COM 	}
11677836SJohn.Forte@Sun.COM 
11687836SJohn.Forte@Sun.COM 	return (0);
11697836SJohn.Forte@Sun.COM }
1170