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