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 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 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 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 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 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