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