1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include "nfsgen.h"
28
29 char *testname;
30
31 #define TESTCASE "Stress test open(), write(), read() unlink()\n\t "
32 #define MIN(a, b) ((a) < (b) ? (a) : (b))
33 #define BUFF_32k (1024*32)
34
35 void usage(int);
36 void fill_buffer(char *, int);
37
38
39 /*
40 * Prints out the usage message and exits with the
41 * passed in exit code "ec"
42 */
43 void
44 usage(int ec)
45 {
46 printf("\t Test UNINITIATED: ");
47 printf("usage: %s -F -T <tc_run> -Q <tc_nap> -I <tc_iter> \n"
48 "\t -d <dbg> -f <filenamae> -s <fsize>\n", testname);
49 puts("\t -F Turn on O_SYNC flag.\n");
50 puts("\t -T <tc_run> Number of testcase runs to execute\n");
51 puts("\t -Q <tc_nap> Inter-testcase run sleep period \n");
52 puts("\t -I <tc_iter> Total number of tests per run to execute\n");
53 puts("\t -d <dbg> Information level: 0 - none \n"
54 "\t 1 - errors \n"
55 "\t 2 - errors and debug\n");
56 puts("\t -f <filename> The filename to use for testing\n");
57 puts("\t -s <fsize> Size of file to create\n");
58
59 exit(ec);
60 }
61
62 /*
63 * Given a buffer pointer "ptr" fill it with a numerically
64 * increasing byte value for its "size"
65 */
66 void
67 fill_buffer(char *ptr, int size)
68 {
69 int i;
70
71 for (i = 0; i < size; i++) {
72 ptr[i] = (i & 0xff);
73 }
74 }
75
76
77 /*
78 * Main test loop.
79 */
80 int
81 main(int argc, char *argv[])
82 {
83 extern int optind;
84 extern char *optarg;
85
86 char buffy[BUFF_32k];
87 char yffub[BUFF_32k];
88
89 char *buf, *filename = NULL;
90 int c, active_iter = 0, nap_time = 0, runs = 0, total_runs = 0;
91 int file_size = BUFF_32k;
92 int file_flags = (O_CREAT|O_TRUNC|O_RDWR);
93
94 testname = argv[0];
95 printf("\n %s: ", testname);
96 while ((c = getopt(argc, argv, "FT:Q:I:u:d:f:s:")) != -1) {
97 switch (c) {
98
99 /* number of testcase runs to perform */
100 case 'T':
101 runs = atoi(optarg);
102 break;
103
104 /* time in seconds to nap in between runs */
105 case 'Q':
106 nap_time = atoi(optarg);
107 break;
108
109 /* number of testcase runs before we nap */
110 case 'I':
111 active_iter = atoi(optarg);
112 break;
113
114 case 's':
115 file_size = atoi(optarg);
116 break;
117
118 case 'f':
119 filename = optarg;
120 break;
121
122 case 'F':
123 file_flags |= O_SYNC;
124 break;
125
126 case 'd':
127 switch (atoi(optarg)) {
128 case 0:
129 debug = 0;
130 showerror = 0;
131 break;
132 case 1:
133 debug = 0;
134 showerror = 1;
135 break;
136 case 2:
137 debug = 1;
138 showerror = 1;
139 break;
140 default:
141 usage(-1);
142 }
143 break;
144
145 case 'h':
146 usage(0);
147 break;
148 default:
149 usage(-1);
150 }
151 }
152
153 if (filename == NULL) {
154 usage(-1);
155 }
156
157 fill_buffer(buffy, BUFF_32k);
158
159 starttime(TESTCASE);
160
161 /*
162 * For "total_runs" do "active_iter" iterations of the
163 * testcase with a potential "nap_time" in-between.
164 */
165 do {
166 c = active_iter;
167 do {
168 int fd, blk, rc, wc, fs = file_size;
169
170 /*
171 * create and open a file
172 */
173 if ((fd = open_file(filename, file_flags, 0777)) < 0) {
174 return (NOOK);
175 }
176
177 /*
178 * now wack out "file_size" bytes from buffy
179 * to the file
180 */
181 do {
182 wc = MIN(fs, BUFF_32k);
183 if ((rc = write(fd, buffy, wc)) != wc) {
184 fprintf(stderr, "\t Test FAIL: ");
185 Perror("write():");
186 close_file(fd, filename);
187 return (NOOK);
188 }
189 fs -= wc;
190 } while (fs);
191
192 /*
193 * invalidate the client pages
194 */
195 if (dirtyfile(fd, filename, file_size) != OK) {
196 fprintf(stderr,
197 "\t Test FAIL: dirtyfile() failed");
198 close_file(fd, filename);
199 return (NOOK);
200 }
201
202 /*
203 * read the file back from
204 * the server and validate
205 */
206 fs = file_size;
207 blk = 0;
208
209 if (pos_file(fd, 0) != 0) {
210 fprintf(stderr, "\t Test FAIL: ");
211 eprint("file rewind filed\n");
212 close_file(fd, filename);
213 return (NOOK);
214 }
215
216 do {
217 /*
218 * compare in 32k blocks.
219 */
220 wc = MIN(fs, BUFF_32k);
221
222 if ((rc = read(fd, yffub, wc)) != wc) {
223 fprintf(stderr, "\t Test FAIL: ");
224 Perror("read():");
225 close_file(fd, filename);
226 return (NOOK);
227 }
228
229 if ((rc = memcmp(buffy, yffub, wc)) != 0) {
230 fprintf(stderr, "\t Test FAIL: ");
231 eprint("written != read in blk @ %d\n",
232 rc, blk);
233 close_file(fd, filename);
234 return (NOOK);
235 }
236 blk += wc;
237 fs -= wc;
238 } while (fs);
239
240 close_file(fd, filename);
241 unlink_file(filename);
242 total_runs++;
243 } while (--c > 0);
244
245 /* Lets take a nap if user sez so.. */
246 if (nap_time)
247 sleep(nap_time);
248 } while (--runs > 0);
249
250 printf("\t Test PASS: ");
251 printf("%s completed %d execution runs.\n", testname, total_runs);
252 endtime(" ");
253
254 return (OK);
255 }