1*96c8483aSYuri Pankov /*
2*96c8483aSYuri Pankov * CDDL HEADER START
3*96c8483aSYuri Pankov *
4*96c8483aSYuri Pankov * The contents of this file are subject to the terms of the
5*96c8483aSYuri Pankov * Common Development and Distribution License (the "License").
6*96c8483aSYuri Pankov * You may not use this file except in compliance with the License.
7*96c8483aSYuri Pankov *
8*96c8483aSYuri Pankov * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*96c8483aSYuri Pankov * or http://www.opensolaris.org/os/licensing.
10*96c8483aSYuri Pankov * See the License for the specific language governing permissions
11*96c8483aSYuri Pankov * and limitations under the License.
12*96c8483aSYuri Pankov *
13*96c8483aSYuri Pankov * When distributing Covered Code, include this CDDL HEADER in each
14*96c8483aSYuri Pankov * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*96c8483aSYuri Pankov * If applicable, add the following below this CDDL HEADER, with the
16*96c8483aSYuri Pankov * fields enclosed by brackets "[]" replaced with your own identifying
17*96c8483aSYuri Pankov * information: Portions Copyright [yyyy] [name of copyright owner]
18*96c8483aSYuri Pankov *
19*96c8483aSYuri Pankov * CDDL HEADER END
20*96c8483aSYuri Pankov */
21*96c8483aSYuri Pankov
22*96c8483aSYuri Pankov /*
23*96c8483aSYuri Pankov * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*96c8483aSYuri Pankov */
25*96c8483aSYuri Pankov
26*96c8483aSYuri Pankov #include <stdio.h>
27*96c8483aSYuri Pankov #include <stdlib.h>
28*96c8483aSYuri Pankov #include <unistd.h>
29*96c8483aSYuri Pankov #include <limits.h>
30*96c8483aSYuri Pankov #include <errno.h>
31*96c8483aSYuri Pankov #include <fcntl.h>
32*96c8483aSYuri Pankov #include <sys/types.h>
33*96c8483aSYuri Pankov #include <sys/fcntl.h>
34*96c8483aSYuri Pankov #include <sys/stat.h>
35*96c8483aSYuri Pankov #include <sys/statvfs.h>
36*96c8483aSYuri Pankov #include <sys/errno.h>
37*96c8483aSYuri Pankov #include <sys/time.h>
38*96c8483aSYuri Pankov #include <sys/ioctl.h>
39*96c8483aSYuri Pankov #include <sys/wait.h>
40*96c8483aSYuri Pankov #include <sys/param.h>
41*96c8483aSYuri Pankov #include <string.h>
42*96c8483aSYuri Pankov
43*96c8483aSYuri Pankov #define FSIZE 256*1024*1024
44*96c8483aSYuri Pankov #define BSIZE 512
45*96c8483aSYuri Pankov
46*96c8483aSYuri Pankov /* Initialize Globals */
47*96c8483aSYuri Pankov static long fsize = FSIZE;
48*96c8483aSYuri Pankov static size_t bsize = BSIZE;
49*96c8483aSYuri Pankov static int count = 0;
50*96c8483aSYuri Pankov static int rflag = 0;
51*96c8483aSYuri Pankov static int seed = 0;
52*96c8483aSYuri Pankov static int vflag = 0;
53*96c8483aSYuri Pankov static int errflag = 0;
54*96c8483aSYuri Pankov static off_t offset = 0;
55*96c8483aSYuri Pankov static char *filename = NULL;
56*96c8483aSYuri Pankov
57*96c8483aSYuri Pankov static void usage(char *execname);
58*96c8483aSYuri Pankov static void parse_options(int argc, char *argv[]);
59*96c8483aSYuri Pankov static void do_write(int fd);
60*96c8483aSYuri Pankov static void do_trunc(int fd);
61*96c8483aSYuri Pankov
62*96c8483aSYuri Pankov static void
usage(char * execname)63*96c8483aSYuri Pankov usage(char *execname)
64*96c8483aSYuri Pankov {
65*96c8483aSYuri Pankov (void) fprintf(stderr,
66*96c8483aSYuri Pankov "usage: %s [-b blocksize] [-c count] [-f filesize]"
67*96c8483aSYuri Pankov " [-o offset] [-s seed] [-r] [-v] filename\n", execname);
68*96c8483aSYuri Pankov (void) exit(1);
69*96c8483aSYuri Pankov }
70*96c8483aSYuri Pankov
71*96c8483aSYuri Pankov int
main(int argc,char * argv[])72*96c8483aSYuri Pankov main(int argc, char *argv[])
73*96c8483aSYuri Pankov {
74*96c8483aSYuri Pankov int i = 0;
75*96c8483aSYuri Pankov int fd = -1;
76*96c8483aSYuri Pankov
77*96c8483aSYuri Pankov parse_options(argc, argv);
78*96c8483aSYuri Pankov
79*96c8483aSYuri Pankov fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
80*96c8483aSYuri Pankov if (fd < 0) {
81*96c8483aSYuri Pankov perror("open");
82*96c8483aSYuri Pankov exit(3);
83*96c8483aSYuri Pankov }
84*96c8483aSYuri Pankov
85*96c8483aSYuri Pankov while (i < count) {
86*96c8483aSYuri Pankov (void) do_write(fd);
87*96c8483aSYuri Pankov (void) do_trunc(fd);
88*96c8483aSYuri Pankov
89*96c8483aSYuri Pankov i++;
90*96c8483aSYuri Pankov }
91*96c8483aSYuri Pankov
92*96c8483aSYuri Pankov (void) close(fd);
93*96c8483aSYuri Pankov return (0);
94*96c8483aSYuri Pankov }
95*96c8483aSYuri Pankov
96*96c8483aSYuri Pankov static void
parse_options(int argc,char * argv[])97*96c8483aSYuri Pankov parse_options(int argc, char *argv[])
98*96c8483aSYuri Pankov {
99*96c8483aSYuri Pankov int c;
100*96c8483aSYuri Pankov
101*96c8483aSYuri Pankov extern char *optarg;
102*96c8483aSYuri Pankov extern int optind, optopt;
103*96c8483aSYuri Pankov
104*96c8483aSYuri Pankov count = fsize / bsize;
105*96c8483aSYuri Pankov seed = time(NULL);
106*96c8483aSYuri Pankov while ((c = getopt(argc, argv, "b:c:f:o:rs:v")) != -1) {
107*96c8483aSYuri Pankov switch (c) {
108*96c8483aSYuri Pankov case 'b':
109*96c8483aSYuri Pankov bsize = atoi(optarg);
110*96c8483aSYuri Pankov break;
111*96c8483aSYuri Pankov
112*96c8483aSYuri Pankov case 'c':
113*96c8483aSYuri Pankov count = atoi(optarg);
114*96c8483aSYuri Pankov break;
115*96c8483aSYuri Pankov
116*96c8483aSYuri Pankov case 'f':
117*96c8483aSYuri Pankov fsize = atoi(optarg);
118*96c8483aSYuri Pankov break;
119*96c8483aSYuri Pankov
120*96c8483aSYuri Pankov case 'o':
121*96c8483aSYuri Pankov offset = atoi(optarg);
122*96c8483aSYuri Pankov break;
123*96c8483aSYuri Pankov
124*96c8483aSYuri Pankov case 'r':
125*96c8483aSYuri Pankov rflag++;
126*96c8483aSYuri Pankov break;
127*96c8483aSYuri Pankov
128*96c8483aSYuri Pankov case 's':
129*96c8483aSYuri Pankov seed = atoi(optarg);
130*96c8483aSYuri Pankov break;
131*96c8483aSYuri Pankov
132*96c8483aSYuri Pankov case 'v':
133*96c8483aSYuri Pankov vflag++;
134*96c8483aSYuri Pankov break;
135*96c8483aSYuri Pankov
136*96c8483aSYuri Pankov case ':':
137*96c8483aSYuri Pankov (void) fprintf(stderr,
138*96c8483aSYuri Pankov "Option -%c requires an operand\n", optopt);
139*96c8483aSYuri Pankov errflag++;
140*96c8483aSYuri Pankov break;
141*96c8483aSYuri Pankov
142*96c8483aSYuri Pankov case '?':
143*96c8483aSYuri Pankov (void) fprintf(stderr,
144*96c8483aSYuri Pankov "Unrecognized option: -%c\n", optopt);
145*96c8483aSYuri Pankov errflag++;
146*96c8483aSYuri Pankov break;
147*96c8483aSYuri Pankov }
148*96c8483aSYuri Pankov
149*96c8483aSYuri Pankov if (errflag) {
150*96c8483aSYuri Pankov (void) usage(argv[0]);
151*96c8483aSYuri Pankov }
152*96c8483aSYuri Pankov }
153*96c8483aSYuri Pankov if (argc <= optind) {
154*96c8483aSYuri Pankov (void) fprintf(stderr,
155*96c8483aSYuri Pankov "No filename specified\n");
156*96c8483aSYuri Pankov usage(argv[0]);
157*96c8483aSYuri Pankov }
158*96c8483aSYuri Pankov filename = argv[optind];
159*96c8483aSYuri Pankov
160*96c8483aSYuri Pankov if (vflag) {
161*96c8483aSYuri Pankov (void) fprintf(stderr, "Seed = %d\n", seed);
162*96c8483aSYuri Pankov }
163*96c8483aSYuri Pankov srandom(seed);
164*96c8483aSYuri Pankov }
165*96c8483aSYuri Pankov
166*96c8483aSYuri Pankov static void
do_write(int fd)167*96c8483aSYuri Pankov do_write(int fd)
168*96c8483aSYuri Pankov {
169*96c8483aSYuri Pankov off_t roffset = 0;
170*96c8483aSYuri Pankov char *buf = NULL;
171*96c8483aSYuri Pankov char *rbuf = NULL;
172*96c8483aSYuri Pankov
173*96c8483aSYuri Pankov buf = (char *)calloc(1, bsize);
174*96c8483aSYuri Pankov rbuf = (char *)calloc(1, bsize);
175*96c8483aSYuri Pankov if (buf == NULL || rbuf == NULL) {
176*96c8483aSYuri Pankov perror("malloc");
177*96c8483aSYuri Pankov exit(4);
178*96c8483aSYuri Pankov }
179*96c8483aSYuri Pankov
180*96c8483aSYuri Pankov roffset = random() % fsize;
181*96c8483aSYuri Pankov if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
182*96c8483aSYuri Pankov perror("lseek");
183*96c8483aSYuri Pankov exit(5);
184*96c8483aSYuri Pankov }
185*96c8483aSYuri Pankov
186*96c8483aSYuri Pankov buf = "SMBFS Test Suite Truncation Test";
187*96c8483aSYuri Pankov if (write(fd, buf, bsize) < bsize) {
188*96c8483aSYuri Pankov perror("write");
189*96c8483aSYuri Pankov exit(6);
190*96c8483aSYuri Pankov }
191*96c8483aSYuri Pankov
192*96c8483aSYuri Pankov if (rflag) {
193*96c8483aSYuri Pankov if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
194*96c8483aSYuri Pankov perror("lseek");
195*96c8483aSYuri Pankov exit(7);
196*96c8483aSYuri Pankov }
197*96c8483aSYuri Pankov
198*96c8483aSYuri Pankov if (read(fd, rbuf, bsize) < bsize) {
199*96c8483aSYuri Pankov perror("read");
200*96c8483aSYuri Pankov exit(8);
201*96c8483aSYuri Pankov }
202*96c8483aSYuri Pankov
203*96c8483aSYuri Pankov if (memcmp(buf, rbuf, bsize) != 0) {
204*96c8483aSYuri Pankov perror("memcmp");
205*96c8483aSYuri Pankov exit(9);
206*96c8483aSYuri Pankov }
207*96c8483aSYuri Pankov }
208*96c8483aSYuri Pankov if (vflag) {
209*96c8483aSYuri Pankov (void) fprintf(stderr,
210*96c8483aSYuri Pankov "Wrote to offset %jd\n", (intmax_t)(offset + roffset));
211*96c8483aSYuri Pankov if (rflag) {
212*96c8483aSYuri Pankov (void) fprintf(stderr,
213*96c8483aSYuri Pankov "Read back from offset %jd\n",
214*96c8483aSYuri Pankov (intmax_t)(offset + roffset));
215*96c8483aSYuri Pankov }
216*96c8483aSYuri Pankov }
217*96c8483aSYuri Pankov
218*96c8483aSYuri Pankov (void) free(buf);
219*96c8483aSYuri Pankov (void) free(rbuf);
220*96c8483aSYuri Pankov }
221*96c8483aSYuri Pankov
222*96c8483aSYuri Pankov static void
do_trunc(int fd)223*96c8483aSYuri Pankov do_trunc(int fd)
224*96c8483aSYuri Pankov {
225*96c8483aSYuri Pankov off_t roffset = 0;
226*96c8483aSYuri Pankov
227*96c8483aSYuri Pankov roffset = random() % fsize;
228*96c8483aSYuri Pankov if (ftruncate64(fd, (offset + roffset)) < 0) {
229*96c8483aSYuri Pankov perror("truncate");
230*96c8483aSYuri Pankov exit(7);
231*96c8483aSYuri Pankov }
232*96c8483aSYuri Pankov
233*96c8483aSYuri Pankov if (vflag) {
234*96c8483aSYuri Pankov (void) fprintf(stderr,
235*96c8483aSYuri Pankov "Truncated at offset %jd\n",
236*96c8483aSYuri Pankov (intmax_t)(offset + roffset));
237*96c8483aSYuri Pankov }
238*96c8483aSYuri Pankov }
239