4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* #include <version.h> SKK */
29 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/inttypes.h>
41 #include <sys/nsctl/sd_cache.h>
42 #include <sys/nsctl/sd_conf.h>
48 #define MAXPARTS 100 /* Max disks */
49 #define MAXBUF 65536 /* Max buffer size in long words */
50 #define DISKLIST "disk_config" /* Default config file */
51 #define DEF_SIZE 8192 /* Default buffer size */
52 #define DEF_LOOP 1000 /* Loops for test */
53 #define RAND_LOOPS DEF_LOOP /* # of random ios to do */
56 * >>>>>>>>> USER LEVEL SD CACHE DIAGNOSTICS <<<<<<<<<<
58 * Write and read data blocks w/multiple processes
59 * Starts one process for each partition specified in
65 char name
[MAXPARTS
][80];
66 int pattern
[MAXPARTS
];
67 int bufsize
= DEF_SIZE
;
69 nsc_size_t loops
= DEF_LOOP
;
70 nsc_size_t r_loops
= RAND_LOOPS
;
83 dfile
= fopen(config_file
, "r");
85 (void) printf("cannot open file: %s\n", config_file
);
89 for (i
= 0; i
< MAXPARTS
; i
++) {
90 if (fscanf(dfile
, "%s %x", name
[i
], (uint_t
*)&pattern
[i
]) ==
94 if (name
[i
][0] == '#' || strchr(name
[i
], '/') == NULL
) {
100 (void) fclose(dfile
);
101 (void) printf("No. of partitions listed in file '%s' = %d\n\n",
102 config_file
, partitions
);
109 (void) printf("Usage:\n");
111 "sd_diag [-R] [-b <bufsize>] [-d <datasize>] [-l <loops>] [-r <readers>]\n");
113 " [-f <disk_config_file>] <test#>\n");
114 (void) printf(" test 1 = random read/write\n");
115 (void) printf(" 2 = random read/write/verify, read after write\n");
116 (void) printf(" 3 = random read/write/verify,");
117 (void) printf(" all reads after all writes\n");
118 (void) printf(" 4 = sequential read/write\n");
119 (void) printf(" 5 = sequential write/read/verify,");
120 (void) printf(" all reads after all writes\n");
122 " 6 = altenating top/bottom sequential read/write/verify\n");
123 (void) printf(" 7 = multiple readers/1 random writer\n");
124 (void) printf(" 8 = random writes\n");
125 (void) printf(" 9 = sequential write of known data\n");
126 (void) printf(" 10 = sequential copy of datasize disk/verify\n");
127 (void) printf(" 11 = sequential read/verify test 9 data -");
128 (void) printf(" then clear data with timestamp\n");
129 (void) printf(" 12 = sequential read/verify test 9 data -");
130 (void) printf(" no clear data\n");
132 (void) printf(" <bufsize> in bytes (minimum is 512 bytes)\n");
133 (void) printf(" <datasize> in Mbytes per disk\n");
134 (void) printf(" <loops> is count of reads/writes,\n");
135 (void) printf(" loops = 0 tests entire datasize disk");
136 (void) printf(" for sequential tests.\n");
137 (void) printf(" loops = 0 performs %d I/Os for the random "
138 "tests\n", RAND_LOOPS
);
139 (void) printf(" <readers> is count of readers for test #7 (default "
141 (void) printf(" [ defaults: bufsize = %d bytes, loops = %d,",
143 (void) printf(" datasize = disksize ]\n");
145 (void) printf(" -R : do nsc_reserve(), nsc_release(0 around each "
150 parse_opts(int argc
, char *argv
[])
155 while ((c
= getopt(argc
, argv
, "b:d:l:r:Rf:")) != -1) {
158 /* printf("\n%s", optarg); */
159 (void) strcpy(config_file
, optarg
);
162 /* bufsize between 1*512 and 512*512 */
163 bufsize
= strtol(optarg
, 0, 0);
164 if (bufsize
> (MAXBUF
*4))
166 else if (bufsize
< FBA_SIZE(1))
167 bufsize
= FBA_SIZE(1);
170 /* convert datasize from Mb's to fba */
171 fsize
= strtol(optarg
, 0, 0) * FBA_NUM(1 << 20);
174 loops
= (nsc_size_t
)strtoll(optarg
, 0, 0);
177 /* count of readers for test 7 */
178 readercount
= strtol(optarg
, 0, 0);
181 /* do reserve, release on a per io basis */
189 bufsize
&= ~FBA_MASK
; /* multiple of 512 bytes for SECTMODE I/O */
190 fba_num_bufsize
= FBA_NUM(bufsize
);
192 /* set #ios for random io tests */
199 set_part_size(char *path
, nsc_fd_t
*sdfd
)
204 rc
= nsc_partsize(sdfd
, &filesize
); /* partsize in FBAs (512 bytes) */
205 if (rc
< 0 || filesize
== 0) {
206 (void) fprintf(stderr
,
207 "set_part_size: cannot access partition size");
208 (void) fprintf(stderr
, " for %s\n", path
);
209 (void) nsc_close(sdfd
);
213 (void) printf("Partition %s, size:%" NSC_SZFMT
" blocks\n", path
,
216 if (fsize
!= -1 && fsize
< filesize
)
218 filesize
-= fba_num_bufsize
;
219 if (filesize
< fba_num_bufsize
) {
220 (void) printf("ERROR: Max block size %" NSC_SZFMT
"\n",
222 (void) nsc_close(sdfd
);
230 do_sdtest1(int fd
, nsc_size_t loops
, nsc_size_t filesize
)
236 for (i
= 0; i
< loops
; i
++) {
238 #ifdef NSC_MULTI_TERABYTE
239 ((nsc_off_t
)rand() << 48) | ((nsc_off_t
)rand() << 32) |
241 (rand() << 16) | rand()) % filesize
;
242 r
= pwrite(fd
, buf1
, bufsize
, (off_t
)(seekpos
<< SCTRSHFT
));
244 perror("Test1: write");
248 #ifdef NSC_MULTI_TERABYTE
249 ((nsc_off_t
)rand() << 48) | ((nsc_off_t
)rand() << 32) |
251 (rand() << 16) | rand()) % filesize
;
252 r
= pread(fd
, buf2
, bufsize
, (off_t
)(seekpos
<< SCTRSHFT
));
254 perror("Test1: read");
262 gen_data(int *buffer
, int size
)
267 for (i
= 0; i
< size
; i
++)
268 buffer
[i
] = rand() << 16 | rand();
272 do_sdtest2(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
)
279 for (i
= 0; i
< loops
; i
++) {
281 #ifdef NSC_MULTI_TERABYTE
282 ((nsc_off_t
)rand() << 48) | ((nsc_off_t
)rand() << 32) |
284 (rand() << 16) | rand()) % filesize
;
285 gen_data(buf1
, bufsize
);
286 r
= pwrite(fd
, buf1
, bufsize
, (off_t
)(seekpos
<< SCTRSHFT
));
288 perror("Test2: write");
292 r
= pread(fd
, buf2
, bufsize
, (off_t
)(seekpos
<< SCTRSHFT
));
294 perror("Test2: read");
298 if (memcmp(buf1
, buf2
, bufsize
)) {
299 (void) printf("Test2: Data corruption,"
300 " fd:%s, fpos:%" PRId64
", len:%d\n",
301 name
[h
], (int64_t)(seekpos
<< SCTRSHFT
),
310 do_sdtest3(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
, nsc_fd_t
*sdfd
)
317 seekpos
= malloc(loops
*sizeof (nsc_off_t
));
318 if (seekpos
== NULL
) {
319 perror("Test3: malloc");
320 (void) nsc_close(sdfd
);
323 gen_data(buf1
, bufsize
);
325 for (i
= 0; i
< loops
; i
++) {
327 #ifdef NSC_MULTI_TERABYTE
328 ((nsc_off_t
)rand() << 48) | ((nsc_off_t
)rand() << 32) |
330 (rand() << 16) | rand()) % filesize
;
331 seekpos
[i
] -= seekpos
[i
] % fba_num_bufsize
;
332 r
= pwrite(fd
, buf1
, bufsize
, (off_t
)(seekpos
[i
] << SCTRSHFT
));
334 perror("Test3: write");
339 for (i
= 0; i
< loops
; i
++) {
340 buf2
[0] = '\0'; /* clear buf to make sure something is read */
341 r
= pread(fd
, buf2
, bufsize
, (off_t
)(seekpos
[i
] << SCTRSHFT
));
343 perror("Test3: read");
347 if (memcmp(buf1
, buf2
, bufsize
)) {
348 (void) printf("Data corruption, fd:%s, fpos:%" PRId64
349 ", len:%d\n", name
[h
],
350 (int64_t)(seekpos
[i
] << SCTRSHFT
), bufsize
);
361 do_sdtest4(int fd
, nsc_size_t loops
, nsc_size_t filesize
)
367 * Do sequential reads/writes for loops number
368 * of bufsize chunks, unless loops == 0, then do
370 * 1. sequential reads from the top down,
371 * 2. sequential writes from the top down,
372 * 3. sequential reads from the bottom up,
373 * 4. sequential writes from the bottom up.
375 if ((loops
> (filesize
/ fba_num_bufsize
)) || (!loops
))
376 loops
= filesize
/ fba_num_bufsize
; /* entire disk */
378 for (i
= 0; i
< loops
; i
++) {
379 r
= pread(fd
, buf2
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
381 perror("Test4: read");
385 for (i
= 0; i
< loops
; i
++) {
386 r
= pwrite(fd
, buf1
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
388 perror("Test4: write");
392 for (i
= loops
- 1; i
+ 1 > 0; i
--) {
393 r
= pread(fd
, buf2
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
395 perror("Test4: read");
399 for (i
= loops
- 1; i
+ 1 > 0; i
--) {
400 r
= pwrite(fd
, buf1
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
402 perror("Test4: write");
410 do_sdtest5(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
)
417 * Do sequential writes with verify reads for loops number
418 * of bufsize chunks, unless loops == 0, then do
420 * 1. sequential writes from the top down,
421 * 2. sequential reads from the top down with verify,
422 * 3. sequential writes from the bottom up,
423 * 4. sequential reads from the bottom up with verify.
425 if ((loops
> (filesize
/ fba_num_bufsize
)) || (!loops
))
426 loops
= filesize
/ fba_num_bufsize
; /* entire disk */
428 gen_data(buf1
, bufsize
);
430 for (i
= 0; i
< loops
; i
++) {
431 r
= pwrite(fd
, buf1
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
433 perror("Test5: write");
438 for (i
= 0; i
< loops
; i
++) {
439 buf2
[0] = '\0'; /* clear buf to make sure something is read */
440 r
= pread(fd
, buf2
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
442 perror("Test5: read");
446 if (memcmp(buf1
, buf2
, bufsize
)) {
447 (void) printf("Test5: Data corruption,"
448 " fd:%s, fpos:%" NSC_SZFMT
", len:%d\n",
449 name
[h
], i
, bufsize
);
454 gen_data(buf1
, bufsize
);
456 for (i
= loops
- 1; i
+ 1 > 0; i
--) {
457 r
= pwrite(fd
, buf1
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
459 perror("Test5: write");
464 for (i
= loops
- 1; i
+ 1 > 0; i
--) {
465 buf2
[0] = '\0'; /* clear buf to make sure something is read */
466 r
= pread(fd
, buf2
, bufsize
, (i
*fba_num_bufsize
) << SCTRSHFT
);
468 perror("Test5: read");
472 if (memcmp(buf1
, buf2
, bufsize
)) {
473 (void) printf("Test5: Data corruption,"
474 " fd:%s, fpos:%" NSC_SZFMT
", len:%d\n",
475 name
[h
], i
, bufsize
);
484 do_sdtest6(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
)
489 nsc_size_t endloop
= filesize
/ fba_num_bufsize
;
492 nsc_off_t top_pos
, bottom_pos
;
495 * Do alternating top down and bottom up sequential writes
496 * (working towards middle) and verify with reads
497 * for loops number of bufsize chunks, unless loops == 0, then do
500 if ((loops
> (filesize
/ fba_num_bufsize
)) || (!loops
))
501 loops
= filesize
/ fba_num_bufsize
; /* entire disk */
503 for (i
= 0; i
< loops
; i
++) {
504 gen_data(buf1
, bufsize
);
505 bottom_pos
= i
*fba_num_bufsize
;
506 r
= pwrite(fd
, buf1
, bufsize
, (off_t
)(bottom_pos
<< SCTRSHFT
));
508 perror("Test6: write");
512 gen_data(buf2
, bufsize
);
513 top_pos
= (endloop
- i
- 1)*fba_num_bufsize
;
515 /* Make sure we don't collide in the middle */
517 if (abs(top_pos
- bottom_pos
) < fba_num_bufsize
)
518 top_pos
= bottom_pos
+ fba_num_bufsize
;
520 r
= pwrite(fd
, buf2
, bufsize
, (off_t
)(top_pos
<< SCTRSHFT
));
522 perror("Test6: write");
526 r
= pread(fd
, buf3
, bufsize
, (off_t
)(bottom_pos
<< SCTRSHFT
));
528 perror("Test6: read");
532 if (memcmp(buf1
, buf3
, bufsize
)) {
533 (void) printf("Data corruption(1), fd:%s, fpos:%"
534 PRId64
", len:%d\n", name
[h
],
535 (int64_t)(bottom_pos
<< SCTRSHFT
), bufsize
);
538 r
= pread(fd
, buf4
, bufsize
, (off_t
)(top_pos
<< SCTRSHFT
));
540 perror("Test6: read");
543 if (memcmp(buf2
, buf4
, bufsize
)) {
544 (void) printf("Test6: Data corruption(2),"
545 " fd:%s, fpos:%" PRId64
", len:%d\n",
546 name
[h
], (int64_t)(top_pos
<< SCTRSHFT
), bufsize
);
555 #define MAXREADERS 32
558 int writebuf
[MAXBUF
];
559 volatile nsc_off_t writepos
;
563 int rd_done
[MAXREADERS
];
564 int rd_done_mask
[MAXREADERS
];
567 #define WRITEBUF (shm->writebuf)
568 #define WRITEPOS (shm->writepos)
570 #define QUIT (shm->quit)
571 #define ERR (shm->err)
572 #define ERRMUTEX (shm->err_mutex)
573 #define RD_DONE (shm->rd_done)
574 #define RD_DONE_MASK (shm->rd_done_mask)
579 /* Clear RD_DONE and Set WRITEPOS */
580 #define FREEWRITE { \
581 bzero(RD_DONE, sizeof (RD_DONE)); \
584 /* Reader i+1 marks himself as finished */
585 #define FREEREAD(i) (RD_DONE[(i)] = 1)
589 do_sdtest7read(int fd
, int h
, int which
)
595 err
= 0; curr_pos
= 0; loop_cnt
= 0;
597 /* Already read this? */
598 if (curr_pos
== WRITEPOS
) {
603 /* printf("Quitting [%d]\n", which+1); */
608 /* get location to read from */
611 r_rd
= pread(fd
, buf1
, bufsize
, (curr_pos
<< SCTRSHFT
));
615 perror("Test7: read");
620 if (memcmp(buf1
, WRITEBUF
, bufsize
)) {
622 (void) printf("\nTest7: Data corruption, reader #%d, "
624 fpos:%" PRId64
", len:%d\n", which
+ 1, name
[h
],
625 (int64_t)(curr_pos
<< SCTRSHFT
), bufsize
);
634 "Partition %s, Test 7, reader #%d: %d errors %lld loops\n",
635 name
[h
], which
+1, err
, loop_cnt
);
638 (void) mutex_lock(&ERRMUTEX
);
640 (void) mutex_unlock(&ERRMUTEX
);
651 do_sdtest7write(int fd
, nsc_size_t filesize
, int h
)
657 /* Wait for readers to finish */
658 while (memcmp(RD_DONE
, RD_DONE_MASK
, readercount
*sizeof (int)))
661 gen_data(WRITEBUF
, bufsize
);
663 #ifdef NSC_MULTI_TERABYTE
664 ((nsc_off_t
)rand() << 48) | ((nsc_off_t
)rand() << 32) |
666 (rand() << 16) | rand()) % filesize
;
667 r
= pwrite(fd
, WRITEBUF
, bufsize
, (off_t
)(wr_pos
<< SCTRSHFT
));
670 perror("Test7: write");
676 r
= pread(fd
, buf1
, bufsize
, (off_t
)(wr_pos
<< SCTRSHFT
));
678 perror("Test7: writer: read");
683 if (memcmp(buf1
, WRITEBUF
, bufsize
)) {
684 (void) printf("\nTest7: Data corruption in writer,"
685 " fd:%s, fpos:%" PRId64
", len:%d\n",
686 name
[h
], (int64_t)(wr_pos
<< SCTRSHFT
), bufsize
);
699 /* Clear out everything */
700 bzero(shm
, sizeof (struct shm_struct
));
702 (void) mutex_init(&ERRMUTEX
, USYNC_PROCESS
, NULL
);
704 /* Set up mask (constant) to test reader doneness */
705 for (i
= 0; i
< readercount
; i
++)
708 /* Mark all readers done - so writer can start */
709 for (i
= 0; i
< readercount
; i
++)
714 do_sdtest7(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
, nsc_fd_t
*sdfd
)
719 if ((shmid
= shmget(IPC_PRIVATE
, sizeof (struct shm_struct
),
720 IPC_CREAT
| 0666)) < 0) {
721 perror("shmget error: ");
722 (void) nsc_close(sdfd
);
726 shm
= (struct shm_struct
*)shmat(shmid
, NULL
, 0);
727 if (shm
== (struct shm_struct
*)-1) {
728 perror("shmat error: ");
729 (void) nsc_close(sdfd
);
730 exit(1); /* cleanup exits */
736 for (i
= 0; i
< readercount
; i
++) {
738 if (r
== 0) { /* child */
739 (void) do_sdtest7read(fd
, h
, i
);
740 (void) nsc_close(sdfd
);
747 srand(getpid()); err
= 0;
748 for (j
= 0; j
< loops
; j
++) {
749 err
+= do_sdtest7write(fd
, filesize
, h
);
753 (void) printf("\n\nPartition %s, Test 7, writer: %d errors\n",
756 for (i
= 0; i
< readercount
; i
++)
759 /* No lock needed here - everybody's finished */
762 (void) mutex_destroy(&ERRMUTEX
);
763 (void) shmctl(shmid
, IPC_RMID
, 0);
768 do_sdtest8(int fd
, nsc_size_t loops
, nsc_size_t filesize
)
775 for (i
= 0; i
< loops
; i
++) {
777 #ifdef NSC_MULTI_TERABYTE
778 ((nsc_off_t
)rand() << 48) | ((nsc_off_t
)rand() << 32) |
780 (rand() << 16) | rand()) % filesize
;
781 gen_data(buf1
, bufsize
);
782 r
= pwrite(fd
, buf1
, bufsize
, (off_t
)(seekpos
<< SCTRSHFT
));
784 perror("Test8: write");
793 gen_data_known(int *buffer
, int size
, int data
)
798 for (i
= 0; i
< size
; i
++)
803 do_sdtest9(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
)
807 nsc_off_t fba_offset
;
808 nsc_size_t i
, wrapval
;
811 * Test 9 will write a given pattern over and over Test 11 or
812 * Test 12 will read same pattern.
814 /* Large loop value that would cause write overflow will wrap */
816 gen_data_known(buf1
, bufsize
, pattern
[h
]);
818 wrapval
= filesize
/ fba_num_bufsize
;
821 loops
= wrapval
; /* entire disk */
823 for (i
= 0; i
< loops
; i
++) {
824 fba_offset
= i
% wrapval
;
825 r
= pwrite(fd
, buf1
, bufsize
,
826 (off_t
)(fba_offset
* fba_num_bufsize
) << SCTRSHFT
);
828 perror("Test9: write");
837 do_sdtest10(int fd1
, int fd2
, nsc_size_t loops
, nsc_size_t filesize1
,
838 nsc_size_t filesize2
, int h
)
846 * Do sequential copy of disk1 to disk2 for loops number
847 * of bufsize chunks, unless loops == 0, then copy size of
849 * Go back and verify that the two disks are identical.
852 filesize
= (filesize1
< filesize2
) ? filesize1
: filesize2
;
853 if ((loops
> (filesize
/ fba_num_bufsize
)) || (!loops
))
854 loops
= filesize
/ fba_num_bufsize
;
856 /* copy disk1 to to disk2 */
857 for (i
= 0; i
< loops
; i
++) {
858 r
= pread(fd1
, buf1
, bufsize
,
859 (off_t
)(i
*fba_num_bufsize
) << SCTRSHFT
);
861 perror("Test10: read");
864 r
= pwrite(fd2
, buf1
, bufsize
,
865 (off_t
)(i
*fba_num_bufsize
) << SCTRSHFT
);
867 perror("Test10: write");
872 /* verify disks are identical */
873 for (i
= 0; i
< loops
; i
++) {
874 buf1
[0] = '\0'; /* clear buf to make sure something is read */
875 r
= pread(fd1
, buf1
, bufsize
,
876 (off_t
)(i
* fba_num_bufsize
) << SCTRSHFT
);
878 perror("Test10: read");
881 buf2
[0] = 'x'; /* make sure something is read */
882 r
= pread(fd2
, buf2
, bufsize
,
883 (off_t
)(i
* fba_num_bufsize
) << SCTRSHFT
);
885 perror("Test10: read");
888 if (memcmp(buf1
, buf2
, bufsize
)) {
889 (void) printf("Test10: Data corruption,"
890 " fd1:%s, fd2:%s fpos:%" NSC_SZFMT
", len:%d\n",
891 name
[2*h
], name
[2*h
+1], i
, bufsize
);
899 buffcmp(int *b1
, int *b2
, int size
)
903 for (i
= 0; i
< size
/4; i
++) {
904 if (b1
[i
] != b2
[i
]) {
905 (void) printf("Word %d does not match b1=0x%x, "
906 "b2=0x%x\n", i
, b1
[i
], b2
[i
]);
915 do_sdtest11(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
)
928 * Test 9 will write a given pattern over and over Test 11 will read
929 * same pattern and clear with timestamp data (MM:SS).
933 tm
= localtime(&clock
);
934 (void) ascftime((char *)×tamp
, "%M""%S", tm
);
936 gen_data_known(buf1
, bufsize
, pattern
[h
]);
937 gen_data_known(buf4
, bufsize
, timestamp
);
938 if ((loops
> filesize
/ fba_num_bufsize
) || (!loops
))
939 loops
= filesize
/ fba_num_bufsize
; /* entire disk */
941 for (i
= 0; i
< loops
; i
++) {
942 r
= pread(fd
, buf3
, bufsize
,
943 (off_t
)(i
*fba_num_bufsize
) << SCTRSHFT
);
945 perror("Test11: read");
949 if (buffcmp(buf1
, buf3
, bufsize
)) {
950 (void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT
951 ", len:%d\n", name
[h
], i
, bufsize
);
955 r
= pwrite(fd
, buf4
, bufsize
,
956 (off_t
)(i
*fba_num_bufsize
) << SCTRSHFT
);
958 perror("Test11: write");
967 do_sdtest12(int fd
, nsc_size_t loops
, nsc_size_t filesize
, int h
)
975 * Test 9 will write a given pattern over and over Test 12 will read
979 gen_data_known(buf1
, bufsize
, pattern
[h
]);
980 if ((loops
> filesize
/ fba_num_bufsize
) || (!loops
))
981 loops
= filesize
/ fba_num_bufsize
; /* entire disk */
983 for (i
= 0; i
< loops
; i
++) {
984 r
= pread(fd
, buf3
, bufsize
,
985 (off_t
)(i
*fba_num_bufsize
) << SCTRSHFT
);
987 perror("Test12: read");
991 if (buffcmp(buf1
, buf3
, bufsize
)) {
992 (void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT
993 ", len:%d\n", name
[h
], i
, bufsize
);
1003 sd_diag_lintmain(int argc
, char *argv
[])
1006 main(int argc
, char *argv
[])
1010 nsc_size_t filesize
, filesize2
;
1011 int fd
, fd2
, r
, id
, h
, i
;
1012 nsc_fd_t
*sdfd
, *sdfd2
;
1018 (void) strcpy(config_file
, DISKLIST
);
1019 parse_opts(argc
, argv
);
1022 if ((procs
= read_parts()) == 0)
1025 id
= strtol(argv
[optind
], 0, 0);
1028 * each process gets 2 disks and copies disk1 to disk2,
1029 * then goes back and verifies that the two disks are
1033 (void) printf("%s requires having at least 2 disks for test "
1034 "#10.\n", config_file
);
1038 for (h
= 0; h
< procs
/2; h
++) {
1044 if (!(sdfd
= nsc_open(name
[2*h
], NSC_CACHE
,
1046 (void) fprintf(stderr
,
1047 "sd_diag: Error opening %s\n", name
[2*h
]);
1050 fd
= nsc_fileno(sdfd
);
1052 (void) fprintf(stderr
,
1053 "sd_diag: Error opening %s\n", name
[2*h
]);
1054 (void) nsc_close(sdfd
);
1057 filesize
= set_part_size(name
[2*h
], sdfd
);
1058 if (!(sdfd2
= nsc_open(name
[2*h
+1], NSC_CACHE
,
1060 (void) fprintf(stderr
,
1061 "sd_diag: Error opening %s\n", name
[2*h
+1]);
1064 fd2
= nsc_fileno(sdfd2
);
1066 (void) fprintf(stderr
,
1067 "sd_diag: Error opening %s\n", name
[2*h
+1]);
1068 (void) nsc_close(sdfd2
);
1071 filesize2
= set_part_size(name
[2*h
+1], sdfd2
);
1073 r
= do_sdtest10(fd
, fd2
, loops
, filesize
, filesize2
, h
);
1075 (void) printf("Partitions %s and %s, Test %d,"
1076 " Completed %d errors\n",
1077 name
[2*h
], name
[2*h
+1], id
, r
);
1078 (void) nsc_close(sdfd
);
1079 (void) nsc_close(sdfd2
);
1081 } else if (r
== -1) {
1087 for (i
= 0; i
< h
; i
++)
1091 for (h
= 0; h
< procs
; h
++) {
1096 id
= strtol(argv
[optind
], 0, 0);
1097 if (!(sdfd
= nsc_open(name
[h
], NSC_CACHE
,
1099 (void) fprintf(stderr
,
1100 "sd_diag: Error opening %s\n", name
[h
]);
1103 fd
= nsc_fileno(sdfd
);
1106 (void) fprintf(stderr
,
1107 "sd_diag: Error opening %s\n", name
[h
]);
1108 (void) nsc_close(sdfd
);
1111 filesize
= set_part_size(name
[h
], sdfd
);
1118 r
= do_sdtest1(fd
, r_loops
, filesize
);
1121 r
= do_sdtest2(fd
, r_loops
, filesize
, h
);
1124 r
= do_sdtest3(fd
, r_loops
, filesize
, h
, sdfd
);
1127 r
= do_sdtest4(fd
, loops
, filesize
);
1130 r
= do_sdtest5(fd
, loops
, filesize
, h
);
1133 r
= do_sdtest6(fd
, loops
, filesize
, h
);
1136 r
= do_sdtest7(fd
, r_loops
, filesize
, h
, sdfd
);
1139 r
= do_sdtest8(fd
, r_loops
, filesize
);
1142 r
= do_sdtest9(fd
, loops
, filesize
, h
);
1145 r
= do_sdtest11(fd
, loops
, filesize
, h
);
1148 r
= do_sdtest12(fd
, loops
, filesize
, h
);
1154 (void) printf("Partition %s, Test %d, Completed %d "
1155 "errors\n", name
[h
], id
, r
);
1156 (void) nsc_close(sdfd
);
1158 } else if (r
== -1) {
1164 for (i
= 0; i
< h
; i
++)