9166 zfs storage pool checkpoint
[unleashed.git] / usr / src / test / zfs-tests / cmd / randwritecomp / randwritecomp.c
blob9f9b9833feb00e7c45c11ec9da67131d6248a373
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.
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.
13 * Copyright (c) 2017 by Delphix. All rights reserved.
17 * The following is defined so the source can use
18 * lrand48() and srand48().
20 #define __EXTENSIONS__
22 #include "../file_common.h"
25 * The following sample was derived from real-world data
26 * of a production Oracle database.
28 static uint64_t size_distribution[] = {
30 1499018,
31 352084,
32 1503485,
33 4206227,
34 5626657,
35 5387001,
36 3733756,
37 2233094,
38 874652,
39 238635,
40 81434,
41 33357,
42 13106,
43 2009,
45 23660,
49 static uint64_t distribution_n;
51 static uint8_t randbuf[BLOCKSZ];
53 static void
54 rwc_pwrite(int fd, const void *buf, size_t nbytes, off_t offset)
56 size_t nleft = nbytes;
57 ssize_t nwrite = 0;
59 nwrite = pwrite(fd, buf, nbytes, offset);
60 if (nwrite < 0) {
61 perror("pwrite");
62 exit(EXIT_FAILURE);
65 nleft -= nwrite;
66 if (nleft != 0) {
67 (void) fprintf(stderr, "warning: pwrite: "
68 "wrote %zu out of %zu bytes\n",
69 (nbytes - nleft), nbytes);
73 static void
74 fillbuf(char *buf)
76 uint64_t rv = lrand48() % distribution_n;
77 uint64_t sum = 0;
79 uint64_t i;
80 for (i = 0;
81 i < sizeof (size_distribution) / sizeof (size_distribution[0]);
82 i++) {
83 sum += size_distribution[i];
84 if (rv < sum)
85 break;
88 bcopy(randbuf, buf, BLOCKSZ);
89 if (i == 0)
90 bzero(buf, BLOCKSZ - 10);
91 else if (i < 16)
92 bzero(buf, BLOCKSZ - i * 512 + 256);
93 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
94 ((uint32_t *)buf)[0] = lrand48();
97 static void
98 exit_usage(void)
100 (void) printf("usage: ");
101 (void) printf("randwritecomp <file> [-s] [nwrites]\n");
102 exit(EXIT_FAILURE);
105 static void
106 sequential_writes(int fd, char *buf, uint64_t nblocks, int64_t n)
108 for (int64_t i = 0; n == -1 || i < n; i++) {
109 fillbuf(buf);
111 static uint64_t j = 0;
112 if (j == 0)
113 j = lrand48() % nblocks;
114 rwc_pwrite(fd, buf, BLOCKSZ, j * BLOCKSZ);
115 j++;
116 if (j >= nblocks)
117 j = 0;
121 static void
122 random_writes(int fd, char *buf, uint64_t nblocks, int64_t n)
124 for (int64_t i = 0; n == -1 || i < n; i++) {
125 fillbuf(buf);
126 rwc_pwrite(fd, buf, BLOCKSZ, (lrand48() % nblocks) * BLOCKSZ);
131 main(int argc, char *argv[])
133 int fd, err;
134 char *filename = NULL;
135 char buf[BLOCKSZ];
136 struct stat ss;
137 uint64_t nblocks;
138 int64_t n = -1;
139 int sequential = 0;
141 if (argc < 2)
142 exit_usage();
144 argv++;
145 if (strcmp("-s", argv[0]) == 0) {
146 sequential = 1;
147 argv++;
150 if (argv[0] == NULL)
151 exit_usage();
152 else
153 filename = argv[0];
155 argv++;
156 if (argv[0] != NULL)
157 n = strtoull(argv[0], NULL, 0);
159 fd = open(filename, O_RDWR|O_CREAT, 0666);
160 err = fstat(fd, &ss);
161 if (err != 0) {
162 (void) fprintf(stderr,
163 "error: fstat returned error code %d\n", err);
164 exit(EXIT_FAILURE);
167 nblocks = ss.st_size / BLOCKSZ;
168 if (nblocks == 0) {
169 (void) fprintf(stderr, "error: "
170 "file is too small (min allowed size is %d bytes)\n",
171 BLOCKSZ);
172 exit(EXIT_FAILURE);
175 srand48(getpid());
176 for (int i = 0; i < BLOCKSZ; i++)
177 randbuf[i] = lrand48();
179 distribution_n = 0;
180 for (uint64_t i = 0;
181 i < sizeof (size_distribution) / sizeof (size_distribution[0]);
182 i++) {
183 distribution_n += size_distribution[i];
186 if (sequential)
187 sequential_writes(fd, buf, nblocks, n);
188 else
189 random_writes(fd, buf, nblocks, n);
191 return (0);