1*86714001SSerapheim Dimitropoulos /*
2*86714001SSerapheim Dimitropoulos * This file and its contents are supplied under the terms of the
3*86714001SSerapheim Dimitropoulos * Common Development and Distribution License ("CDDL"), version 1.0.
4*86714001SSerapheim Dimitropoulos * You may only use this file in accordance with the terms of version
5*86714001SSerapheim Dimitropoulos * 1.0 of the CDDL.
6*86714001SSerapheim Dimitropoulos *
7*86714001SSerapheim Dimitropoulos * A full copy of the text of the CDDL should have accompanied this
8*86714001SSerapheim Dimitropoulos * source. A copy of the CDDL is also available via the Internet at
9*86714001SSerapheim Dimitropoulos * http://www.illumos.org/license/CDDL.
10*86714001SSerapheim Dimitropoulos */
11*86714001SSerapheim Dimitropoulos
12*86714001SSerapheim Dimitropoulos /*
13*86714001SSerapheim Dimitropoulos * Copyright (c) 2017 by Delphix. All rights reserved.
14*86714001SSerapheim Dimitropoulos */
15*86714001SSerapheim Dimitropoulos
16*86714001SSerapheim Dimitropoulos /*
17*86714001SSerapheim Dimitropoulos * The following is defined so the source can use
18*86714001SSerapheim Dimitropoulos * lrand48() and srand48().
19*86714001SSerapheim Dimitropoulos */
20*86714001SSerapheim Dimitropoulos #define __EXTENSIONS__
21*86714001SSerapheim Dimitropoulos
22*86714001SSerapheim Dimitropoulos #include "../file_common.h"
23*86714001SSerapheim Dimitropoulos
24*86714001SSerapheim Dimitropoulos /*
25*86714001SSerapheim Dimitropoulos * The following sample was derived from real-world data
26*86714001SSerapheim Dimitropoulos * of a production Oracle database.
27*86714001SSerapheim Dimitropoulos */
28*86714001SSerapheim Dimitropoulos static uint64_t size_distribution[] = {
29*86714001SSerapheim Dimitropoulos 0,
30*86714001SSerapheim Dimitropoulos 1499018,
31*86714001SSerapheim Dimitropoulos 352084,
32*86714001SSerapheim Dimitropoulos 1503485,
33*86714001SSerapheim Dimitropoulos 4206227,
34*86714001SSerapheim Dimitropoulos 5626657,
35*86714001SSerapheim Dimitropoulos 5387001,
36*86714001SSerapheim Dimitropoulos 3733756,
37*86714001SSerapheim Dimitropoulos 2233094,
38*86714001SSerapheim Dimitropoulos 874652,
39*86714001SSerapheim Dimitropoulos 238635,
40*86714001SSerapheim Dimitropoulos 81434,
41*86714001SSerapheim Dimitropoulos 33357,
42*86714001SSerapheim Dimitropoulos 13106,
43*86714001SSerapheim Dimitropoulos 2009,
44*86714001SSerapheim Dimitropoulos 1,
45*86714001SSerapheim Dimitropoulos 23660,
46*86714001SSerapheim Dimitropoulos };
47*86714001SSerapheim Dimitropoulos
48*86714001SSerapheim Dimitropoulos
49*86714001SSerapheim Dimitropoulos static uint64_t distribution_n;
50*86714001SSerapheim Dimitropoulos
51*86714001SSerapheim Dimitropoulos static uint8_t randbuf[BLOCKSZ];
52*86714001SSerapheim Dimitropoulos
53*86714001SSerapheim Dimitropoulos static void
rwc_pwrite(int fd,const void * buf,size_t nbytes,off_t offset)54*86714001SSerapheim Dimitropoulos rwc_pwrite(int fd, const void *buf, size_t nbytes, off_t offset)
55*86714001SSerapheim Dimitropoulos {
56*86714001SSerapheim Dimitropoulos size_t nleft = nbytes;
57*86714001SSerapheim Dimitropoulos ssize_t nwrite = 0;
58*86714001SSerapheim Dimitropoulos
59*86714001SSerapheim Dimitropoulos nwrite = pwrite(fd, buf, nbytes, offset);
60*86714001SSerapheim Dimitropoulos if (nwrite < 0) {
61*86714001SSerapheim Dimitropoulos perror("pwrite");
62*86714001SSerapheim Dimitropoulos exit(EXIT_FAILURE);
63*86714001SSerapheim Dimitropoulos }
64*86714001SSerapheim Dimitropoulos
65*86714001SSerapheim Dimitropoulos nleft -= nwrite;
66*86714001SSerapheim Dimitropoulos if (nleft != 0) {
67*86714001SSerapheim Dimitropoulos (void) fprintf(stderr, "warning: pwrite: "
68*86714001SSerapheim Dimitropoulos "wrote %zu out of %zu bytes\n",
69*86714001SSerapheim Dimitropoulos (nbytes - nleft), nbytes);
70*86714001SSerapheim Dimitropoulos }
71*86714001SSerapheim Dimitropoulos }
72*86714001SSerapheim Dimitropoulos
73*86714001SSerapheim Dimitropoulos static void
fillbuf(char * buf)74*86714001SSerapheim Dimitropoulos fillbuf(char *buf)
75*86714001SSerapheim Dimitropoulos {
76*86714001SSerapheim Dimitropoulos uint64_t rv = lrand48() % distribution_n;
77*86714001SSerapheim Dimitropoulos uint64_t sum = 0;
78*86714001SSerapheim Dimitropoulos
79*86714001SSerapheim Dimitropoulos uint64_t i;
80*86714001SSerapheim Dimitropoulos for (i = 0;
81*86714001SSerapheim Dimitropoulos i < sizeof (size_distribution) / sizeof (size_distribution[0]);
82*86714001SSerapheim Dimitropoulos i++) {
83*86714001SSerapheim Dimitropoulos sum += size_distribution[i];
84*86714001SSerapheim Dimitropoulos if (rv < sum)
85*86714001SSerapheim Dimitropoulos break;
86*86714001SSerapheim Dimitropoulos }
87*86714001SSerapheim Dimitropoulos
88*86714001SSerapheim Dimitropoulos bcopy(randbuf, buf, BLOCKSZ);
89*86714001SSerapheim Dimitropoulos if (i == 0)
90*86714001SSerapheim Dimitropoulos bzero(buf, BLOCKSZ - 10);
91*86714001SSerapheim Dimitropoulos else if (i < 16)
92*86714001SSerapheim Dimitropoulos bzero(buf, BLOCKSZ - i * 512 + 256);
93*86714001SSerapheim Dimitropoulos /*LINTED: E_BAD_PTR_CAST_ALIGN*/
94*86714001SSerapheim Dimitropoulos ((uint32_t *)buf)[0] = lrand48();
95*86714001SSerapheim Dimitropoulos }
96*86714001SSerapheim Dimitropoulos
97*86714001SSerapheim Dimitropoulos static void
exit_usage(void)98*86714001SSerapheim Dimitropoulos exit_usage(void)
99*86714001SSerapheim Dimitropoulos {
100*86714001SSerapheim Dimitropoulos (void) printf("usage: ");
101*86714001SSerapheim Dimitropoulos (void) printf("randwritecomp <file> [-s] [nwrites]\n");
102*86714001SSerapheim Dimitropoulos exit(EXIT_FAILURE);
103*86714001SSerapheim Dimitropoulos }
104*86714001SSerapheim Dimitropoulos
105*86714001SSerapheim Dimitropoulos static void
sequential_writes(int fd,char * buf,uint64_t nblocks,int64_t n)106*86714001SSerapheim Dimitropoulos sequential_writes(int fd, char *buf, uint64_t nblocks, int64_t n)
107*86714001SSerapheim Dimitropoulos {
108*86714001SSerapheim Dimitropoulos for (int64_t i = 0; n == -1 || i < n; i++) {
109*86714001SSerapheim Dimitropoulos fillbuf(buf);
110*86714001SSerapheim Dimitropoulos
111*86714001SSerapheim Dimitropoulos static uint64_t j = 0;
112*86714001SSerapheim Dimitropoulos if (j == 0)
113*86714001SSerapheim Dimitropoulos j = lrand48() % nblocks;
114*86714001SSerapheim Dimitropoulos rwc_pwrite(fd, buf, BLOCKSZ, j * BLOCKSZ);
115*86714001SSerapheim Dimitropoulos j++;
116*86714001SSerapheim Dimitropoulos if (j >= nblocks)
117*86714001SSerapheim Dimitropoulos j = 0;
118*86714001SSerapheim Dimitropoulos }
119*86714001SSerapheim Dimitropoulos }
120*86714001SSerapheim Dimitropoulos
121*86714001SSerapheim Dimitropoulos static void
random_writes(int fd,char * buf,uint64_t nblocks,int64_t n)122*86714001SSerapheim Dimitropoulos random_writes(int fd, char *buf, uint64_t nblocks, int64_t n)
123*86714001SSerapheim Dimitropoulos {
124*86714001SSerapheim Dimitropoulos for (int64_t i = 0; n == -1 || i < n; i++) {
125*86714001SSerapheim Dimitropoulos fillbuf(buf);
126*86714001SSerapheim Dimitropoulos rwc_pwrite(fd, buf, BLOCKSZ, (lrand48() % nblocks) * BLOCKSZ);
127*86714001SSerapheim Dimitropoulos }
128*86714001SSerapheim Dimitropoulos }
129*86714001SSerapheim Dimitropoulos
130*86714001SSerapheim Dimitropoulos int
main(int argc,char * argv[])131*86714001SSerapheim Dimitropoulos main(int argc, char *argv[])
132*86714001SSerapheim Dimitropoulos {
133*86714001SSerapheim Dimitropoulos int fd, err;
134*86714001SSerapheim Dimitropoulos char *filename = NULL;
135*86714001SSerapheim Dimitropoulos char buf[BLOCKSZ];
136*86714001SSerapheim Dimitropoulos struct stat ss;
137*86714001SSerapheim Dimitropoulos uint64_t nblocks;
138*86714001SSerapheim Dimitropoulos int64_t n = -1;
139*86714001SSerapheim Dimitropoulos int sequential = 0;
140*86714001SSerapheim Dimitropoulos
141*86714001SSerapheim Dimitropoulos if (argc < 2)
142*86714001SSerapheim Dimitropoulos exit_usage();
143*86714001SSerapheim Dimitropoulos
144*86714001SSerapheim Dimitropoulos argv++;
145*86714001SSerapheim Dimitropoulos if (strcmp("-s", argv[0]) == 0) {
146*86714001SSerapheim Dimitropoulos sequential = 1;
147*86714001SSerapheim Dimitropoulos argv++;
148*86714001SSerapheim Dimitropoulos }
149*86714001SSerapheim Dimitropoulos
150*86714001SSerapheim Dimitropoulos if (argv[0] == NULL)
151*86714001SSerapheim Dimitropoulos exit_usage();
152*86714001SSerapheim Dimitropoulos else
153*86714001SSerapheim Dimitropoulos filename = argv[0];
154*86714001SSerapheim Dimitropoulos
155*86714001SSerapheim Dimitropoulos argv++;
156*86714001SSerapheim Dimitropoulos if (argv[0] != NULL)
157*86714001SSerapheim Dimitropoulos n = strtoull(argv[0], NULL, 0);
158*86714001SSerapheim Dimitropoulos
159*86714001SSerapheim Dimitropoulos fd = open(filename, O_RDWR|O_CREAT, 0666);
160*86714001SSerapheim Dimitropoulos err = fstat(fd, &ss);
161*86714001SSerapheim Dimitropoulos if (err != 0) {
162*86714001SSerapheim Dimitropoulos (void) fprintf(stderr,
163*86714001SSerapheim Dimitropoulos "error: fstat returned error code %d\n", err);
164*86714001SSerapheim Dimitropoulos exit(EXIT_FAILURE);
165*86714001SSerapheim Dimitropoulos }
166*86714001SSerapheim Dimitropoulos
167*86714001SSerapheim Dimitropoulos nblocks = ss.st_size / BLOCKSZ;
168*86714001SSerapheim Dimitropoulos if (nblocks == 0) {
169*86714001SSerapheim Dimitropoulos (void) fprintf(stderr, "error: "
170*86714001SSerapheim Dimitropoulos "file is too small (min allowed size is %d bytes)\n",
171*86714001SSerapheim Dimitropoulos BLOCKSZ);
172*86714001SSerapheim Dimitropoulos exit(EXIT_FAILURE);
173*86714001SSerapheim Dimitropoulos }
174*86714001SSerapheim Dimitropoulos
175*86714001SSerapheim Dimitropoulos srand48(getpid());
176*86714001SSerapheim Dimitropoulos for (int i = 0; i < BLOCKSZ; i++)
177*86714001SSerapheim Dimitropoulos randbuf[i] = lrand48();
178*86714001SSerapheim Dimitropoulos
179*86714001SSerapheim Dimitropoulos distribution_n = 0;
180*86714001SSerapheim Dimitropoulos for (uint64_t i = 0;
181*86714001SSerapheim Dimitropoulos i < sizeof (size_distribution) / sizeof (size_distribution[0]);
182*86714001SSerapheim Dimitropoulos i++) {
183*86714001SSerapheim Dimitropoulos distribution_n += size_distribution[i];
184*86714001SSerapheim Dimitropoulos }
185*86714001SSerapheim Dimitropoulos
186*86714001SSerapheim Dimitropoulos if (sequential)
187*86714001SSerapheim Dimitropoulos sequential_writes(fd, buf, nblocks, n);
188*86714001SSerapheim Dimitropoulos else
189*86714001SSerapheim Dimitropoulos random_writes(fd, buf, nblocks, n);
190*86714001SSerapheim Dimitropoulos
191*86714001SSerapheim Dimitropoulos return (0);
192*86714001SSerapheim Dimitropoulos }
193