blktrace: kill zero sized write test
[fio.git] / options.c
CommitLineData
214e1eca
JA
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <ctype.h>
5#include <string.h>
214e1eca 6#include <assert.h>
5921e80c 7#include <sys/stat.h>
e13c3b50 8#include <netinet/in.h>
214e1eca
JA
9
10#include "fio.h"
4f5af7b2 11#include "verify.h"
214e1eca 12#include "parse.h"
61b9861d 13#include "lib/pattern.h"
9f988e2e 14#include "options.h"
d220c761 15#include "optgroup.h"
214e1eca 16
e13c3b50 17char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
72a703da 18
a609f12a
JA
19#define cb_data_to_td(data) container_of(data, struct thread_data, o)
20
fc8d6d05 21static struct pattern_fmt_desc fmt_desc[] = {
4205998f
JA
22 {
23 .fmt = "%o",
24 .len = FIELD_SIZE(struct io_u *, offset),
25 .paste = paste_blockoff
26 }
27};
28
214e1eca
JA
29/*
30 * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
31 */
32static char *get_opt_postfix(const char *str)
33{
34 char *p = strstr(str, ":");
35
36 if (!p)
37 return NULL;
38
39 p++;
40 strip_blank_front(&p);
41 strip_blank_end(p);
42 return strdup(p);
43}
44
564ca972
JA
45static int bs_cmp(const void *p1, const void *p2)
46{
47 const struct bssplit *bsp1 = p1;
48 const struct bssplit *bsp2 = p2;
49
a7cd478d 50 return (int) bsp1->perc - (int) bsp2->perc;
564ca972
JA
51}
52
d2835319
JA
53struct split {
54 unsigned int nr;
9d8fc5e4
JA
55 unsigned int val1[ZONESPLIT_MAX];
56 unsigned long long val2[ZONESPLIT_MAX];
d2835319
JA
57};
58
59static int split_parse_ddir(struct thread_options *o, struct split *split,
b53a2155
JA
60 enum fio_ddir ddir, char *str, bool absolute,
61 unsigned int max_splits)
564ca972 62{
59466396
JA
63 unsigned long long perc;
64 unsigned int i;
564ca972 65 long long val;
720e84ad 66 char *fname;
564ca972 67
d2835319 68 split->nr = 0;
564ca972
JA
69
70 i = 0;
564ca972
JA
71 while ((fname = strsep(&str, ":")) != NULL) {
72 char *perc_str;
73
74 if (!strlen(fname))
75 break;
76
564ca972
JA
77 perc_str = strstr(fname, "/");
78 if (perc_str) {
79 *perc_str = '\0';
80 perc_str++;
59466396
JA
81 if (absolute) {
82 if (str_to_decimal(perc_str, &val, 1, o, 0, 0)) {
83 log_err("fio: split conversion failed\n");
84 return 1;
85 }
86 perc = val;
87 } else {
88 perc = atoi(perc_str);
89 if (perc > 100)
90 perc = 100;
91 else if (!perc)
92 perc = -1U;
93 }
94 } else {
95 if (absolute)
96 perc = 0;
97 else
d711cce5 98 perc = -1U;
59466396 99 }
564ca972 100
88038bc7 101 if (str_to_decimal(fname, &val, 1, o, 0, 0)) {
59466396 102 log_err("fio: split conversion failed\n");
564ca972
JA
103 return 1;
104 }
105
d2835319
JA
106 split->val1[i] = val;
107 split->val2[i] = perc;
564ca972 108 i++;
c32e1a09
JA
109 if (i == max_splits) {
110 log_err("fio: hit max of %d split entries\n", i);
d2835319 111 break;
c32e1a09 112 }
564ca972
JA
113 }
114
d2835319
JA
115 split->nr = i;
116 return 0;
117}
118
59466396
JA
119static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str,
120 bool data)
d2835319
JA
121{
122 unsigned int i, perc, perc_missing;
123 unsigned int max_bs, min_bs;
124 struct split split;
125
126 memset(&split, 0, sizeof(split));
127
b53a2155 128 if (split_parse_ddir(o, &split, ddir, str, data, BSSPLIT_MAX))
d2835319
JA
129 return 1;
130 if (!split.nr)
131 return 0;
132
133 max_bs = 0;
134 min_bs = -1;
135 o->bssplit[ddir] = malloc(split.nr * sizeof(struct bssplit));
136 o->bssplit_nr[ddir] = split.nr;
137 for (i = 0; i < split.nr; i++) {
138 if (split.val1[i] > max_bs)
139 max_bs = split.val1[i];
140 if (split.val1[i] < min_bs)
141 min_bs = split.val1[i];
142
143 o->bssplit[ddir][i].bs = split.val1[i];
144 o->bssplit[ddir][i].perc =split.val2[i];
145 }
564ca972
JA
146
147 /*
148 * Now check if the percentages add up, and how much is missing
149 */
150 perc = perc_missing = 0;
83ea422a 151 for (i = 0; i < o->bssplit_nr[ddir]; i++) {
d2835319 152 struct bssplit *bsp = &o->bssplit[ddir][i];
564ca972 153
d711cce5 154 if (bsp->perc == -1U)
564ca972
JA
155 perc_missing++;
156 else
157 perc += bsp->perc;
158 }
159
40bafa33 160 if (perc > 100 && perc_missing > 1) {
564ca972 161 log_err("fio: bssplit percentages add to more than 100%%\n");
d2835319
JA
162 free(o->bssplit[ddir]);
163 o->bssplit[ddir] = NULL;
564ca972
JA
164 return 1;
165 }
d711cce5 166
564ca972
JA
167 /*
168 * If values didn't have a percentage set, divide the remains between
169 * them.
170 */
171 if (perc_missing) {
d711cce5 172 if (perc_missing == 1 && o->bssplit_nr[ddir] == 1)
40bafa33 173 perc = 100;
83ea422a 174 for (i = 0; i < o->bssplit_nr[ddir]; i++) {
d2835319 175 struct bssplit *bsp = &o->bssplit[ddir][i];
564ca972 176
d711cce5 177 if (bsp->perc == -1U)
564ca972
JA
178 bsp->perc = (100 - perc) / perc_missing;
179 }
180 }
181
83ea422a
JA
182 o->min_bs[ddir] = min_bs;
183 o->max_bs[ddir] = max_bs;
564ca972
JA
184
185 /*
186 * now sort based on percentages, for ease of lookup
187 */
d2835319 188 qsort(o->bssplit[ddir], o->bssplit_nr[ddir], sizeof(struct bssplit), bs_cmp);
720e84ad 189 return 0;
720e84ad
JA
190}
191
59466396 192typedef int (split_parse_fn)(struct thread_options *, enum fio_ddir, char *, bool);
764593c0 193
59466396
JA
194static int str_split_parse(struct thread_data *td, char *str,
195 split_parse_fn *fn, bool data)
720e84ad 196{
764593c0 197 char *odir, *ddir;
720e84ad
JA
198 int ret = 0;
199
720e84ad
JA
200 odir = strchr(str, ',');
201 if (odir) {
6eaf09d6
SL
202 ddir = strchr(odir + 1, ',');
203 if (ddir) {
59466396 204 ret = fn(&td->o, DDIR_TRIM, ddir + 1, data);
6eaf09d6
SL
205 if (!ret)
206 *ddir = '\0';
207 } else {
208 char *op;
209
210 op = strdup(odir + 1);
59466396 211 ret = fn(&td->o, DDIR_TRIM, op, data);
6eaf09d6
SL
212
213 free(op);
214 }
d79db122 215 if (!ret)
59466396 216 ret = fn(&td->o, DDIR_WRITE, odir + 1, data);
720e84ad
JA
217 if (!ret) {
218 *odir = '\0';
59466396 219 ret = fn(&td->o, DDIR_READ, str, data);
720e84ad
JA
220 }
221 } else {
222 char *op;
223
224 op = strdup(str);
59466396 225 ret = fn(&td->o, DDIR_WRITE, op, data);
6eaf09d6 226 free(op);
720e84ad 227
6eaf09d6
SL
228 if (!ret) {
229 op = strdup(str);
59466396 230 ret = fn(&td->o, DDIR_TRIM, op, data);
6eaf09d6
SL
231 free(op);
232 }
f0c9c217 233 if (!ret)
59466396 234 ret = fn(&td->o, DDIR_READ, str, data);
720e84ad 235 }
564ca972 236
764593c0
JA
237 return ret;
238}
239
240static int str_bssplit_cb(void *data, const char *input)
241{
a609f12a 242 struct thread_data *td = cb_data_to_td(data);
764593c0
JA
243 char *str, *p;
244 int ret = 0;
245
764593c0
JA
246 p = str = strdup(input);
247
248 strip_blank_front(&str);
249 strip_blank_end(str);
250
59466396 251 ret = str_split_parse(td, str, bssplit_ddir, false);
764593c0 252
55baca06
JA
253 if (parse_dryrun()) {
254 int i;
255
256 for (i = 0; i < DDIR_RWDIR_CNT; i++) {
257 free(td->o.bssplit[i]);
258 td->o.bssplit[i] = NULL;
259 td->o.bssplit_nr[i] = 0;
260 }
261 }
262
564ca972 263 free(p);
720e84ad 264 return ret;
564ca972
JA
265}
266
8b28bd41
DM
267static int str2error(char *str)
268{
a94eb99a 269 const char *err[] = { "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO",
8b28bd41
DM
270 "ENXIO", "E2BIG", "ENOEXEC", "EBADF",
271 "ECHILD", "EAGAIN", "ENOMEM", "EACCES",
272 "EFAULT", "ENOTBLK", "EBUSY", "EEXIST",
273 "EXDEV", "ENODEV", "ENOTDIR", "EISDIR",
274 "EINVAL", "ENFILE", "EMFILE", "ENOTTY",
275 "ETXTBSY","EFBIG", "ENOSPC", "ESPIPE",
a94eb99a 276 "EROFS","EMLINK", "EPIPE", "EDOM", "ERANGE" };
7fe481b4 277 int i = 0, num = sizeof(err) / sizeof(char *);
8b28bd41 278
a94eb99a 279 while (i < num) {
8b28bd41
DM
280 if (!strcmp(err[i], str))
281 return i + 1;
282 i++;
283 }
284 return 0;
285}
286
3ed673c6
TK
287static int ignore_error_type(struct thread_data *td, enum error_type_bit etype,
288 char *str)
8b28bd41
DM
289{
290 unsigned int i;
291 int *error;
292 char *fname;
293
294 if (etype >= ERROR_TYPE_CNT) {
295 log_err("Illegal error type\n");
296 return 1;
297 }
298
299 td->o.ignore_error_nr[etype] = 4;
685ffd57 300 error = calloc(4, sizeof(int));
8b28bd41
DM
301
302 i = 0;
303 while ((fname = strsep(&str, ":")) != NULL) {
304
305 if (!strlen(fname))
306 break;
307
308 /*
309 * grow struct buffer, if needed
310 */
311 if (i == td->o.ignore_error_nr[etype]) {
312 td->o.ignore_error_nr[etype] <<= 1;
313 error = realloc(error, td->o.ignore_error_nr[etype]
314 * sizeof(int));
315 }
316 if (fname[0] == 'E') {
317 error[i] = str2error(fname);
318 } else {
319 error[i] = atoi(fname);
320 if (error[i] < 0)
1616e025 321 error[i] = -error[i];
8b28bd41
DM
322 }
323 if (!error[i]) {
d503e281 324 log_err("Unknown error %s, please use number value\n",
8b28bd41 325 fname);
d503e281 326 td->o.ignore_error_nr[etype] = 0;
0fddbf7a 327 free(error);
8b28bd41
DM
328 return 1;
329 }
330 i++;
331 }
332 if (i) {
333 td->o.continue_on_error |= 1 << etype;
334 td->o.ignore_error_nr[etype] = i;
335 td->o.ignore_error[etype] = error;
d503e281
TK
336 } else {
337 td->o.ignore_error_nr[etype] = 0;
c7b086be 338 free(error);
d503e281 339 }
c7b086be 340
8b28bd41
DM
341 return 0;
342
343}
344
345static int str_ignore_error_cb(void *data, const char *input)
346{
a609f12a 347 struct thread_data *td = cb_data_to_td(data);
8b28bd41 348 char *str, *p, *n;
3ed673c6
TK
349 int ret = 1;
350 enum error_type_bit type = 0;
52c0cea3
JA
351
352 if (parse_dryrun())
353 return 0;
354
8b28bd41
DM
355 p = str = strdup(input);
356
357 strip_blank_front(&str);
358 strip_blank_end(str);
359
360 while (p) {
361 n = strchr(p, ',');
362 if (n)
363 *n++ = '\0';
364 ret = ignore_error_type(td, type, p);
365 if (ret)
366 break;
367 p = n;
368 type++;
369 }
370 free(str);
371 return ret;
372}
373
211097b2
JA
374static int str_rw_cb(void *data, const char *str)
375{
a609f12a 376 struct thread_data *td = cb_data_to_td(data);
83ea422a 377 struct thread_options *o = &td->o;
27ca949f 378 char *nr;
211097b2 379
52c0cea3
JA
380 if (parse_dryrun())
381 return 0;
382
83ea422a
JA
383 o->ddir_seq_nr = 1;
384 o->ddir_seq_add = 0;
059b0802 385
27ca949f 386 nr = get_opt_postfix(str);
059b0802
JA
387 if (!nr)
388 return 0;
389
390 if (td_random(td))
83ea422a 391 o->ddir_seq_nr = atoi(nr);
059b0802
JA
392 else {
393 long long val;
394
88038bc7 395 if (str_to_decimal(nr, &val, 1, o, 0, 0)) {
059b0802
JA
396 log_err("fio: rw postfix parsing failed\n");
397 free(nr);
398 return 1;
399 }
400
83ea422a 401 o->ddir_seq_add = val;
182ec6ee 402 }
211097b2 403
059b0802 404 free(nr);
211097b2
JA
405 return 0;
406}
407
214e1eca
JA
408static int str_mem_cb(void *data, const char *mem)
409{
a609f12a 410 struct thread_data *td = cb_data_to_td(data);
214e1eca 411
217b0f1d
LG
412 if (td->o.mem_type == MEM_MMAPHUGE || td->o.mem_type == MEM_MMAP ||
413 td->o.mem_type == MEM_MMAPSHARED)
836fcc0f 414 td->o.mmapfile = get_opt_postfix(mem);
214e1eca
JA
415
416 return 0;
417}
418
c223da83
JA
419static int fio_clock_source_cb(void *data, const char *str)
420{
a609f12a 421 struct thread_data *td = cb_data_to_td(data);
c223da83
JA
422
423 fio_clock_source = td->o.clocksource;
fa80feae 424 fio_clock_source_set = 1;
01423eae 425 fio_clock_init();
c223da83
JA
426 return 0;
427}
428
85bc833b 429static int str_rwmix_read_cb(void *data, unsigned long long *val)
cb499fc4 430{
a609f12a 431 struct thread_data *td = cb_data_to_td(data);
cb499fc4
JA
432
433 td->o.rwmix[DDIR_READ] = *val;
434 td->o.rwmix[DDIR_WRITE] = 100 - *val;
435 return 0;
436}
437
85bc833b 438static int str_rwmix_write_cb(void *data, unsigned long long *val)
cb499fc4 439{
a609f12a 440 struct thread_data *td = cb_data_to_td(data);
cb499fc4
JA
441
442 td->o.rwmix[DDIR_WRITE] = *val;
443 td->o.rwmix[DDIR_READ] = 100 - *val;
444 return 0;
445}
446
214e1eca
JA
447static int str_exitall_cb(void)
448{
449 exitall_on_terminate = 1;
450 return 0;
451}
452
214e1eca 453#ifdef FIO_HAVE_CPU_AFFINITY
50b5860b 454int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu_index)
c2acfbac 455{
50b5860b 456 unsigned int i, index, cpus_in_mask;
c2acfbac 457 const long max_cpu = cpus_online();
c2acfbac 458
50b5860b
JA
459 cpus_in_mask = fio_cpu_count(mask);
460 cpu_index = cpu_index % cpus_in_mask;
461
462 index = 0;
c2acfbac 463 for (i = 0; i < max_cpu; i++) {
50b5860b 464 if (!fio_cpu_isset(mask, i))
c2acfbac 465 continue;
50b5860b
JA
466
467 if (cpu_index != index)
468 fio_cpu_clear(mask, i);
469
470 index++;
c2acfbac
JA
471 }
472
473 return fio_cpu_count(mask);
474}
475
85bc833b 476static int str_cpumask_cb(void *data, unsigned long long *val)
d2e268b0 477{
a609f12a 478 struct thread_data *td = cb_data_to_td(data);
214e1eca 479 unsigned int i;
b03daafb 480 long max_cpu;
d2ce18b5
JA
481 int ret;
482
52c0cea3
JA
483 if (parse_dryrun())
484 return 0;
485
d2ce18b5
JA
486 ret = fio_cpuset_init(&td->o.cpumask);
487 if (ret < 0) {
488 log_err("fio: cpuset_init failed\n");
489 td_verror(td, ret, "fio_cpuset_init");
490 return 1;
491 }
214e1eca 492
c00a2289 493 max_cpu = cpus_online();
214e1eca 494
62a7273d
JA
495 for (i = 0; i < sizeof(int) * 8; i++) {
496 if ((1 << i) & *val) {
b8411399 497 if (i >= max_cpu) {
b03daafb 498 log_err("fio: CPU %d too large (max=%ld)\n", i,
b8411399 499 max_cpu - 1);
b03daafb
JA
500 return 1;
501 }
62a7273d 502 dprint(FD_PARSE, "set cpu allowed %d\n", i);
6d459ee7 503 fio_cpu_set(&td->o.cpumask, i);
62a7273d
JA
504 }
505 }
d2e268b0 506
d2e268b0 507 return 0;
214e1eca
JA
508}
509
e8462bd8
JA
510static int set_cpus_allowed(struct thread_data *td, os_cpu_mask_t *mask,
511 const char *input)
214e1eca 512{
d2e268b0 513 char *cpu, *str, *p;
b03daafb 514 long max_cpu;
19608d6c 515 int ret = 0;
d2e268b0 516
e8462bd8 517 ret = fio_cpuset_init(mask);
d2ce18b5
JA
518 if (ret < 0) {
519 log_err("fio: cpuset_init failed\n");
520 td_verror(td, ret, "fio_cpuset_init");
521 return 1;
522 }
d2e268b0
JA
523
524 p = str = strdup(input);
214e1eca 525
d2e268b0
JA
526 strip_blank_front(&str);
527 strip_blank_end(str);
528
c00a2289 529 max_cpu = cpus_online();
b03daafb 530
d2e268b0 531 while ((cpu = strsep(&str, ",")) != NULL) {
62a7273d
JA
532 char *str2, *cpu2;
533 int icpu, icpu2;
534
d2e268b0
JA
535 if (!strlen(cpu))
536 break;
62a7273d
JA
537
538 str2 = cpu;
539 icpu2 = -1;
540 while ((cpu2 = strsep(&str2, "-")) != NULL) {
541 if (!strlen(cpu2))
542 break;
543
544 icpu2 = atoi(cpu2);
545 }
546
547 icpu = atoi(cpu);
548 if (icpu2 == -1)
549 icpu2 = icpu;
550 while (icpu <= icpu2) {
6d459ee7 551 if (icpu >= FIO_MAX_CPUS) {
19608d6c 552 log_err("fio: your OS only supports up to"
6d459ee7 553 " %d CPUs\n", (int) FIO_MAX_CPUS);
19608d6c
JA
554 ret = 1;
555 break;
556 }
9e986889 557 if (icpu >= max_cpu) {
b03daafb 558 log_err("fio: CPU %d too large (max=%ld)\n",
9e986889 559 icpu, max_cpu - 1);
b03daafb
JA
560 ret = 1;
561 break;
562 }
0b9d69ec 563
62a7273d 564 dprint(FD_PARSE, "set cpu allowed %d\n", icpu);
e8462bd8 565 fio_cpu_set(mask, icpu);
62a7273d
JA
566 icpu++;
567 }
19608d6c
JA
568 if (ret)
569 break;
d2e268b0
JA
570 }
571
572 free(p);
19608d6c 573 return ret;
214e1eca 574}
e8462bd8
JA
575
576static int str_cpus_allowed_cb(void *data, const char *input)
577{
a609f12a 578 struct thread_data *td = cb_data_to_td(data);
e8462bd8 579
52c0cea3
JA
580 if (parse_dryrun())
581 return 0;
582
b2a9e649 583 return set_cpus_allowed(td, &td->o.cpumask, input);
e8462bd8
JA
584}
585
586static int str_verify_cpus_allowed_cb(void *data, const char *input)
587{
a609f12a 588 struct thread_data *td = cb_data_to_td(data);
e8462bd8 589
466155e2
JA
590 if (parse_dryrun())
591 return 0;
592
b2a9e649 593 return set_cpus_allowed(td, &td->o.verify_cpumask, input);
e8462bd8 594}
c08f9fe2 595
105157ad 596#ifdef CONFIG_ZLIB
c08f9fe2
JA
597static int str_log_cpus_allowed_cb(void *data, const char *input)
598{
a609f12a 599 struct thread_data *td = cb_data_to_td(data);
c08f9fe2
JA
600
601 if (parse_dryrun())
602 return 0;
603
604 return set_cpus_allowed(td, &td->o.log_gz_cpumask, input);
605}
105157ad 606#endif /* CONFIG_ZLIB */
c08f9fe2 607
105157ad 608#endif /* FIO_HAVE_CPU_AFFINITY */
214e1eca 609
67bf9823 610#ifdef CONFIG_LIBNUMA
d0b937ed
YR
611static int str_numa_cpunodes_cb(void *data, char *input)
612{
a609f12a 613 struct thread_data *td = cb_data_to_td(data);
43522848 614 struct bitmask *verify_bitmask;
d0b937ed 615
52c0cea3
JA
616 if (parse_dryrun())
617 return 0;
618
d0b937ed
YR
619 /* numa_parse_nodestring() parses a character string list
620 * of nodes into a bit mask. The bit mask is allocated by
621 * numa_allocate_nodemask(), so it should be freed by
622 * numa_free_nodemask().
623 */
43522848
DG
624 verify_bitmask = numa_parse_nodestring(input);
625 if (verify_bitmask == NULL) {
d0b937ed
YR
626 log_err("fio: numa_parse_nodestring failed\n");
627 td_verror(td, 1, "str_numa_cpunodes_cb");
628 return 1;
629 }
43522848 630 numa_free_nodemask(verify_bitmask);
d0b937ed 631
43522848 632 td->o.numa_cpunodes = strdup(input);
d0b937ed
YR
633 return 0;
634}
635
636static int str_numa_mpol_cb(void *data, char *input)
637{
a609f12a 638 struct thread_data *td = cb_data_to_td(data);
d0b937ed 639 const char * const policy_types[] =
05d6f44b 640 { "default", "prefer", "bind", "interleave", "local", NULL };
d0b937ed 641 int i;
52c0cea3 642 char *nodelist;
43522848 643 struct bitmask *verify_bitmask;
52c0cea3
JA
644
645 if (parse_dryrun())
646 return 0;
d0b937ed 647
52c0cea3 648 nodelist = strchr(input, ':');
d0b937ed
YR
649 if (nodelist) {
650 /* NUL-terminate mode */
651 *nodelist++ = '\0';
652 }
653
654 for (i = 0; i <= MPOL_LOCAL; i++) {
655 if (!strcmp(input, policy_types[i])) {
656 td->o.numa_mem_mode = i;
657 break;
658 }
659 }
660 if (i > MPOL_LOCAL) {
661 log_err("fio: memory policy should be: default, prefer, bind, interleave, local\n");
662 goto out;
663 }
664
665 switch (td->o.numa_mem_mode) {
666 case MPOL_PREFERRED:
667 /*
668 * Insist on a nodelist of one node only
669 */
670 if (nodelist) {
671 char *rest = nodelist;
672 while (isdigit(*rest))
673 rest++;
674 if (*rest) {
675 log_err("fio: one node only for \'prefer\'\n");
676 goto out;
677 }
678 } else {
679 log_err("fio: one node is needed for \'prefer\'\n");
680 goto out;
681 }
682 break;
683 case MPOL_INTERLEAVE:
684 /*
685 * Default to online nodes with memory if no nodelist
686 */
687 if (!nodelist)
688 nodelist = strdup("all");
689 break;
690 case MPOL_LOCAL:
691 case MPOL_DEFAULT:
692 /*
693 * Don't allow a nodelist
694 */
695 if (nodelist) {
696 log_err("fio: NO nodelist for \'local\'\n");
697 goto out;
698 }
699 break;
700 case MPOL_BIND:
701 /*
702 * Insist on a nodelist
703 */
704 if (!nodelist) {
705 log_err("fio: a nodelist is needed for \'bind\'\n");
706 goto out;
707 }
708 break;
709 }
710
711
712 /* numa_parse_nodestring() parses a character string list
713 * of nodes into a bit mask. The bit mask is allocated by
714 * numa_allocate_nodemask(), so it should be freed by
715 * numa_free_nodemask().
716 */
717 switch (td->o.numa_mem_mode) {
718 case MPOL_PREFERRED:
719 td->o.numa_mem_prefer_node = atoi(nodelist);
720 break;
721 case MPOL_INTERLEAVE:
722 case MPOL_BIND:
43522848
DG
723 verify_bitmask = numa_parse_nodestring(nodelist);
724 if (verify_bitmask == NULL) {
d0b937ed
YR
725 log_err("fio: numa_parse_nodestring failed\n");
726 td_verror(td, 1, "str_numa_memnodes_cb");
727 return 1;
728 }
43522848
DG
729 td->o.numa_memnodes = strdup(nodelist);
730 numa_free_nodemask(verify_bitmask);
b74e419e 731
d0b937ed
YR
732 break;
733 case MPOL_LOCAL:
734 case MPOL_DEFAULT:
735 default:
736 break;
737 }
738
d0b937ed 739 return 0;
d0b937ed
YR
740out:
741 return 1;
742}
743#endif
744
214e1eca
JA
745static int str_fst_cb(void *data, const char *str)
746{
a609f12a 747 struct thread_data *td = cb_data_to_td(data);
8c07860d
JA
748 double val;
749 bool done = false;
750 char *nr;
214e1eca
JA
751
752 td->file_service_nr = 1;
8c07860d
JA
753
754 switch (td->o.file_service_type) {
755 case FIO_FSERVICE_RANDOM:
756 case FIO_FSERVICE_RR:
757 case FIO_FSERVICE_SEQ:
758 nr = get_opt_postfix(str);
759 if (nr) {
760 td->file_service_nr = atoi(nr);
761 free(nr);
762 }
763 done = true;
764 break;
765 case FIO_FSERVICE_ZIPF:
766 val = FIO_DEF_ZIPF;
767 break;
768 case FIO_FSERVICE_PARETO:
769 val = FIO_DEF_PARETO;
770 break;
771 case FIO_FSERVICE_GAUSS:
772 val = 0.0;
773 break;
774 default:
775 log_err("fio: bad file service type: %d\n", td->o.file_service_type);
776 return 1;
777 }
778
779 if (done)
780 return 0;
781
782 nr = get_opt_postfix(str);
783 if (nr && !str_to_float(nr, &val, 0)) {
784 log_err("fio: file service type random postfix parsing failed\n");
182ec6ee 785 free(nr);
8c07860d
JA
786 return 1;
787 }
788
789 free(nr);
790
791 switch (td->o.file_service_type) {
792 case FIO_FSERVICE_ZIPF:
793 if (val == 1.00) {
794 log_err("fio: zipf theta must be different than 1.0\n");
795 return 1;
796 }
797 if (parse_dryrun())
798 return 0;
799 td->zipf_theta = val;
800 break;
801 case FIO_FSERVICE_PARETO:
802 if (val <= 0.00 || val >= 1.00) {
803 log_err("fio: pareto input out of range (0 < input < 1.0)\n");
804 return 1;
805 }
806 if (parse_dryrun())
807 return 0;
808 td->pareto_h = val;
809 break;
810 case FIO_FSERVICE_GAUSS:
811 if (val < 0.00 || val >= 100.00) {
99c94a6b 812 log_err("fio: normal deviation out of range (0 <= input < 100.0)\n");
8c07860d
JA
813 return 1;
814 }
815 if (parse_dryrun())
816 return 0;
817 td->gauss_dev = val;
818 break;
182ec6ee 819 }
214e1eca
JA
820
821 return 0;
822}
823
67bf9823 824#ifdef CONFIG_SYNC_FILE_RANGE
44f29692
JA
825static int str_sfr_cb(void *data, const char *str)
826{
a609f12a 827 struct thread_data *td = cb_data_to_td(data);
44f29692
JA
828 char *nr = get_opt_postfix(str);
829
830 td->sync_file_range_nr = 1;
831 if (nr) {
832 td->sync_file_range_nr = atoi(nr);
833 free(nr);
834 }
835
836 return 0;
837}
3ae06371 838#endif
44f29692 839
764593c0 840static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir,
59466396 841 char *str, bool absolute)
e0a04ac1 842{
e0a04ac1 843 unsigned int i, perc, perc_missing, sperc, sperc_missing;
d2835319 844 struct split split;
e0a04ac1 845
d2835319 846 memset(&split, 0, sizeof(split));
e0a04ac1 847
b53a2155 848 if (split_parse_ddir(o, &split, ddir, str, absolute, ZONESPLIT_MAX))
d2835319
JA
849 return 1;
850 if (!split.nr)
851 return 0;
e0a04ac1 852
d2835319
JA
853 o->zone_split[ddir] = malloc(split.nr * sizeof(struct zone_split));
854 o->zone_split_nr[ddir] = split.nr;
855 for (i = 0; i < split.nr; i++) {
856 o->zone_split[ddir][i].access_perc = split.val1[i];
59466396
JA
857 if (absolute)
858 o->zone_split[ddir][i].size = split.val2[i];
859 else
860 o->zone_split[ddir][i].size_perc = split.val2[i];
e0a04ac1
JA
861 }
862
e0a04ac1
JA
863 /*
864 * Now check if the percentages add up, and how much is missing
865 */
866 perc = perc_missing = 0;
867 sperc = sperc_missing = 0;
868 for (i = 0; i < o->zone_split_nr[ddir]; i++) {
d2835319 869 struct zone_split *zsp = &o->zone_split[ddir][i];
e0a04ac1
JA
870
871 if (zsp->access_perc == (uint8_t) -1U)
872 perc_missing++;
873 else
874 perc += zsp->access_perc;
875
59466396
JA
876 if (!absolute) {
877 if (zsp->size_perc == (uint8_t) -1U)
878 sperc_missing++;
879 else
880 sperc += zsp->size_perc;
881 }
e0a04ac1
JA
882 }
883
884 if (perc > 100 || sperc > 100) {
885 log_err("fio: zone_split percentages add to more than 100%%\n");
d2835319
JA
886 free(o->zone_split[ddir]);
887 o->zone_split[ddir] = NULL;
e0a04ac1
JA
888 return 1;
889 }
890 if (perc < 100) {
891 log_err("fio: access percentage don't add up to 100 for zoned "
892 "random distribution (got=%u)\n", perc);
d2835319
JA
893 free(o->zone_split[ddir]);
894 o->zone_split[ddir] = NULL;
e0a04ac1
JA
895 return 1;
896 }
897
898 /*
899 * If values didn't have a percentage set, divide the remains between
900 * them.
901 */
902 if (perc_missing) {
903 if (perc_missing == 1 && o->zone_split_nr[ddir] == 1)
904 perc = 100;
905 for (i = 0; i < o->zone_split_nr[ddir]; i++) {
d2835319 906 struct zone_split *zsp = &o->zone_split[ddir][i];
e0a04ac1
JA
907
908 if (zsp->access_perc == (uint8_t) -1U)
909 zsp->access_perc = (100 - perc) / perc_missing;
910 }
911 }
912 if (sperc_missing) {
913 if (sperc_missing == 1 && o->zone_split_nr[ddir] == 1)
914 sperc = 100;
915 for (i = 0; i < o->zone_split_nr[ddir]; i++) {
d2835319 916 struct zone_split *zsp = &o->zone_split[ddir][i];
e0a04ac1
JA
917
918 if (zsp->size_perc == (uint8_t) -1U)
919 zsp->size_perc = (100 - sperc) / sperc_missing;
920 }
921 }
922
e0a04ac1
JA
923 return 0;
924}
925
926static void __td_zone_gen_index(struct thread_data *td, enum fio_ddir ddir)
927{
928 unsigned int i, j, sprev, aprev;
59466396 929 uint64_t sprev_sz;
e0a04ac1
JA
930
931 td->zone_state_index[ddir] = malloc(sizeof(struct zone_split_index) * 100);
932
59466396 933 sprev_sz = sprev = aprev = 0;
e0a04ac1
JA
934 for (i = 0; i < td->o.zone_split_nr[ddir]; i++) {
935 struct zone_split *zsp = &td->o.zone_split[ddir][i];
936
937 for (j = aprev; j < aprev + zsp->access_perc; j++) {
938 struct zone_split_index *zsi = &td->zone_state_index[ddir][j];
939
940 zsi->size_perc = sprev + zsp->size_perc;
941 zsi->size_perc_prev = sprev;
59466396
JA
942
943 zsi->size = sprev_sz + zsp->size;
944 zsi->size_prev = sprev_sz;
e0a04ac1
JA
945 }
946
947 aprev += zsp->access_perc;
948 sprev += zsp->size_perc;
59466396 949 sprev_sz += zsp->size;
e0a04ac1
JA
950 }
951}
952
953/*
954 * Generate state table for indexes, so we don't have to do it inline from
955 * the hot IO path
956 */
957static void td_zone_gen_index(struct thread_data *td)
958{
959 int i;
960
961 td->zone_state_index = malloc(DDIR_RWDIR_CNT *
962 sizeof(struct zone_split_index *));
963
964 for (i = 0; i < DDIR_RWDIR_CNT; i++)
965 __td_zone_gen_index(td, i);
966}
967
59466396
JA
968static int parse_zoned_distribution(struct thread_data *td, const char *input,
969 bool absolute)
e0a04ac1 970{
59466396 971 const char *pre = absolute ? "zoned_abs:" : "zoned:";
764593c0 972 char *str, *p;
e0a04ac1
JA
973 int i, ret = 0;
974
975 p = str = strdup(input);
976
977 strip_blank_front(&str);
978 strip_blank_end(str);
979
980 /* We expect it to start like that, bail if not */
59466396 981 if (strncmp(str, pre, strlen(pre))) {
e0a04ac1
JA
982 log_err("fio: mismatch in zoned input <%s>\n", str);
983 free(p);
984 return 1;
985 }
59466396 986 str += strlen(pre);
e0a04ac1 987
59466396 988 ret = str_split_parse(td, str, zone_split_ddir, absolute);
e0a04ac1
JA
989
990 free(p);
991
992 for (i = 0; i < DDIR_RWDIR_CNT; i++) {
993 int j;
994
995 dprint(FD_PARSE, "zone ddir %d (nr=%u): \n", i, td->o.zone_split_nr[i]);
996
997 for (j = 0; j < td->o.zone_split_nr[i]; j++) {
998 struct zone_split *zsp = &td->o.zone_split[i][j];
999
59466396
JA
1000 if (absolute) {
1001 dprint(FD_PARSE, "\t%d: %u/%llu\n", j,
1002 zsp->access_perc,
1003 (unsigned long long) zsp->size);
1004 } else {
1005 dprint(FD_PARSE, "\t%d: %u/%u\n", j,
1006 zsp->access_perc,
1007 zsp->size_perc);
1008 }
e0a04ac1
JA
1009 }
1010 }
1011
55baca06
JA
1012 if (parse_dryrun()) {
1013 int i;
1014
1015 for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1016 free(td->o.zone_split[i]);
1017 td->o.zone_split[i] = NULL;
1018 td->o.zone_split_nr[i] = 0;
1019 }
1020
1021 return ret;
1022 }
1023
e0a04ac1
JA
1024 if (!ret)
1025 td_zone_gen_index(td);
dc4bffb8
JA
1026 else {
1027 for (i = 0; i < DDIR_RWDIR_CNT; i++)
1028 td->o.zone_split_nr[i] = 0;
1029 }
e0a04ac1
JA
1030
1031 return ret;
1032}
1033
e25839d4
JA
1034static int str_random_distribution_cb(void *data, const char *str)
1035{
a609f12a 1036 struct thread_data *td = cb_data_to_td(data);
e25839d4
JA
1037 double val;
1038 char *nr;
1039
925fee33 1040 if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
c95f9404 1041 val = FIO_DEF_ZIPF;
925fee33 1042 else if (td->o.random_distribution == FIO_RAND_DIST_PARETO)
c95f9404 1043 val = FIO_DEF_PARETO;
56d9fa4b
JA
1044 else if (td->o.random_distribution == FIO_RAND_DIST_GAUSS)
1045 val = 0.0;
e0a04ac1 1046 else if (td->o.random_distribution == FIO_RAND_DIST_ZONED)
59466396
JA
1047 return parse_zoned_distribution(td, str, false);
1048 else if (td->o.random_distribution == FIO_RAND_DIST_ZONED_ABS)
1049 return parse_zoned_distribution(td, str, true);
925fee33 1050 else
e25839d4
JA
1051 return 0;
1052
1053 nr = get_opt_postfix(str);
88038bc7 1054 if (nr && !str_to_float(nr, &val, 0)) {
e25839d4
JA
1055 log_err("fio: random postfix parsing failed\n");
1056 free(nr);
1057 return 1;
1058 }
1059
078189c1
JA
1060 free(nr);
1061
18ded917
JA
1062 if (td->o.random_distribution == FIO_RAND_DIST_ZIPF) {
1063 if (val == 1.00) {
1064 log_err("fio: zipf theta must different than 1.0\n");
1065 return 1;
1066 }
55baca06
JA
1067 if (parse_dryrun())
1068 return 0;
1e5324e7 1069 td->o.zipf_theta.u.f = val;
56d9fa4b 1070 } else if (td->o.random_distribution == FIO_RAND_DIST_PARETO) {
078189c1
JA
1071 if (val <= 0.00 || val >= 1.00) {
1072 log_err("fio: pareto input out of range (0 < input < 1.0)\n");
1073 return 1;
1074 }
55baca06
JA
1075 if (parse_dryrun())
1076 return 0;
1e5324e7 1077 td->o.pareto_h.u.f = val;
3cdb8cf3 1078 } else {
76527b19 1079 if (val < 0.00 || val >= 100.0) {
99c94a6b 1080 log_err("fio: normal deviation out of range (0 <= input < 100.0)\n");
3cdb8cf3
JA
1081 return 1;
1082 }
55baca06
JA
1083 if (parse_dryrun())
1084 return 0;
f88cd222 1085 td->o.gauss_dev.u.f = val;
3cdb8cf3 1086 }
921c766f
JA
1087
1088 return 0;
1089}
1090
16e56d25
VF
1091static int str_steadystate_cb(void *data, const char *str)
1092{
94f218f6 1093 struct thread_data *td = cb_data_to_td(data);
16e56d25
VF
1094 double val;
1095 char *nr;
1096 char *pct;
1097 long long ll;
1098
2c5d94bc
VF
1099 if (td->o.ss_state != FIO_SS_IOPS && td->o.ss_state != FIO_SS_IOPS_SLOPE &&
1100 td->o.ss_state != FIO_SS_BW && td->o.ss_state != FIO_SS_BW_SLOPE) {
16e56d25
VF
1101 /* should be impossible to get here */
1102 log_err("fio: unknown steady state criterion\n");
1103 return 1;
1104 }
1105
1106 nr = get_opt_postfix(str);
1107 if (!nr) {
1108 log_err("fio: steadystate threshold must be specified in addition to criterion\n");
1109 free(nr);
1110 return 1;
1111 }
1112
1113 /* ENHANCEMENT Allow fio to understand size=10.2% and use here */
1114 pct = strstr(nr, "%");
1115 if (pct) {
1116 *pct = '\0';
1117 strip_blank_end(nr);
1118 if (!str_to_float(nr, &val, 0)) {
1119 log_err("fio: could not parse steadystate threshold percentage\n");
1120 free(nr);
1121 return 1;
1122 }
1123
1124 dprint(FD_PARSE, "set steady state threshold to %f%%\n", val);
1125 free(nr);
1126 if (parse_dryrun())
1127 return 0;
1128
c8caba48 1129 td->o.ss_state |= FIO_SS_PCT;
16e56d25 1130 td->o.ss_limit.u.f = val;
c8caba48 1131 } else if (td->o.ss_state & FIO_SS_IOPS) {
16e56d25
VF
1132 if (!str_to_float(nr, &val, 0)) {
1133 log_err("fio: steadystate IOPS threshold postfix parsing failed\n");
1134 free(nr);
1135 return 1;
1136 }
1137
1138 dprint(FD_PARSE, "set steady state IOPS threshold to %f\n", val);
1139 free(nr);
1140 if (parse_dryrun())
1141 return 0;
1142
16e56d25 1143 td->o.ss_limit.u.f = val;
16e56d25
VF
1144 } else { /* bandwidth criterion */
1145 if (str_to_decimal(nr, &ll, 1, td, 0, 0)) {
1146 log_err("fio: steadystate BW threshold postfix parsing failed\n");
1147 free(nr);
1148 return 1;
1149 }
1150
1151 dprint(FD_PARSE, "set steady state BW threshold to %lld\n", ll);
1152 free(nr);
1153 if (parse_dryrun())
1154 return 0;
1155
16e56d25 1156 td->o.ss_limit.u.f = (double) ll;
16e56d25
VF
1157 }
1158
2c5d94bc 1159 td->ss.state = td->o.ss_state;
16e56d25
VF
1160 return 0;
1161}
1162
8e827d35 1163/*
bcbfeefa 1164 * Return next name in the string. Files are separated with ':'. If the ':'
8e827d35
JA
1165 * is escaped with a '\', then that ':' is part of the filename and does not
1166 * indicate a new file.
1167 */
bcbfeefa 1168static char *get_next_name(char **ptr)
8e827d35
JA
1169{
1170 char *str = *ptr;
1171 char *p, *start;
1172
1173 if (!str || !strlen(str))
1174 return NULL;
1175
1176 start = str;
1177 do {
1178 /*
1179 * No colon, we are done
1180 */
1181 p = strchr(str, ':');
1182 if (!p) {
1183 *ptr = NULL;
1184 break;
1185 }
1186
1187 /*
1188 * We got a colon, but it's the first character. Skip and
1189 * continue
1190 */
1191 if (p == start) {
1192 str = ++start;
1193 continue;
1194 }
1195
1196 if (*(p - 1) != '\\') {
1197 *p = '\0';
1198 *ptr = p + 1;
1199 break;
1200 }
1201
1202 memmove(p - 1, p, strlen(p) + 1);
1203 str = p;
1204 } while (1);
1205
1206 return start;
1207}
1208
bcbfeefa
CE
1209
1210static int get_max_name_idx(char *input)
1211{
1212 unsigned int cur_idx;
1213 char *str, *p;
1214
1215 p = str = strdup(input);
1216 for (cur_idx = 0; ; cur_idx++)
1217 if (get_next_name(&str) == NULL)
1218 break;
1219
1220 free(p);
1221 return cur_idx;
1222}
1223
1224/*
1225 * Returns the directory at the index, indexes > entires will be
1226 * assigned via modulo division of the index
1227 */
922a5be8
JA
1228int set_name_idx(char *target, size_t tlen, char *input, int index,
1229 bool unique_filename)
bcbfeefa
CE
1230{
1231 unsigned int cur_idx;
1232 int len;
1233 char *fname, *str, *p;
1234
1235 p = str = strdup(input);
1236
1237 index %= get_max_name_idx(input);
1238 for (cur_idx = 0; cur_idx <= index; cur_idx++)
1239 fname = get_next_name(&str);
1240
922a5be8 1241 if (client_sockaddr_str[0] && unique_filename) {
e13c3b50
JA
1242 len = snprintf(target, tlen, "%s/%s.", fname,
1243 client_sockaddr_str);
1244 } else
1245 len = snprintf(target, tlen, "%s/", fname);
72a703da 1246
e13c3b50 1247 target[tlen - 1] = '\0';
bcbfeefa
CE
1248 free(p);
1249
1250 return len;
1251}
1252
214e1eca
JA
1253static int str_filename_cb(void *data, const char *input)
1254{
a609f12a 1255 struct thread_data *td = cb_data_to_td(data);
214e1eca
JA
1256 char *fname, *str, *p;
1257
1258 p = str = strdup(input);
1259
1260 strip_blank_front(&str);
1261 strip_blank_end(str);
1262
79591fa9
TK
1263 /*
1264 * Ignore what we may already have from nrfiles option.
1265 */
214e1eca 1266 if (!td->files_index)
2dc1bbeb 1267 td->o.nr_files = 0;
214e1eca 1268
bcbfeefa 1269 while ((fname = get_next_name(&str)) != NULL) {
214e1eca
JA
1270 if (!strlen(fname))
1271 break;
5903e7b7 1272 add_file(td, fname, 0, 1);
214e1eca
JA
1273 }
1274
1275 free(p);
1276 return 0;
1277}
1278
bcbfeefa 1279static int str_directory_cb(void *data, const char fio_unused *unused)
214e1eca 1280{
a609f12a 1281 struct thread_data *td = cb_data_to_td(data);
214e1eca 1282 struct stat sb;
bcbfeefa
CE
1283 char *dirname, *str, *p;
1284 int ret = 0;
214e1eca 1285
f9633d72
JA
1286 if (parse_dryrun())
1287 return 0;
1288
bcbfeefa
CE
1289 p = str = strdup(td->o.directory);
1290 while ((dirname = get_next_name(&str)) != NULL) {
1291 if (lstat(dirname, &sb) < 0) {
1292 ret = errno;
921c766f 1293
bcbfeefa
CE
1294 log_err("fio: %s is not a directory\n", dirname);
1295 td_verror(td, ret, "lstat");
1296 goto out;
1297 }
1298 if (!S_ISDIR(sb.st_mode)) {
1299 log_err("fio: %s is not a directory\n", dirname);
1300 ret = 1;
1301 goto out;
1302 }
214e1eca
JA
1303 }
1304
bcbfeefa
CE
1305out:
1306 free(p);
1307 return ret;
214e1eca
JA
1308}
1309
1310static int str_opendir_cb(void *data, const char fio_unused *str)
1311{
a609f12a 1312 struct thread_data *td = cb_data_to_td(data);
214e1eca 1313
52c0cea3
JA
1314 if (parse_dryrun())
1315 return 0;
1316
214e1eca 1317 if (!td->files_index)
2dc1bbeb 1318 td->o.nr_files = 0;
214e1eca 1319
2dc1bbeb 1320 return add_dir_files(td, td->o.opendir);
214e1eca
JA
1321}
1322
ce35b1ec
JA
1323static int str_buffer_pattern_cb(void *data, const char *input)
1324{
a609f12a 1325 struct thread_data *td = cb_data_to_td(data);
ce35b1ec
JA
1326 int ret;
1327
61b9861d
RP
1328 /* FIXME: for now buffer pattern does not support formats */
1329 ret = parse_and_fill_pattern(input, strlen(input), td->o.buffer_pattern,
1330 MAX_PATTERN_SIZE, NULL, 0, NULL, NULL);
1331 if (ret < 0)
1332 return 1;
ce35b1ec 1333
61b9861d
RP
1334 assert(ret != 0);
1335 td->o.buffer_pattern_bytes = ret;
c55fae03
JA
1336
1337 /*
1338 * If this job is doing any reading or has compression set,
1339 * ensure that we refill buffers for writes or we could be
1340 * invalidating the pattern through reads.
1341 */
1342 if (!td->o.compress_percentage && !td_read(td))
61b9861d 1343 td->o.refill_buffers = 0;
c55fae03
JA
1344 else
1345 td->o.refill_buffers = 1;
1346
61b9861d
RP
1347 td->o.scramble_buffers = 0;
1348 td->o.zero_buffers = 0;
efcd9dcc 1349
61b9861d 1350 return 0;
ce35b1ec
JA
1351}
1352
bedc9dc2
JA
1353static int str_buffer_compress_cb(void *data, unsigned long long *il)
1354{
a609f12a 1355 struct thread_data *td = cb_data_to_td(data);
bedc9dc2
JA
1356
1357 td->flags |= TD_F_COMPRESS;
1358 td->o.compress_percentage = *il;
1359 return 0;
1360}
1361
5c94b008
JA
1362static int str_dedupe_cb(void *data, unsigned long long *il)
1363{
a609f12a 1364 struct thread_data *td = cb_data_to_td(data);
5c94b008
JA
1365
1366 td->flags |= TD_F_COMPRESS;
1367 td->o.dedupe_percentage = *il;
1368 td->o.refill_buffers = 1;
1369 return 0;
1370}
1371
ce35b1ec
JA
1372static int str_verify_pattern_cb(void *data, const char *input)
1373{
a609f12a 1374 struct thread_data *td = cb_data_to_td(data);
ce35b1ec
JA
1375 int ret;
1376
61b9861d
RP
1377 td->o.verify_fmt_sz = ARRAY_SIZE(td->o.verify_fmt);
1378 ret = parse_and_fill_pattern(input, strlen(input), td->o.verify_pattern,
4205998f
JA
1379 MAX_PATTERN_SIZE, fmt_desc, sizeof(fmt_desc),
1380 td->o.verify_fmt, &td->o.verify_fmt_sz);
61b9861d
RP
1381 if (ret < 0)
1382 return 1;
efcd9dcc 1383
61b9861d
RP
1384 assert(ret != 0);
1385 td->o.verify_pattern_bytes = ret;
92bf48d5 1386 /*
b638d82f 1387 * VERIFY_* could already be set
92bf48d5 1388 */
61b9861d 1389 if (!fio_option_is_set(&td->o, verify))
92bf48d5 1390 td->o.verify = VERIFY_PATTERN;
efcd9dcc 1391
61b9861d 1392 return 0;
90059d65 1393}
214e1eca 1394
993bf48b
JA
1395static int str_gtod_reduce_cb(void *data, int *il)
1396{
a609f12a 1397 struct thread_data *td = cb_data_to_td(data);
993bf48b
JA
1398 int val = *il;
1399
02af0988 1400 td->o.disable_lat = !!val;
993bf48b
JA
1401 td->o.disable_clat = !!val;
1402 td->o.disable_slat = !!val;
1403 td->o.disable_bw = !!val;
0dc1bc03 1404 td->o.clat_percentiles = !val;
993bf48b 1405 if (val)
8b6a404c 1406 td->ts_cache_mask = 63;
993bf48b
JA
1407
1408 return 0;
1409}
1410
89978a6b
BW
1411static int str_offset_cb(void *data, unsigned long long *__val)
1412{
1413 struct thread_data *td = cb_data_to_td(data);
1414 unsigned long long v = *__val;
1415
1416 if (parse_is_percent(v)) {
1417 td->o.start_offset = 0;
1418 td->o.start_offset_percent = -1ULL - v;
872e0415
JA
1419 dprint(FD_PARSE, "SET start_offset_percent %d\n",
1420 td->o.start_offset_percent);
89978a6b
BW
1421 } else
1422 td->o.start_offset = v;
1423
1424 return 0;
1425}
1426
7bb59102
JA
1427static int str_size_cb(void *data, unsigned long long *__val)
1428{
a609f12a 1429 struct thread_data *td = cb_data_to_td(data);
7bb59102
JA
1430 unsigned long long v = *__val;
1431
1432 if (parse_is_percent(v)) {
1433 td->o.size = 0;
1434 td->o.size_percent = -1ULL - v;
24e4321c
TK
1435 dprint(FD_PARSE, "SET size_percent %d\n",
1436 td->o.size_percent);
7bb59102
JA
1437 } else
1438 td->o.size = v;
1439
1440 return 0;
1441}
1442
dded427c
OS
1443static int str_write_bw_log_cb(void *data, const char *str)
1444{
1445 struct thread_data *td = cb_data_to_td(data);
1446
1447 if (str)
1448 td->o.bw_log_file = strdup(str);
1449
1450 td->o.write_bw_log = 1;
1451 return 0;
1452}
1453
1454static int str_write_lat_log_cb(void *data, const char *str)
1455{
1456 struct thread_data *td = cb_data_to_td(data);
1457
1458 if (str)
1459 td->o.lat_log_file = strdup(str);
1460
1461 td->o.write_lat_log = 1;
1462 return 0;
1463}
1464
1465static int str_write_iops_log_cb(void *data, const char *str)
1466{
1467 struct thread_data *td = cb_data_to_td(data);
1468
1469 if (str)
1470 td->o.iops_log_file = strdup(str);
1471
1472 td->o.write_iops_log = 1;
1473 return 0;
1474}
1475
1476static int str_write_hist_log_cb(void *data, const char *str)
1477{
1478 struct thread_data *td = cb_data_to_td(data);
1479
1480 if (str)
1481 td->o.hist_log_file = strdup(str);
1482
1483 td->o.write_hist_log = 1;
1484 return 0;
1485}
1486
6730b40f
TK
1487/*
1488 * str is supposed to be a substring of the strdup'd original string,
1489 * and is valid only if it's a regular file path.
1490 * This function keeps the pointer to the path as needed later.
1491 *
1492 * "external:/path/to/so\0" <- original pointer updated with strdup'd
1493 * "external\0" <- above pointer after parsed, i.e. ->ioengine
1494 * "/path/to/so\0" <- str argument, i.e. ->ioengine_so_path
1495 */
1496static int str_ioengine_external_cb(void *data, const char *str)
1497{
1498 struct thread_data *td = cb_data_to_td(data);
1499 struct stat sb;
1500 char *p;
1501
1502 if (!str) {
1503 log_err("fio: null external ioengine path\n");
1504 return 1;
1505 }
1506
1507 p = (char *)str; /* str is mutable */
1508 strip_blank_front(&p);
1509 strip_blank_end(p);
1510
1511 if (stat(p, &sb) || !S_ISREG(sb.st_mode)) {
1512 log_err("fio: invalid external ioengine path \"%s\"\n", p);
1513 return 1;
1514 }
1515
1516 td->o.ioengine_so_path = p;
1517 return 0;
1518}
1519
9109883a 1520static int rw_verify(const struct fio_option *o, void *data)
896cac2a 1521{
a609f12a 1522 struct thread_data *td = cb_data_to_td(data);
896cac2a
JA
1523
1524 if (read_only && td_write(td)) {
1525 log_err("fio: job <%s> has write bit set, but fio is in"
1526 " read-only mode\n", td->o.name);
1527 return 1;
1528 }
1529
1530 return 0;
1531}
1532
9109883a 1533static int gtod_cpu_verify(const struct fio_option *o, void *data)
29d43ff9 1534{
276ca4f7 1535#ifndef FIO_HAVE_CPU_AFFINITY
a609f12a 1536 struct thread_data *td = cb_data_to_td(data);
29d43ff9 1537
29d43ff9
JA
1538 if (td->o.gtod_cpu) {
1539 log_err("fio: platform must support CPU affinity for"
1540 "gettimeofday() offloading\n");
1541 return 1;
1542 }
1543#endif
1544
1545 return 0;
1546}
1547
214e1eca
JA
1548/*
1549 * Map of job/command line options
1550 */
9af4a244 1551struct fio_option fio_options[FIO_MAX_OPTS] = {
214e1eca
JA
1552 {
1553 .name = "description",
e8b0e958 1554 .lname = "Description of job",
214e1eca 1555 .type = FIO_OPT_STR_STORE,
a609f12a 1556 .off1 = offsetof(struct thread_options, description),
214e1eca 1557 .help = "Text job description",
e8b0e958 1558 .category = FIO_OPT_C_GENERAL,
0626037e 1559 .group = FIO_OPT_G_DESC,
214e1eca
JA
1560 },
1561 {
1562 .name = "name",
e8b0e958 1563 .lname = "Job name",
214e1eca 1564 .type = FIO_OPT_STR_STORE,
a609f12a 1565 .off1 = offsetof(struct thread_options, name),
214e1eca 1566 .help = "Name of this job",
e8b0e958 1567 .category = FIO_OPT_C_GENERAL,
0626037e 1568 .group = FIO_OPT_G_DESC,
214e1eca 1569 },
9cc8cb91
AK
1570 {
1571 .name = "wait_for",
1572 .lname = "Waitee name",
1573 .type = FIO_OPT_STR_STORE,
a609f12a 1574 .off1 = offsetof(struct thread_options, wait_for),
9cc8cb91
AK
1575 .help = "Name of the job this one wants to wait for before starting",
1576 .category = FIO_OPT_C_GENERAL,
1577 .group = FIO_OPT_G_DESC,
1578 },
214e1eca
JA
1579 {
1580 .name = "filename",
e8b0e958 1581 .lname = "Filename(s)",
214e1eca 1582 .type = FIO_OPT_STR_STORE,
a609f12a 1583 .off1 = offsetof(struct thread_options, filename),
214e1eca 1584 .cb = str_filename_cb,
f0d524b0 1585 .prio = -1, /* must come after "directory" */
214e1eca 1586 .help = "File(s) to use for the workload",
e8b0e958 1587 .category = FIO_OPT_C_FILE,
0626037e 1588 .group = FIO_OPT_G_FILENAME,
214e1eca 1589 },
90fef2d1 1590 {
e8b0e958
JA
1591 .name = "directory",
1592 .lname = "Directory",
1593 .type = FIO_OPT_STR_STORE,
a609f12a 1594 .off1 = offsetof(struct thread_options, directory),
e8b0e958
JA
1595 .cb = str_directory_cb,
1596 .help = "Directory to store files in",
1597 .category = FIO_OPT_C_FILE,
0626037e 1598 .group = FIO_OPT_G_FILENAME,
90fef2d1 1599 },
de98bd30
JA
1600 {
1601 .name = "filename_format",
922a5be8 1602 .lname = "Filename Format",
de98bd30 1603 .type = FIO_OPT_STR_STORE,
a609f12a 1604 .off1 = offsetof(struct thread_options, filename_format),
de98bd30
JA
1605 .prio = -1, /* must come after "directory" */
1606 .help = "Override default $jobname.$jobnum.$filenum naming",
1607 .def = "$jobname.$jobnum.$filenum",
93bb626a
JA
1608 .category = FIO_OPT_C_FILE,
1609 .group = FIO_OPT_G_FILENAME,
ad705bcb 1610 },
922a5be8
JA
1611 {
1612 .name = "unique_filename",
1613 .lname = "Unique Filename",
1614 .type = FIO_OPT_BOOL,
a609f12a 1615 .off1 = offsetof(struct thread_options, unique_filename),
922a5be8
JA
1616 .help = "For network clients, prefix file with source IP",
1617 .def = "1",
1618 .category = FIO_OPT_C_FILE,
1619 .group = FIO_OPT_G_FILENAME,
1620 },
29c1349f
JA
1621 {
1622 .name = "lockfile",
e8b0e958 1623 .lname = "Lockfile",
4d4e80f2 1624 .type = FIO_OPT_STR,
a609f12a 1625 .off1 = offsetof(struct thread_options, file_lock_mode),
29c1349f 1626 .help = "Lock file when doing IO to it",
bc6a0a5d 1627 .prio = 1,
29c1349f 1628 .parent = "filename",
d71c154c 1629 .hide = 0,
4d4e80f2 1630 .def = "none",
e8b0e958 1631 .category = FIO_OPT_C_FILE,
0626037e 1632 .group = FIO_OPT_G_FILENAME,
4d4e80f2
JA
1633 .posval = {
1634 { .ival = "none",
1635 .oval = FILE_LOCK_NONE,
1636 .help = "No file locking",
1637 },
1638 { .ival = "exclusive",
1639 .oval = FILE_LOCK_EXCLUSIVE,
1640 .help = "Exclusive file lock",
1641 },
1642 {
1643 .ival = "readwrite",
1644 .oval = FILE_LOCK_READWRITE,
1645 .help = "Read vs write lock",
1646 },
1647 },
29c1349f 1648 },
214e1eca
JA
1649 {
1650 .name = "opendir",
e8b0e958 1651 .lname = "Open directory",
214e1eca 1652 .type = FIO_OPT_STR_STORE,
a609f12a 1653 .off1 = offsetof(struct thread_options, opendir),
214e1eca
JA
1654 .cb = str_opendir_cb,
1655 .help = "Recursively add files from this directory and down",
e8b0e958 1656 .category = FIO_OPT_C_FILE,
0626037e 1657 .group = FIO_OPT_G_FILENAME,
214e1eca
JA
1658 },
1659 {
1660 .name = "rw",
e8b0e958 1661 .lname = "Read/write",
d3aad8f2 1662 .alias = "readwrite",
214e1eca 1663 .type = FIO_OPT_STR,
211097b2 1664 .cb = str_rw_cb,
a609f12a 1665 .off1 = offsetof(struct thread_options, td_ddir),
214e1eca
JA
1666 .help = "IO direction",
1667 .def = "read",
896cac2a 1668 .verify = rw_verify,
e8b0e958 1669 .category = FIO_OPT_C_IO,
0626037e 1670 .group = FIO_OPT_G_IO_BASIC,
214e1eca
JA
1671 .posval = {
1672 { .ival = "read",
1673 .oval = TD_DDIR_READ,
1674 .help = "Sequential read",
1675 },
1676 { .ival = "write",
1677 .oval = TD_DDIR_WRITE,
1678 .help = "Sequential write",
1679 },
6eaf09d6
SL
1680 { .ival = "trim",
1681 .oval = TD_DDIR_TRIM,
1682 .help = "Sequential trim",
1683 },
214e1eca
JA
1684 { .ival = "randread",
1685 .oval = TD_DDIR_RANDREAD,
1686 .help = "Random read",
1687 },
1688 { .ival = "randwrite",
1689 .oval = TD_DDIR_RANDWRITE,
1690 .help = "Random write",
1691 },
6eaf09d6
SL
1692 { .ival = "randtrim",
1693 .oval = TD_DDIR_RANDTRIM,
1694 .help = "Random trim",
1695 },
214e1eca
JA
1696 { .ival = "rw",
1697 .oval = TD_DDIR_RW,
1698 .help = "Sequential read and write mix",
1699 },
10b023db
JA
1700 { .ival = "readwrite",
1701 .oval = TD_DDIR_RW,
1702 .help = "Sequential read and write mix",
1703 },
214e1eca
JA
1704 { .ival = "randrw",
1705 .oval = TD_DDIR_RANDRW,
1706 .help = "Random read and write mix"
1707 },
82a90686
JA
1708 { .ival = "trimwrite",
1709 .oval = TD_DDIR_TRIMWRITE,
1710 .help = "Trim and write mix, trims preceding writes"
0e4dd95c 1711 },
214e1eca
JA
1712 },
1713 },
38dad62d
JA
1714 {
1715 .name = "rw_sequencer",
e8b0e958 1716 .lname = "RW Sequencer",
38dad62d 1717 .type = FIO_OPT_STR,
a609f12a 1718 .off1 = offsetof(struct thread_options, rw_seq),
38dad62d
JA
1719 .help = "IO offset generator modifier",
1720 .def = "sequential",
e8b0e958 1721 .category = FIO_OPT_C_IO,
0626037e 1722 .group = FIO_OPT_G_IO_BASIC,
38dad62d
JA
1723 .posval = {
1724 { .ival = "sequential",
1725 .oval = RW_SEQ_SEQ,
1726 .help = "Generate sequential offsets",
1727 },
1728 { .ival = "identical",
1729 .oval = RW_SEQ_IDENT,
1730 .help = "Generate identical offsets",
1731 },
1732 },
1733 },
1734
214e1eca
JA
1735 {
1736 .name = "ioengine",
e8b0e958 1737 .lname = "IO Engine",
214e1eca 1738 .type = FIO_OPT_STR_STORE,
a609f12a 1739 .off1 = offsetof(struct thread_options, ioengine),
214e1eca 1740 .help = "IO engine to use",
58483fa4 1741 .def = FIO_PREFERRED_ENGINE,
e8b0e958 1742 .category = FIO_OPT_C_IO,
0626037e 1743 .group = FIO_OPT_G_IO_BASIC,
214e1eca
JA
1744 .posval = {
1745 { .ival = "sync",
1746 .help = "Use read/write",
1747 },
a31041ea 1748 { .ival = "psync",
1749 .help = "Use pread/pwrite",
1750 },
1d2af02a 1751 { .ival = "vsync",
03e20d68 1752 .help = "Use readv/writev",
1d2af02a 1753 },
07fc0acd
JA
1754#ifdef CONFIG_PWRITEV
1755 { .ival = "pvsync",
1756 .help = "Use preadv/pwritev",
1757 },
1758#endif
6562685f 1759#ifdef FIO_HAVE_PWRITEV2
2cafffbe
JA
1760 { .ival = "pvsync2",
1761 .help = "Use preadv2/pwritev2",
1762 },
1763#endif
67bf9823 1764#ifdef CONFIG_LIBAIO
214e1eca
JA
1765 { .ival = "libaio",
1766 .help = "Linux native asynchronous IO",
1767 },
1768#endif
67bf9823 1769#ifdef CONFIG_POSIXAIO
214e1eca
JA
1770 { .ival = "posixaio",
1771 .help = "POSIX asynchronous IO",
1772 },
417f0068 1773#endif
997843cb 1774#ifdef CONFIG_SOLARISAIO
417f0068
JA
1775 { .ival = "solarisaio",
1776 .help = "Solaris native asynchronous IO",
1777 },
214e1eca 1778#endif
4700b234 1779#ifdef CONFIG_WINDOWSAIO
03e20d68 1780 { .ival = "windowsaio",
3be80071 1781 .help = "Windows native asynchronous IO"
de890a1e 1782 },
fc5c0345
DG
1783#endif
1784#ifdef CONFIG_RBD
1785 { .ival = "rbd",
1786 .help = "Rados Block Device asynchronous IO"
1787 },
3be80071 1788#endif
214e1eca 1789 { .ival = "mmap",
03e20d68 1790 .help = "Memory mapped IO"
214e1eca 1791 },
67bf9823 1792#ifdef CONFIG_LINUX_SPLICE
214e1eca
JA
1793 { .ival = "splice",
1794 .help = "splice/vmsplice based IO",
1795 },
9cce02e8
JA
1796 { .ival = "netsplice",
1797 .help = "splice/vmsplice to/from the network",
1798 },
214e1eca
JA
1799#endif
1800#ifdef FIO_HAVE_SGIO
1801 { .ival = "sg",
1802 .help = "SCSI generic v3 IO",
1803 },
1804#endif
1805 { .ival = "null",
1806 .help = "Testing engine (no data transfer)",
1807 },
1808 { .ival = "net",
1809 .help = "Network IO",
1810 },
214e1eca 1811 { .ival = "cpuio",
03e20d68 1812 .help = "CPU cycle burner engine",
214e1eca 1813 },
67bf9823 1814#ifdef CONFIG_GUASI
b8c82a46
JA
1815 { .ival = "guasi",
1816 .help = "GUASI IO engine",
1817 },
79a43187 1818#endif
67bf9823 1819#ifdef CONFIG_RDMA
21b8aee8 1820 { .ival = "rdma",
1821 .help = "RDMA IO engine",
1822 },
8200b8c7 1823#endif
67bf9823 1824#ifdef CONFIG_FUSION_AW
8200b8c7
JA
1825 { .ival = "fusion-aw-sync",
1826 .help = "Fusion-io atomic write engine",
1827 },
1ecc95ca 1828#endif
997843cb 1829#ifdef CONFIG_LINUX_EXT4_MOVE_EXTENT
1ecc95ca
JA
1830 { .ival = "e4defrag",
1831 .help = "ext4 defrag engine",
1832 },
1833#endif
997843cb 1834#ifdef CONFIG_LINUX_FALLOCATE
1ecc95ca
JA
1835 { .ival = "falloc",
1836 .help = "fallocate() file based engine",
1837 },
b8c82a46 1838#endif
a7c386f4 1839#ifdef CONFIG_GFAPI
1840 { .ival = "gfapi",
cc47f094 1841 .help = "Glusterfs libgfapi(sync) based engine"
1842 },
1843 { .ival = "gfapi_async",
1844 .help = "Glusterfs libgfapi(async) based engine"
a7c386f4 1845 },
1846#endif
1b10477b 1847#ifdef CONFIG_LIBHDFS
b74e419e 1848 { .ival = "libhdfs",
1b10477b
MM
1849 .help = "Hadoop Distributed Filesystem (HDFS) engine"
1850 },
5c4ef02e
JA
1851#endif
1852#ifdef CONFIG_PMEMBLK
1853 { .ival = "pmemblk",
363a5f65 1854 .help = "PMDK libpmemblk based IO engine",
5c4ef02e
JA
1855 },
1856
104ee4de
DJ
1857#endif
1858#ifdef CONFIG_LINUX_DEVDAX
1859 { .ival = "dev-dax",
1860 .help = "DAX Device based IO engine",
1861 },
1b10477b 1862#endif
edc5fa12
JA
1863 {
1864 .ival = "filecreate",
1865 .help = "File creation engine",
1866 },
214e1eca
JA
1867 { .ival = "external",
1868 .help = "Load external engine (append name)",
6730b40f 1869 .cb = str_ioengine_external_cb,
214e1eca 1870 },
ae0db592
TI
1871#ifdef CONFIG_LIBPMEM
1872 { .ival = "libpmem",
363a5f65 1873 .help = "PMDK libpmem based IO engine",
ae0db592
TI
1874 },
1875#endif
214e1eca
JA
1876 },
1877 },
1878 {
1879 .name = "iodepth",
e8b0e958 1880 .lname = "IO Depth",
214e1eca 1881 .type = FIO_OPT_INT,
a609f12a 1882 .off1 = offsetof(struct thread_options, iodepth),
03e20d68 1883 .help = "Number of IO buffers to keep in flight",
757aff4f 1884 .minval = 1,
20eb06bd 1885 .interval = 1,
214e1eca 1886 .def = "1",
e8b0e958 1887 .category = FIO_OPT_C_IO,
0626037e 1888 .group = FIO_OPT_G_IO_BASIC,
214e1eca
JA
1889 },
1890 {
1891 .name = "iodepth_batch",
e8b0e958 1892 .lname = "IO Depth batch",
4950421a 1893 .alias = "iodepth_batch_submit",
214e1eca 1894 .type = FIO_OPT_INT,
a609f12a 1895 .off1 = offsetof(struct thread_options, iodepth_batch),
d65db441 1896 .help = "Number of IO buffers to submit in one go",
afdf9352 1897 .parent = "iodepth",
d71c154c 1898 .hide = 1,
20eb06bd 1899 .interval = 1,
a2e6f8ac 1900 .def = "1",
e8b0e958 1901 .category = FIO_OPT_C_IO,
0626037e 1902 .group = FIO_OPT_G_IO_BASIC,
4950421a
JA
1903 },
1904 {
82407585
RP
1905 .name = "iodepth_batch_complete_min",
1906 .lname = "Min IO depth batch complete",
1907 .alias = "iodepth_batch_complete",
4950421a 1908 .type = FIO_OPT_INT,
a609f12a 1909 .off1 = offsetof(struct thread_options, iodepth_batch_complete_min),
82407585 1910 .help = "Min number of IO buffers to retrieve in one go",
4950421a 1911 .parent = "iodepth",
d71c154c 1912 .hide = 1,
4950421a 1913 .minval = 0,
20eb06bd 1914 .interval = 1,
4950421a 1915 .def = "1",
e8b0e958 1916 .category = FIO_OPT_C_IO,
0626037e 1917 .group = FIO_OPT_G_IO_BASIC,
214e1eca 1918 },
82407585
RP
1919 {
1920 .name = "iodepth_batch_complete_max",
1921 .lname = "Max IO depth batch complete",
1922 .type = FIO_OPT_INT,
a609f12a 1923 .off1 = offsetof(struct thread_options, iodepth_batch_complete_max),
82407585
RP
1924 .help = "Max number of IO buffers to retrieve in one go",
1925 .parent = "iodepth",
1926 .hide = 1,
1927 .minval = 0,
1928 .interval = 1,
1929 .category = FIO_OPT_C_IO,
1930 .group = FIO_OPT_G_IO_BASIC,
1931 },
214e1eca
JA
1932 {
1933 .name = "iodepth_low",
e8b0e958 1934 .lname = "IO Depth batch low",
214e1eca 1935 .type = FIO_OPT_INT,
a609f12a 1936 .off1 = offsetof(struct thread_options, iodepth_low),
214e1eca 1937 .help = "Low water mark for queuing depth",
afdf9352 1938 .parent = "iodepth",
d71c154c 1939 .hide = 1,
20eb06bd 1940 .interval = 1,
e8b0e958 1941 .category = FIO_OPT_C_IO,
0626037e 1942 .group = FIO_OPT_G_IO_BASIC,
214e1eca 1943 },
997b5680
SW
1944 {
1945 .name = "serialize_overlap",
1946 .lname = "Serialize overlap",
1947 .off1 = offsetof(struct thread_options, serialize_overlap),
1948 .type = FIO_OPT_BOOL,
1949 .help = "Wait for in-flight IOs that collide to complete",
1950 .parent = "iodepth",
1951 .def = "0",
1952 .category = FIO_OPT_C_IO,
1953 .group = FIO_OPT_G_IO_BASIC,
1954 },
a9da8ab2
JA
1955 {
1956 .name = "io_submit_mode",
1957 .lname = "IO submit mode",
1958 .type = FIO_OPT_STR,
a609f12a 1959 .off1 = offsetof(struct thread_options, io_submit_mode),
a9da8ab2
JA
1960 .help = "How IO submissions and completions are done",
1961 .def = "inline",
1962 .category = FIO_OPT_C_IO,
1963 .group = FIO_OPT_G_IO_BASIC,
1964 .posval = {
1965 { .ival = "inline",
1966 .oval = IO_MODE_INLINE,
1967 .help = "Submit and complete IO inline",
1968 },
1969 { .ival = "offload",
1970 .oval = IO_MODE_OFFLOAD,
1971 .help = "Offload submit and complete to threads",
1972 },
1973 },
1974 },
214e1eca
JA
1975 {
1976 .name = "size",
e8b0e958 1977 .lname = "Size",
214e1eca 1978 .type = FIO_OPT_STR_VAL,
7bb59102 1979 .cb = str_size_cb,
a609f12a 1980 .off1 = offsetof(struct thread_options, size),
214e1eca 1981 .help = "Total size of device or files",
20eb06bd 1982 .interval = 1024 * 1024,
e8b0e958
JA
1983 .category = FIO_OPT_C_IO,
1984 .group = FIO_OPT_G_INVALID,
214e1eca 1985 },
77731b29 1986 {
a4d3b4db
JA
1987 .name = "io_size",
1988 .alias = "io_limit",
1989 .lname = "IO Size",
77731b29 1990 .type = FIO_OPT_STR_VAL,
5be9bf09 1991 .off1 = offsetof(struct thread_options, io_size),
1684f7fd 1992 .help = "Total size of I/O to be performed",
77731b29
JA
1993 .interval = 1024 * 1024,
1994 .category = FIO_OPT_C_IO,
1995 .group = FIO_OPT_G_INVALID,
1996 },
aa31f1f1
SL
1997 {
1998 .name = "fill_device",
e8b0e958 1999 .lname = "Fill device",
74586c1e 2000 .alias = "fill_fs",
aa31f1f1 2001 .type = FIO_OPT_BOOL,
a609f12a 2002 .off1 = offsetof(struct thread_options, fill_device),
aa31f1f1
SL
2003 .help = "Write until an ENOSPC error occurs",
2004 .def = "0",
e8b0e958
JA
2005 .category = FIO_OPT_C_FILE,
2006 .group = FIO_OPT_G_INVALID,
aa31f1f1 2007 },
214e1eca
JA
2008 {
2009 .name = "filesize",
e8b0e958 2010 .lname = "File size",
214e1eca 2011 .type = FIO_OPT_STR_VAL,
a609f12a
JA
2012 .off1 = offsetof(struct thread_options, file_size_low),
2013 .off2 = offsetof(struct thread_options, file_size_high),
c3edbdba 2014 .minval = 1,
214e1eca 2015 .help = "Size of individual files",
20eb06bd 2016 .interval = 1024 * 1024,
e8b0e958
JA
2017 .category = FIO_OPT_C_FILE,
2018 .group = FIO_OPT_G_INVALID,
214e1eca 2019 },
bedc9dc2
JA
2020 {
2021 .name = "file_append",
2022 .lname = "File append",
2023 .type = FIO_OPT_BOOL,
a609f12a 2024 .off1 = offsetof(struct thread_options, file_append),
bedc9dc2
JA
2025 .help = "IO will start at the end of the file(s)",
2026 .def = "0",
2027 .category = FIO_OPT_C_FILE,
2028 .group = FIO_OPT_G_INVALID,
2029 },
67a1000f
JA
2030 {
2031 .name = "offset",
e8b0e958 2032 .lname = "IO offset",
67a1000f
JA
2033 .alias = "fileoffset",
2034 .type = FIO_OPT_STR_VAL,
89978a6b 2035 .cb = str_offset_cb,
a609f12a 2036 .off1 = offsetof(struct thread_options, start_offset),
67a1000f
JA
2037 .help = "Start IO from this offset",
2038 .def = "0",
20eb06bd 2039 .interval = 1024 * 1024,
e8b0e958
JA
2040 .category = FIO_OPT_C_IO,
2041 .group = FIO_OPT_G_INVALID,
67a1000f 2042 },
83c8b093
JF
2043 {
2044 .name = "offset_align",
2045 .lname = "IO offset alignment",
2046 .type = FIO_OPT_INT,
2047 .off1 = offsetof(struct thread_options, start_offset_align),
2048 .help = "Start IO from this offset alignment",
2049 .def = "0",
2050 .interval = 512,
2051 .category = FIO_OPT_C_IO,
2052 .group = FIO_OPT_G_INVALID,
2053 },
2d7cd868
JA
2054 {
2055 .name = "offset_increment",
e8b0e958 2056 .lname = "IO offset increment",
2d7cd868 2057 .type = FIO_OPT_STR_VAL,
a609f12a 2058 .off1 = offsetof(struct thread_options, offset_increment),
2d7cd868
JA
2059 .help = "What is the increment from one offset to the next",
2060 .parent = "offset",
d71c154c 2061 .hide = 1,
2d7cd868 2062 .def = "0",
20eb06bd 2063 .interval = 1024 * 1024,
e8b0e958
JA
2064 .category = FIO_OPT_C_IO,
2065 .group = FIO_OPT_G_INVALID,
2d7cd868 2066 },
ddf24e42
JA
2067 {
2068 .name = "number_ios",
2069 .lname = "Number of IOs to perform",
2070 .type = FIO_OPT_STR_VAL,
a609f12a 2071 .off1 = offsetof(struct thread_options, number_ios),
be3fec7d 2072 .help = "Force job completion after this number of IOs",
ddf24e42
JA
2073 .def = "0",
2074 .category = FIO_OPT_C_IO,
2075 .group = FIO_OPT_G_INVALID,
2076 },
214e1eca
JA
2077 {
2078 .name = "bs",
e8b0e958 2079 .lname = "Block size",
d3aad8f2 2080 .alias = "blocksize",
e01b22b8 2081 .type = FIO_OPT_INT,
a609f12a
JA
2082 .off1 = offsetof(struct thread_options, bs[DDIR_READ]),
2083 .off2 = offsetof(struct thread_options, bs[DDIR_WRITE]),
2084 .off3 = offsetof(struct thread_options, bs[DDIR_TRIM]),
c3edbdba 2085 .minval = 1,
214e1eca 2086 .help = "Block size unit",
2b9136a3 2087 .def = "4096",
67a1000f 2088 .parent = "rw",
d71c154c 2089 .hide = 1,
20eb06bd 2090 .interval = 512,
e8b0e958
JA
2091 .category = FIO_OPT_C_IO,
2092 .group = FIO_OPT_G_INVALID,
214e1eca 2093 },
2b7a01d0
JA
2094 {
2095 .name = "ba",
e8b0e958 2096 .lname = "Block size align",
2b7a01d0 2097 .alias = "blockalign",
e01b22b8 2098 .type = FIO_OPT_INT,
a609f12a
JA
2099 .off1 = offsetof(struct thread_options, ba[DDIR_READ]),
2100 .off2 = offsetof(struct thread_options, ba[DDIR_WRITE]),
2101 .off3 = offsetof(struct thread_options, ba[DDIR_TRIM]),
2b7a01d0
JA
2102 .minval = 1,
2103 .help = "IO block offset alignment",
2104 .parent = "rw",
d71c154c 2105 .hide = 1,
20eb06bd 2106 .interval = 512,
e8b0e958
JA
2107 .category = FIO_OPT_C_IO,
2108 .group = FIO_OPT_G_INVALID,
2b7a01d0 2109 },
214e1eca
JA
2110 {
2111 .name = "bsrange",
e8b0e958 2112 .lname = "Block size range",
d3aad8f2 2113 .alias = "blocksize_range",
214e1eca 2114 .type = FIO_OPT_RANGE,
a609f12a
JA
2115 .off1 = offsetof(struct thread_options, min_bs[DDIR_READ]),
2116 .off2 = offsetof(struct thread_options, max_bs[DDIR_READ]),
2117 .off3 = offsetof(struct thread_options, min_bs[DDIR_WRITE]),
2118 .off4 = offsetof(struct thread_options, max_bs[DDIR_WRITE]),
2119 .off5 = offsetof(struct thread_options, min_bs[DDIR_TRIM]),
2120 .off6 = offsetof(struct thread_options, max_bs[DDIR_TRIM]),
c3edbdba 2121 .minval = 1,
214e1eca 2122 .help = "Set block size range (in more detail than bs)",
67a1000f 2123 .parent = "rw",
d71c154c 2124 .hide = 1,
20eb06bd 2125 .interval = 4096,
e8b0e958
JA
2126 .category = FIO_OPT_C_IO,
2127 .group = FIO_OPT_G_INVALID,
214e1eca 2128 },
564ca972
JA
2129 {
2130 .name = "bssplit",
e8b0e958 2131 .lname = "Block size split",
564ca972
JA
2132 .type = FIO_OPT_STR,
2133 .cb = str_bssplit_cb,
a609f12a 2134 .off1 = offsetof(struct thread_options, bssplit),
564ca972
JA
2135 .help = "Set a specific mix of block sizes",
2136 .parent = "rw",
d71c154c 2137 .hide = 1,
e8b0e958
JA
2138 .category = FIO_OPT_C_IO,
2139 .group = FIO_OPT_G_INVALID,
564ca972 2140 },
214e1eca
JA
2141 {
2142 .name = "bs_unaligned",
e8b0e958 2143 .lname = "Block size unaligned",
d3aad8f2 2144 .alias = "blocksize_unaligned",
214e1eca 2145 .type = FIO_OPT_STR_SET,
a609f12a 2146 .off1 = offsetof(struct thread_options, bs_unaligned),
214e1eca 2147 .help = "Don't sector align IO buffer sizes",
67a1000f 2148 .parent = "rw",
d71c154c 2149 .hide = 1,
e8b0e958
JA
2150 .category = FIO_OPT_C_IO,
2151 .group = FIO_OPT_G_INVALID,
214e1eca 2152 },
6aca9b3d
JA
2153 {
2154 .name = "bs_is_seq_rand",
2155 .lname = "Block size division is seq/random (not read/write)",
2156 .type = FIO_OPT_BOOL,
a609f12a 2157 .off1 = offsetof(struct thread_options, bs_is_seq_rand),
86d59660 2158 .help = "Consider any blocksize setting to be sequential,random",
6aca9b3d
JA
2159 .def = "0",
2160 .parent = "blocksize",
2161 .category = FIO_OPT_C_IO,
2162 .group = FIO_OPT_G_INVALID,
2163 },
214e1eca
JA
2164 {
2165 .name = "randrepeat",
e8b0e958 2166 .lname = "Random repeatable",
214e1eca 2167 .type = FIO_OPT_BOOL,
a609f12a 2168 .off1 = offsetof(struct thread_options, rand_repeatable),
214e1eca
JA
2169 .help = "Use repeatable random IO pattern",
2170 .def = "1",
67a1000f 2171 .parent = "rw",
d71c154c 2172 .hide = 1,
e8b0e958 2173 .category = FIO_OPT_C_IO,
3ceb458f 2174 .group = FIO_OPT_G_RANDOM,
214e1eca 2175 },
04778baf
JA
2176 {
2177 .name = "randseed",
2178 .lname = "The random generator seed",
363cffa7 2179 .type = FIO_OPT_STR_VAL,
a609f12a 2180 .off1 = offsetof(struct thread_options, rand_seed),
04778baf 2181 .help = "Set the random generator seed value",
40fe5e7b 2182 .def = "0x89",
04778baf
JA
2183 .parent = "rw",
2184 .category = FIO_OPT_C_IO,
2185 .group = FIO_OPT_G_RANDOM,
2186 },
2615cc4b
JA
2187 {
2188 .name = "use_os_rand",
e8b0e958 2189 .lname = "Use OS random",
54a21917 2190 .type = FIO_OPT_DEPRECATED,
a609f12a 2191 .off1 = offsetof(struct thread_options, dep_use_os_rand),
e8b0e958 2192 .category = FIO_OPT_C_IO,
3ceb458f 2193 .group = FIO_OPT_G_RANDOM,
2615cc4b 2194 },
214e1eca
JA
2195 {
2196 .name = "norandommap",
e8b0e958 2197 .lname = "No randommap",
214e1eca 2198 .type = FIO_OPT_STR_SET,
a609f12a 2199 .off1 = offsetof(struct thread_options, norandommap),
214e1eca 2200 .help = "Accept potential duplicate random blocks",
67a1000f 2201 .parent = "rw",
d71c154c 2202 .hide = 1,
b2452a43 2203 .hide_on_set = 1,
e8b0e958 2204 .category = FIO_OPT_C_IO,
3ceb458f 2205 .group = FIO_OPT_G_RANDOM,
214e1eca 2206 },
2b386d25
JA
2207 {
2208 .name = "softrandommap",
e8b0e958 2209 .lname = "Soft randommap",
2b386d25 2210 .type = FIO_OPT_BOOL,
a609f12a 2211 .off1 = offsetof(struct thread_options, softrandommap),
f66ab3c8 2212 .help = "Set norandommap if randommap allocation fails",
2b386d25 2213 .parent = "norandommap",
d71c154c 2214 .hide = 1,
2b386d25 2215 .def = "0",
e8b0e958 2216 .category = FIO_OPT_C_IO,
3ceb458f 2217 .group = FIO_OPT_G_RANDOM,
2b386d25 2218 },
8055e41d
JA
2219 {
2220 .name = "random_generator",
cce2fdfe 2221 .lname = "Random Generator",
8055e41d 2222 .type = FIO_OPT_STR,
a609f12a 2223 .off1 = offsetof(struct thread_options, random_generator),
8055e41d
JA
2224 .help = "Type of random number generator to use",
2225 .def = "tausworthe",
2226 .posval = {
2227 { .ival = "tausworthe",
2228 .oval = FIO_RAND_GEN_TAUSWORTHE,
2229 .help = "Strong Tausworthe generator",
2230 },
2231 { .ival = "lfsr",
2232 .oval = FIO_RAND_GEN_LFSR,
2233 .help = "Variable length LFSR",
2234 },
c3546b53
JA
2235 {
2236 .ival = "tausworthe64",
2237 .oval = FIO_RAND_GEN_TAUSWORTHE64,
2238 .help = "64-bit Tausworthe variant",
2239 },
8055e41d 2240 },
48107598
JA
2241 .category = FIO_OPT_C_IO,
2242 .group = FIO_OPT_G_RANDOM,
8055e41d 2243 },
e25839d4
JA
2244 {
2245 .name = "random_distribution",
cce2fdfe 2246 .lname = "Random Distribution",
e25839d4 2247 .type = FIO_OPT_STR,
a609f12a 2248 .off1 = offsetof(struct thread_options, random_distribution),
e25839d4
JA
2249 .cb = str_random_distribution_cb,
2250 .help = "Random offset distribution generator",
2251 .def = "random",
2252 .posval = {
2253 { .ival = "random",
2254 .oval = FIO_RAND_DIST_RANDOM,
2255 .help = "Completely random",
2256 },
2257 { .ival = "zipf",
2258 .oval = FIO_RAND_DIST_ZIPF,
2259 .help = "Zipf distribution",
2260 },
925fee33
JA
2261 { .ival = "pareto",
2262 .oval = FIO_RAND_DIST_PARETO,
2263 .help = "Pareto distribution",
2264 },
56d9fa4b
JA
2265 { .ival = "normal",
2266 .oval = FIO_RAND_DIST_GAUSS,
ba2b3b07 2267 .help = "Normal (Gaussian) distribution",
56d9fa4b 2268 },
e0a04ac1
JA
2269 { .ival = "zoned",
2270 .oval = FIO_RAND_DIST_ZONED,
2271 .help = "Zoned random distribution",
2272 },
59466396
JA
2273 { .ival = "zoned_abs",
2274 .oval = FIO_RAND_DIST_ZONED_ABS,
2275 .help = "Zoned absolute random distribution",
2276 },
e25839d4 2277 },
48107598
JA
2278 .category = FIO_OPT_C_IO,
2279 .group = FIO_OPT_G_RANDOM,
e25839d4 2280 },
211c9b89
JA
2281 {
2282 .name = "percentage_random",
2283 .lname = "Percentage Random",
2284 .type = FIO_OPT_INT,
a609f12a
JA
2285 .off1 = offsetof(struct thread_options, perc_rand[DDIR_READ]),
2286 .off2 = offsetof(struct thread_options, perc_rand[DDIR_WRITE]),
2287 .off3 = offsetof(struct thread_options, perc_rand[DDIR_TRIM]),
211c9b89
JA
2288 .maxval = 100,
2289 .help = "Percentage of seq/random mix that should be random",
d9472271 2290 .def = "100,100,100",
211c9b89
JA
2291 .interval = 5,
2292 .inverse = "percentage_sequential",
2293 .category = FIO_OPT_C_IO,
2294 .group = FIO_OPT_G_RANDOM,
2295 },
2296 {
2297 .name = "percentage_sequential",
2298 .lname = "Percentage Sequential",
d9472271 2299 .type = FIO_OPT_DEPRECATED,
211c9b89
JA
2300 .category = FIO_OPT_C_IO,
2301 .group = FIO_OPT_G_RANDOM,
2302 },
56e2a5fc
CE
2303 {
2304 .name = "allrandrepeat",
cce2fdfe 2305 .lname = "All Random Repeat",
56e2a5fc 2306 .type = FIO_OPT_BOOL,
a609f12a 2307 .off1 = offsetof(struct thread_options, allrand_repeatable),
56e2a5fc
CE
2308 .help = "Use repeatable random numbers for everything",
2309 .def = "0",
a869d9c6
JA
2310 .category = FIO_OPT_C_IO,
2311 .group = FIO_OPT_G_RANDOM,
56e2a5fc 2312 },
214e1eca
JA
2313 {
2314 .name = "nrfiles",
e8b0e958 2315 .lname = "Number of files",
d7c8be03 2316 .alias = "nr_files",
214e1eca 2317 .type = FIO_OPT_INT,
a609f12a 2318 .off1 = offsetof(struct thread_options, nr_files),
214e1eca
JA
2319 .help = "Split job workload between this number of files",
2320 .def = "1",
20eb06bd 2321 .interval = 1,
e8b0e958
JA
2322 .category = FIO_OPT_C_FILE,
2323 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2324 },
2325 {
2326 .name = "openfiles",
e8b0e958 2327 .lname = "Number of open files",
214e1eca 2328 .type = FIO_OPT_INT,
a609f12a 2329 .off1 = offsetof(struct thread_options, open_files),
214e1eca 2330 .help = "Number of files to keep open at the same time",
e8b0e958
JA
2331 .category = FIO_OPT_C_FILE,
2332 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2333 },
2334 {
2335 .name = "file_service_type",
e8b0e958 2336 .lname = "File service type",
214e1eca
JA
2337 .type = FIO_OPT_STR,
2338 .cb = str_fst_cb,
a609f12a 2339 .off1 = offsetof(struct thread_options, file_service_type),
214e1eca
JA
2340 .help = "How to select which file to service next",
2341 .def = "roundrobin",
e8b0e958
JA
2342 .category = FIO_OPT_C_FILE,
2343 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2344 .posval = {
2345 { .ival = "random",
2346 .oval = FIO_FSERVICE_RANDOM,
8c07860d
JA
2347 .help = "Choose a file at random (uniform)",
2348 },
2349 { .ival = "zipf",
2350 .oval = FIO_FSERVICE_ZIPF,
2351 .help = "Zipf randomized",
2352 },
2353 { .ival = "pareto",
2354 .oval = FIO_FSERVICE_PARETO,
2355 .help = "Pareto randomized",
2356 },
dd3503d3
SW
2357 { .ival = "normal",
2358 .oval = FIO_FSERVICE_GAUSS,
2359 .help = "Normal (Gaussian) randomized",
2360 },
8c07860d
JA
2361 { .ival = "gauss",
2362 .oval = FIO_FSERVICE_GAUSS,
dd3503d3 2363 .help = "Alias for normal",
214e1eca
JA
2364 },
2365 { .ival = "roundrobin",
2366 .oval = FIO_FSERVICE_RR,
2367 .help = "Round robin select files",
2368 },
a086c257
JA
2369 { .ival = "sequential",
2370 .oval = FIO_FSERVICE_SEQ,
2371 .help = "Finish one file before moving to the next",
2372 },
214e1eca 2373 },
67a1000f 2374 .parent = "nrfiles",
d71c154c 2375 .hide = 1,
67a1000f 2376 },
cbbdf1c8 2377#ifdef FIO_HAVE_ANY_FALLOCATE
7bc8c2cf
JA
2378 {
2379 .name = "fallocate",
e8b0e958 2380 .lname = "Fallocate",
a596f047 2381 .type = FIO_OPT_STR,
a609f12a 2382 .off1 = offsetof(struct thread_options, fallocate_mode),
a596f047 2383 .help = "Whether pre-allocation is performed when laying out files",
2c3e17be 2384 .def = "native",
e8b0e958
JA
2385 .category = FIO_OPT_C_FILE,
2386 .group = FIO_OPT_G_INVALID,
a596f047
EG
2387 .posval = {
2388 { .ival = "none",
2389 .oval = FIO_FALLOCATE_NONE,
2390 .help = "Do not pre-allocate space",
2391 },
2c3e17be
SW
2392 { .ival = "native",
2393 .oval = FIO_FALLOCATE_NATIVE,
2394 .help = "Use native pre-allocation if possible",
2395 },
2396#ifdef CONFIG_POSIX_FALLOCATE
a596f047
EG
2397 { .ival = "posix",
2398 .oval = FIO_FALLOCATE_POSIX,
2399 .help = "Use posix_fallocate()",
2400 },
2c3e17be 2401#endif
97ac992c 2402#ifdef CONFIG_LINUX_FALLOCATE
a596f047
EG
2403 { .ival = "keep",
2404 .oval = FIO_FALLOCATE_KEEP_SIZE,
2405 .help = "Use fallocate(..., FALLOC_FL_KEEP_SIZE, ...)",
2406 },
7bc8c2cf 2407#endif
a596f047
EG
2408 /* Compatibility with former boolean values */
2409 { .ival = "0",
2410 .oval = FIO_FALLOCATE_NONE,
2411 .help = "Alias for 'none'",
2412 },
2c3e17be 2413#ifdef CONFIG_POSIX_FALLOCATE
a596f047
EG
2414 { .ival = "1",
2415 .oval = FIO_FALLOCATE_POSIX,
2416 .help = "Alias for 'posix'",
2417 },
2c3e17be 2418#endif
a596f047
EG
2419 },
2420 },
cbbdf1c8 2421#else /* FIO_HAVE_ANY_FALLOCATE */
a275c37a
JA
2422 {
2423 .name = "fallocate",
2424 .lname = "Fallocate",
2425 .type = FIO_OPT_UNSUPPORTED,
2426 .help = "Your platform does not support fallocate",
2427 },
cbbdf1c8 2428#endif /* FIO_HAVE_ANY_FALLOCATE */
67a1000f
JA
2429 {
2430 .name = "fadvise_hint",
e8b0e958 2431 .lname = "Fadvise hint",
ecb2083d 2432 .type = FIO_OPT_STR,
a609f12a 2433 .off1 = offsetof(struct thread_options, fadvise_hint),
ecb2083d
JA
2434 .posval = {
2435 { .ival = "0",
2436 .oval = F_ADV_NONE,
c712c97a 2437 .help = "Don't issue fadvise/madvise",
ecb2083d
JA
2438 },
2439 { .ival = "1",
2440 .oval = F_ADV_TYPE,
2441 .help = "Advise using fio IO pattern",
2442 },
2443 { .ival = "random",
2444 .oval = F_ADV_RANDOM,
2445 .help = "Advise using FADV_RANDOM",
2446 },
2447 { .ival = "sequential",
2448 .oval = F_ADV_SEQUENTIAL,
2449 .help = "Advise using FADV_SEQUENTIAL",
2450 },
2451 },
67a1000f
JA
2452 .help = "Use fadvise() to advise the kernel on IO pattern",
2453 .def = "1",
e8b0e958
JA
2454 .category = FIO_OPT_C_FILE,
2455 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2456 },
2457 {
2458 .name = "fsync",
e8b0e958 2459 .lname = "Fsync",
214e1eca 2460 .type = FIO_OPT_INT,
a609f12a 2461 .off1 = offsetof(struct thread_options, fsync_blocks),
214e1eca
JA
2462 .help = "Issue fsync for writes every given number of blocks",
2463 .def = "0",
20eb06bd 2464 .interval = 1,
e8b0e958
JA
2465 .category = FIO_OPT_C_FILE,
2466 .group = FIO_OPT_G_INVALID,
214e1eca 2467 },
5f9099ea
JA
2468 {
2469 .name = "fdatasync",
e8b0e958 2470 .lname = "Fdatasync",
5f9099ea 2471 .type = FIO_OPT_INT,
a609f12a 2472 .off1 = offsetof(struct thread_options, fdatasync_blocks),
5f9099ea
JA
2473 .help = "Issue fdatasync for writes every given number of blocks",
2474 .def = "0",
20eb06bd 2475 .interval = 1,
e8b0e958
JA
2476 .category = FIO_OPT_C_FILE,
2477 .group = FIO_OPT_G_INVALID,
5f9099ea 2478 },
1ef2b6be
JA
2479 {
2480 .name = "write_barrier",
e8b0e958 2481 .lname = "Write barrier",
1ef2b6be 2482 .type = FIO_OPT_INT,
a609f12a 2483 .off1 = offsetof(struct thread_options, barrier_blocks),
1ef2b6be
JA
2484 .help = "Make every Nth write a barrier write",
2485 .def = "0",
20eb06bd 2486 .interval = 1,
e8b0e958
JA
2487 .category = FIO_OPT_C_IO,
2488 .group = FIO_OPT_G_INVALID,
1ef2b6be 2489 },
67bf9823 2490#ifdef CONFIG_SYNC_FILE_RANGE
44f29692
JA
2491 {
2492 .name = "sync_file_range",
e8b0e958 2493 .lname = "Sync file range",
44f29692
JA
2494 .posval = {
2495 { .ival = "wait_before",
2496 .oval = SYNC_FILE_RANGE_WAIT_BEFORE,
2497 .help = "SYNC_FILE_RANGE_WAIT_BEFORE",
ebadc0ce 2498 .orval = 1,
44f29692
JA
2499 },
2500 { .ival = "write",
2501 .oval = SYNC_FILE_RANGE_WRITE,
2502 .help = "SYNC_FILE_RANGE_WRITE",
ebadc0ce 2503 .orval = 1,
44f29692
JA
2504 },
2505 {
2506 .ival = "wait_after",
2507 .oval = SYNC_FILE_RANGE_WAIT_AFTER,
2508 .help = "SYNC_FILE_RANGE_WAIT_AFTER",
ebadc0ce 2509 .orval = 1,
44f29692
JA
2510 },
2511 },
3843deb3 2512 .type = FIO_OPT_STR_MULTI,
44f29692 2513 .cb = str_sfr_cb,
a609f12a 2514 .off1 = offsetof(struct thread_options, sync_file_range),
44f29692 2515 .help = "Use sync_file_range()",
e8b0e958
JA
2516 .category = FIO_OPT_C_FILE,
2517 .group = FIO_OPT_G_INVALID,
44f29692 2518 },
a275c37a 2519#else
54d0a315 2520 {
a275c37a
JA
2521 .name = "sync_file_range",
2522 .lname = "Sync file range",
2523 .type = FIO_OPT_UNSUPPORTED,
2524 .help = "Your platform does not support sync_file_range",
2525 },
44f29692 2526#endif
214e1eca
JA
2527 {
2528 .name = "direct",
e8b0e958 2529 .lname = "Direct I/O",
214e1eca 2530 .type = FIO_OPT_BOOL,
a609f12a 2531 .off1 = offsetof(struct thread_options, odirect),
214e1eca
JA
2532 .help = "Use O_DIRECT IO (negates buffered)",
2533 .def = "0",
a01a1bc5 2534 .inverse = "buffered",
e8b0e958 2535 .category = FIO_OPT_C_IO,
3ceb458f 2536 .group = FIO_OPT_G_IO_TYPE,
214e1eca 2537 },
d01612f3
CM
2538 {
2539 .name = "atomic",
2540 .lname = "Atomic I/O",
2541 .type = FIO_OPT_BOOL,
a609f12a 2542 .off1 = offsetof(struct thread_options, oatomic),
d01612f3
CM
2543 .help = "Use Atomic IO with O_DIRECT (implies O_DIRECT)",
2544 .def = "0",
2545 .category = FIO_OPT_C_IO,
2546 .group = FIO_OPT_G_IO_TYPE,
2547 },
214e1eca
JA
2548 {
2549 .name = "buffered",
e8b0e958 2550 .lname = "Buffered I/O",
214e1eca 2551 .type = FIO_OPT_BOOL,
a609f12a 2552 .off1 = offsetof(struct thread_options, odirect),
214e1eca
JA
2553 .neg = 1,
2554 .help = "Use buffered IO (negates direct)",
2555 .def = "1",
a01a1bc5 2556 .inverse = "direct",
e8b0e958 2557 .category = FIO_OPT_C_IO,
3ceb458f 2558 .group = FIO_OPT_G_IO_TYPE,
214e1eca
JA
2559 },
2560 {
2561 .name = "overwrite",
e8b0e958 2562 .lname = "Overwrite",
214e1eca 2563 .type = FIO_OPT_BOOL,
a609f12a 2564 .off1 = offsetof(struct thread_options, overwrite),
214e1eca
JA
2565 .help = "When writing, set whether to overwrite current data",
2566 .def = "0",
e8b0e958
JA
2567 .category = FIO_OPT_C_FILE,
2568 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2569 },
2570 {
2571 .name = "loops",
e8b0e958 2572 .lname = "Loops",
214e1eca 2573 .type = FIO_OPT_INT,
a609f12a 2574 .off1 = offsetof(struct thread_options, loops),
214e1eca
JA
2575 .help = "Number of times to run the job",
2576 .def = "1",
20eb06bd 2577 .interval = 1,
e8b0e958 2578 .category = FIO_OPT_C_GENERAL,
a1f6afec 2579 .group = FIO_OPT_G_RUNTIME,
214e1eca
JA
2580 },
2581 {
2582 .name = "numjobs",
e8b0e958 2583 .lname = "Number of jobs",
214e1eca 2584 .type = FIO_OPT_INT,
a609f12a 2585 .off1 = offsetof(struct thread_options, numjobs),
214e1eca
JA
2586 .help = "Duplicate this job this many times",
2587 .def = "1",
20eb06bd 2588 .interval = 1,
e8b0e958 2589 .category = FIO_OPT_C_GENERAL,
a1f6afec 2590 .group = FIO_OPT_G_RUNTIME,
214e1eca
JA
2591 },
2592 {
2593 .name = "startdelay",
e8b0e958 2594 .lname = "Start delay",
a5737c93 2595 .type = FIO_OPT_STR_VAL_TIME,
a609f12a
JA
2596 .off1 = offsetof(struct thread_options, start_delay),
2597 .off2 = offsetof(struct thread_options, start_delay_high),
214e1eca
JA
2598 .help = "Only start job when this period has passed",
2599 .def = "0",
0de5b26f 2600 .is_seconds = 1,
88038bc7 2601 .is_time = 1,
e8b0e958 2602 .category = FIO_OPT_C_GENERAL,
a1f6afec 2603 .group = FIO_OPT_G_RUNTIME,
214e1eca
JA
2604 },
2605 {
2606 .name = "runtime",
e8b0e958 2607 .lname = "Runtime",
214e1eca
JA
2608 .alias = "timeout",
2609 .type = FIO_OPT_STR_VAL_TIME,
a609f12a 2610 .off1 = offsetof(struct thread_options, timeout),
214e1eca
JA
2611 .help = "Stop workload when this amount of time has passed",
2612 .def = "0",
0de5b26f 2613 .is_seconds = 1,
88038bc7 2614 .is_time = 1,
e8b0e958 2615 .category = FIO_OPT_C_GENERAL,
a1f6afec 2616 .group = FIO_OPT_G_RUNTIME,
214e1eca 2617 },
cf4464ca
JA
2618 {
2619 .name = "time_based",
e8b0e958 2620 .lname = "Time based",
cf4464ca 2621 .type = FIO_OPT_STR_SET,
a609f12a 2622 .off1 = offsetof(struct thread_options, time_based),
cf4464ca 2623 .help = "Keep running until runtime/timeout is met",
e8b0e958 2624 .category = FIO_OPT_C_GENERAL,
a1f6afec 2625 .group = FIO_OPT_G_RUNTIME,
cf4464ca 2626 },
62167762
JC
2627 {
2628 .name = "verify_only",
2629 .lname = "Verify only",
2630 .type = FIO_OPT_STR_SET,
a609f12a 2631 .off1 = offsetof(struct thread_options, verify_only),
62167762
JC
2632 .help = "Verifies previously written data is still valid",
2633 .category = FIO_OPT_C_GENERAL,
2634 .group = FIO_OPT_G_RUNTIME,
2635 },
721938ae
JA
2636 {
2637 .name = "ramp_time",
e8b0e958 2638 .lname = "Ramp time",
721938ae 2639 .type = FIO_OPT_STR_VAL_TIME,
a609f12a 2640 .off1 = offsetof(struct thread_options, ramp_time),
721938ae 2641 .help = "Ramp up time before measuring performance",
0de5b26f 2642 .is_seconds = 1,
88038bc7 2643 .is_time = 1,
e8b0e958 2644 .category = FIO_OPT_C_GENERAL,
a1f6afec 2645 .group = FIO_OPT_G_RUNTIME,
721938ae 2646 },
c223da83
JA
2647 {
2648 .name = "clocksource",
e8b0e958 2649 .lname = "Clock source",
c223da83
JA
2650 .type = FIO_OPT_STR,
2651 .cb = fio_clock_source_cb,
a609f12a 2652 .off1 = offsetof(struct thread_options, clocksource),
c223da83 2653 .help = "What type of timing source to use",
e8b0e958 2654 .category = FIO_OPT_C_GENERAL,
10860056 2655 .group = FIO_OPT_G_CLOCK,
c223da83 2656 .posval = {
67bf9823 2657#ifdef CONFIG_GETTIMEOFDAY
c223da83
JA
2658 { .ival = "gettimeofday",
2659 .oval = CS_GTOD,
2660 .help = "Use gettimeofday(2) for timing",
2661 },
67bf9823
JA
2662#endif
2663#ifdef CONFIG_CLOCK_GETTIME
c223da83
JA
2664 { .ival = "clock_gettime",
2665 .oval = CS_CGETTIME,
2666 .help = "Use clock_gettime(2) for timing",
2667 },
67bf9823 2668#endif
c223da83
JA
2669#ifdef ARCH_HAVE_CPU_CLOCK
2670 { .ival = "cpu",
2671 .oval = CS_CPUCLOCK,
2672 .help = "Use CPU private clock",
2673 },
2674#endif
2675 },
2676 },
214e1eca
JA
2677 {
2678 .name = "mem",
d3aad8f2 2679 .alias = "iomem",
e8b0e958 2680 .lname = "I/O Memory",
214e1eca
JA
2681 .type = FIO_OPT_STR,
2682 .cb = str_mem_cb,
a609f12a 2683 .off1 = offsetof(struct thread_options, mem_type),
214e1eca
JA
2684 .help = "Backing type for IO buffers",
2685 .def = "malloc",
e8b0e958
JA
2686 .category = FIO_OPT_C_IO,
2687 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2688 .posval = {
2689 { .ival = "malloc",
2690 .oval = MEM_MALLOC,
2691 .help = "Use malloc(3) for IO buffers",
2692 },
c8931876 2693#ifndef CONFIG_NO_SHM
37c8cdfe
JA
2694 { .ival = "shm",
2695 .oval = MEM_SHM,
2696 .help = "Use shared memory segments for IO buffers",
2697 },
214e1eca
JA
2698#ifdef FIO_HAVE_HUGETLB
2699 { .ival = "shmhuge",
2700 .oval = MEM_SHMHUGE,
2701 .help = "Like shm, but use huge pages",
2702 },
c8931876 2703#endif
b370e46a 2704#endif
37c8cdfe
JA
2705 { .ival = "mmap",
2706 .oval = MEM_MMAP,
2707 .help = "Use mmap(2) (file or anon) for IO buffers",
2708 },
217b0f1d
LG
2709 { .ival = "mmapshared",
2710 .oval = MEM_MMAPSHARED,
2711 .help = "Like mmap, but use the shared flag",
2712 },
214e1eca
JA
2713#ifdef FIO_HAVE_HUGETLB
2714 { .ival = "mmaphuge",
2715 .oval = MEM_MMAPHUGE,
2716 .help = "Like mmap, but use huge pages",
2717 },
03553853
YR
2718#endif
2719#ifdef CONFIG_CUDA
2720 { .ival = "cudamalloc",
2721 .oval = MEM_CUDA_MALLOC,
2722 .help = "Allocate GPU device memory for GPUDirect RDMA",
2723 },
214e1eca
JA
2724#endif
2725 },
2726 },
d529ee19
JA
2727 {
2728 .name = "iomem_align",
2729 .alias = "mem_align",
e8b0e958 2730 .lname = "I/O memory alignment",
d529ee19 2731 .type = FIO_OPT_INT,
a609f12a 2732 .off1 = offsetof(struct thread_options, mem_align),
d529ee19
JA
2733 .minval = 0,
2734 .help = "IO memory buffer offset alignment",
2735 .def = "0",
2736 .parent = "iomem",
d71c154c 2737 .hide = 1,
e8b0e958
JA
2738 .category = FIO_OPT_C_IO,
2739 .group = FIO_OPT_G_INVALID,
d529ee19 2740 },
214e1eca
JA
2741 {
2742 .name = "verify",
e8b0e958 2743 .lname = "Verify",
214e1eca 2744 .type = FIO_OPT_STR,
a609f12a 2745 .off1 = offsetof(struct thread_options, verify),
214e1eca
JA
2746 .help = "Verify data written",
2747 .def = "0",
e8b0e958 2748 .category = FIO_OPT_C_IO,
3ceb458f 2749 .group = FIO_OPT_G_VERIFY,
214e1eca
JA
2750 .posval = {
2751 { .ival = "0",
2752 .oval = VERIFY_NONE,
2753 .help = "Don't do IO verification",
2754 },
fcca4b58
JA
2755 { .ival = "md5",
2756 .oval = VERIFY_MD5,
2757 .help = "Use md5 checksums for verification",
2758 },
d77a7af3
JA
2759 { .ival = "crc64",
2760 .oval = VERIFY_CRC64,
2761 .help = "Use crc64 checksums for verification",
2762 },
214e1eca
JA
2763 { .ival = "crc32",
2764 .oval = VERIFY_CRC32,
2765 .help = "Use crc32 checksums for verification",
2766 },
af497e6a 2767 { .ival = "crc32c-intel",
e3aaafc4
JA
2768 .oval = VERIFY_CRC32C,
2769 .help = "Use crc32c checksums for verification (hw assisted, if available)",
af497e6a 2770 },
bac39e0e
JA
2771 { .ival = "crc32c",
2772 .oval = VERIFY_CRC32C,
e3aaafc4 2773 .help = "Use crc32c checksums for verification (hw assisted, if available)",
bac39e0e 2774 },
969f7ed3
JA
2775 { .ival = "crc16",
2776 .oval = VERIFY_CRC16,
2777 .help = "Use crc16 checksums for verification",
2778 },
1e154bdb
JA
2779 { .ival = "crc7",
2780 .oval = VERIFY_CRC7,
2781 .help = "Use crc7 checksums for verification",
2782 },
7c353ceb
JA
2783 { .ival = "sha1",
2784 .oval = VERIFY_SHA1,
2785 .help = "Use sha1 checksums for verification",
2786 },
cd14cc10
JA
2787 { .ival = "sha256",
2788 .oval = VERIFY_SHA256,
2789 .help = "Use sha256 checksums for verification",
2790 },
2791 { .ival = "sha512",
2792 .oval = VERIFY_SHA512,
2793 .help = "Use sha512 checksums for verification",
ae3a5acc
JA
2794 },
2795 { .ival = "sha3-224",
2796 .oval = VERIFY_SHA3_224,
2797 .help = "Use sha3-224 checksums for verification",
2798 },
2799 { .ival = "sha3-256",
2800 .oval = VERIFY_SHA3_256,
2801 .help = "Use sha3-256 checksums for verification",
2802 },
2803 { .ival = "sha3-384",
2804 .oval = VERIFY_SHA3_384,
2805 .help = "Use sha3-384 checksums for verification",
2806 },
2807 { .ival = "sha3-512",
2808 .oval = VERIFY_SHA3_512,
2809 .help = "Use sha3-512 checksums for verification",
cd14cc10 2810 },
844ea602
JA
2811 { .ival = "xxhash",
2812 .oval = VERIFY_XXHASH,
2813 .help = "Use xxhash checksums for verification",
2814 },
b638d82f
RP
2815 /* Meta information was included into verify_header,
2816 * 'meta' verification is implied by default. */
7437ee87 2817 { .ival = "meta",
b638d82f
RP
2818 .oval = VERIFY_HDR_ONLY,
2819 .help = "Use io information for verification. "
2820 "Now is implied by default, thus option is obsolete, "
2821 "don't use it",
7437ee87 2822 },
59245381
JA
2823 { .ival = "pattern",
2824 .oval = VERIFY_PATTERN_NO_HDR,
2825 .help = "Verify strict pattern",
2826 },
36690c9b
JA
2827 {
2828 .ival = "null",
2829 .oval = VERIFY_NULL,
2830 .help = "Pretend to verify",
2831 },
214e1eca
JA
2832 },
2833 },
005c565a
JA
2834 {
2835 .name = "do_verify",
e8b0e958 2836 .lname = "Perform verify step",
68e1f29a 2837 .type = FIO_OPT_BOOL,
a609f12a 2838 .off1 = offsetof(struct thread_options, do_verify),
005c565a
JA
2839 .help = "Run verification stage after write",
2840 .def = "1",
2841 .parent = "verify",
d71c154c 2842 .hide = 1,
e8b0e958
JA
2843 .category = FIO_OPT_C_IO,
2844 .group = FIO_OPT_G_VERIFY,
005c565a 2845 },
160b966d
JA
2846 {
2847 .name = "verifysort",
e8b0e958 2848 .lname = "Verify sort",
f31feaa2 2849 .type = FIO_OPT_SOFT_DEPRECATED,
e8b0e958
JA
2850 .category = FIO_OPT_C_IO,
2851 .group = FIO_OPT_G_VERIFY,
160b966d 2852 },
1ae83d45
JA
2853 {
2854 .name = "verifysort_nr",
cce2fdfe 2855 .lname = "Verify Sort Nr",
f31feaa2 2856 .type = FIO_OPT_SOFT_DEPRECATED,
836fcc0f
JA
2857 .category = FIO_OPT_C_IO,
2858 .group = FIO_OPT_G_VERIFY,
1ae83d45 2859 },
3f9f4e26 2860 {
a59e170d 2861 .name = "verify_interval",
e8b0e958 2862 .lname = "Verify interval",
e01b22b8 2863 .type = FIO_OPT_INT,
a609f12a 2864 .off1 = offsetof(struct thread_options, verify_interval),
819a9680 2865 .minval = 2 * sizeof(struct verify_header),
a59e170d 2866 .help = "Store verify buffer header every N bytes",
afdf9352 2867 .parent = "verify",
d71c154c 2868 .hide = 1,
20eb06bd 2869 .interval = 2 * sizeof(struct verify_header),
e8b0e958
JA
2870 .category = FIO_OPT_C_IO,
2871 .group = FIO_OPT_G_VERIFY,
3f9f4e26 2872 },
546a9142 2873 {
a59e170d 2874 .name = "verify_offset",
e8b0e958 2875 .lname = "Verify offset",
e01b22b8 2876 .type = FIO_OPT_INT,
a59e170d 2877 .help = "Offset verify header location by N bytes",
a609f12a 2878 .off1 = offsetof(struct thread_options, verify_offset),
203160d5 2879 .minval = sizeof(struct verify_header),
afdf9352 2880 .parent = "verify",
d71c154c 2881 .hide = 1,
e8b0e958
JA
2882 .category = FIO_OPT_C_IO,
2883 .group = FIO_OPT_G_VERIFY,
546a9142 2884 },
e28218f3
SL
2885 {
2886 .name = "verify_pattern",
e8b0e958 2887 .lname = "Verify pattern",
0e92f873 2888 .type = FIO_OPT_STR,
e28218f3 2889 .cb = str_verify_pattern_cb,
a609f12a 2890 .off1 = offsetof(struct thread_options, verify_pattern),
e28218f3
SL
2891 .help = "Fill pattern for IO buffers",
2892 .parent = "verify",
d71c154c 2893 .hide = 1,
e8b0e958
JA
2894 .category = FIO_OPT_C_IO,
2895 .group = FIO_OPT_G_VERIFY,
e28218f3 2896 },
a12a3b4d
JA
2897 {
2898 .name = "verify_fatal",
e8b0e958 2899 .lname = "Verify fatal",
68e1f29a 2900 .type = FIO_OPT_BOOL,
a609f12a 2901 .off1 = offsetof(struct thread_options, verify_fatal),
a12a3b4d
JA
2902 .def = "0",
2903 .help = "Exit on a single verify failure, don't continue",
2904 .parent = "verify",
d71c154c 2905 .hide = 1,
e8b0e958
JA
2906 .category = FIO_OPT_C_IO,
2907 .group = FIO_OPT_G_VERIFY,
a12a3b4d 2908 },
b463e936
JA
2909 {
2910 .name = "verify_dump",
e8b0e958 2911 .lname = "Verify dump",
b463e936 2912 .type = FIO_OPT_BOOL,
a609f12a 2913 .off1 = offsetof(struct thread_options, verify_dump),
ef71e317 2914 .def = "0",
b463e936
JA
2915 .help = "Dump contents of good and bad blocks on failure",
2916 .parent = "verify",
d71c154c 2917 .hide = 1,
e8b0e958
JA
2918 .category = FIO_OPT_C_IO,
2919 .group = FIO_OPT_G_VERIFY,
b463e936 2920 },
e8462bd8
JA
2921 {
2922 .name = "verify_async",
e8b0e958 2923 .lname = "Verify asynchronously",
e8462bd8 2924 .type = FIO_OPT_INT,
a609f12a 2925 .off1 = offsetof(struct thread_options, verify_async),
e8462bd8
JA
2926 .def = "0",
2927 .help = "Number of async verifier threads to use",
2928 .parent = "verify",
d71c154c 2929 .hide = 1,
e8b0e958
JA
2930 .category = FIO_OPT_C_IO,
2931 .group = FIO_OPT_G_VERIFY,
e8462bd8 2932 },
9e144189
JA
2933 {
2934 .name = "verify_backlog",
e8b0e958 2935 .lname = "Verify backlog",
9e144189 2936 .type = FIO_OPT_STR_VAL,
a609f12a 2937 .off1 = offsetof(struct thread_options, verify_backlog),
9e144189
JA
2938 .help = "Verify after this number of blocks are written",
2939 .parent = "verify",
d71c154c 2940 .hide = 1,
e8b0e958
JA
2941 .category = FIO_OPT_C_IO,
2942 .group = FIO_OPT_G_VERIFY,
9e144189
JA
2943 },
2944 {
2945 .name = "verify_backlog_batch",
e8b0e958 2946 .lname = "Verify backlog batch",
9e144189 2947 .type = FIO_OPT_INT,
a609f12a 2948 .off1 = offsetof(struct thread_options, verify_batch),
9e144189 2949 .help = "Verify this number of IO blocks",
0d29de83 2950 .parent = "verify",
d71c154c 2951 .hide = 1,
e8b0e958
JA
2952 .category = FIO_OPT_C_IO,
2953 .group = FIO_OPT_G_VERIFY,
9e144189 2954 },
e8462bd8
JA
2955#ifdef FIO_HAVE_CPU_AFFINITY
2956 {
2957 .name = "verify_async_cpus",
e8b0e958 2958 .lname = "Async verify CPUs",
e8462bd8
JA
2959 .type = FIO_OPT_STR,
2960 .cb = str_verify_cpus_allowed_cb,
a609f12a 2961 .off1 = offsetof(struct thread_options, verify_cpumask),
e8462bd8
JA
2962 .help = "Set CPUs allowed for async verify threads",
2963 .parent = "verify_async",
d71c154c 2964 .hide = 1,
e8b0e958
JA
2965 .category = FIO_OPT_C_IO,
2966 .group = FIO_OPT_G_VERIFY,
e8462bd8 2967 },
a275c37a
JA
2968#else
2969 {
2970 .name = "verify_async_cpus",
2971 .lname = "Async verify CPUs",
2972 .type = FIO_OPT_UNSUPPORTED,
54d0a315 2973 .help = "Your platform does not support CPU affinities",
a275c37a 2974 },
0d29de83 2975#endif
51aa2da8
JA
2976 {
2977 .name = "experimental_verify",
cce2fdfe 2978 .lname = "Experimental Verify",
a609f12a 2979 .off1 = offsetof(struct thread_options, experimental_verify),
51aa2da8 2980 .type = FIO_OPT_BOOL,
b31eaac9 2981 .help = "Enable experimental verification",
ca09be4b
JA
2982 .parent = "verify",
2983 .category = FIO_OPT_C_IO,
2984 .group = FIO_OPT_G_VERIFY,
2985 },
2986 {
2987 .name = "verify_state_load",
2988 .lname = "Load verify state",
a609f12a 2989 .off1 = offsetof(struct thread_options, verify_state),
ca09be4b
JA
2990 .type = FIO_OPT_BOOL,
2991 .help = "Load verify termination state",
2992 .parent = "verify",
2993 .category = FIO_OPT_C_IO,
2994 .group = FIO_OPT_G_VERIFY,
2995 },
2996 {
2997 .name = "verify_state_save",
2998 .lname = "Save verify state",
a609f12a 2999 .off1 = offsetof(struct thread_options, verify_state_save),
ca09be4b
JA
3000 .type = FIO_OPT_BOOL,
3001 .def = "1",
3002 .help = "Save verify state on termination",
3003 .parent = "verify",
836fcc0f
JA
3004 .category = FIO_OPT_C_IO,
3005 .group = FIO_OPT_G_VERIFY,
51aa2da8 3006 },
0d29de83
JA
3007#ifdef FIO_HAVE_TRIM
3008 {
3009 .name = "trim_percentage",
e8b0e958 3010 .lname = "Trim percentage",
0d29de83 3011 .type = FIO_OPT_INT,
a609f12a 3012 .off1 = offsetof(struct thread_options, trim_percentage),
20eb06bd 3013 .minval = 0,
0d29de83 3014 .maxval = 100,
169c098d 3015 .help = "Number of verify blocks to trim (i.e., discard)",
0d29de83
JA
3016 .parent = "verify",
3017 .def = "0",
20eb06bd 3018 .interval = 1,
d71c154c 3019 .hide = 1,
e8b0e958
JA
3020 .category = FIO_OPT_C_IO,
3021 .group = FIO_OPT_G_TRIM,
0d29de83
JA
3022 },
3023 {
3024 .name = "trim_verify_zero",
e8b0e958 3025 .lname = "Verify trim zero",
20eb06bd 3026 .type = FIO_OPT_BOOL,
169c098d 3027 .help = "Verify that trimmed (i.e., discarded) blocks are returned as zeroes",
a609f12a 3028 .off1 = offsetof(struct thread_options, trim_zero),
0d29de83 3029 .parent = "trim_percentage",
d71c154c 3030 .hide = 1,
0d29de83 3031 .def = "1",
e8b0e958
JA
3032 .category = FIO_OPT_C_IO,
3033 .group = FIO_OPT_G_TRIM,
0d29de83
JA
3034 },
3035 {
3036 .name = "trim_backlog",
e8b0e958 3037 .lname = "Trim backlog",
0d29de83 3038 .type = FIO_OPT_STR_VAL,
a609f12a 3039 .off1 = offsetof(struct thread_options, trim_backlog),
0d29de83
JA
3040 .help = "Trim after this number of blocks are written",
3041 .parent = "trim_percentage",
d71c154c 3042 .hide = 1,
20eb06bd 3043 .interval = 1,
e8b0e958
JA
3044 .category = FIO_OPT_C_IO,
3045 .group = FIO_OPT_G_TRIM,
0d29de83
JA
3046 },
3047 {
3048 .name = "trim_backlog_batch",
e8b0e958 3049 .lname = "Trim backlog batch",
0d29de83 3050 .type = FIO_OPT_INT,
a609f12a 3051 .off1 = offsetof(struct thread_options, trim_batch),
0d29de83
JA
3052 .help = "Trim this number of IO blocks",
3053 .parent = "trim_percentage",
d71c154c 3054 .hide = 1,
20eb06bd 3055 .interval = 1,
e8b0e958
JA
3056 .category = FIO_OPT_C_IO,
3057 .group = FIO_OPT_G_TRIM,
0d29de83 3058 },
a275c37a
JA
3059#else
3060 {
3061 .name = "trim_percentage",
3062 .lname = "Trim percentage",
3063 .type = FIO_OPT_UNSUPPORTED,
3064 .help = "Fio does not support TRIM on your platform",
3065 },
3066 {
3067 .name = "trim_verify_zero",
3068 .lname = "Verify trim zero",
3069 .type = FIO_OPT_UNSUPPORTED,
3070 .help = "Fio does not support TRIM on your platform",
3071 },
3072 {
3073 .name = "trim_backlog",
3074 .lname = "Trim backlog",
3075 .type = FIO_OPT_UNSUPPORTED,
3076 .help = "Fio does not support TRIM on your platform",
3077 },
3078 {
3079 .name = "trim_backlog_batch",
3080 .lname = "Trim backlog batch",
3081 .type = FIO_OPT_UNSUPPORTED,
3082 .help = "Fio does not support TRIM on your platform",
3083 },
e8462bd8 3084#endif
214e1eca
JA
3085 {
3086 .name = "write_iolog",
e8b0e958 3087 .lname = "Write I/O log",
214e1eca 3088 .type = FIO_OPT_STR_STORE,
a609f12a 3089 .off1 = offsetof(struct thread_options, write_iolog_file),
214e1eca 3090 .help = "Store IO pattern to file",
e8b0e958
JA
3091 .category = FIO_OPT_C_IO,
3092 .group = FIO_OPT_G_IOLOG,
214e1eca
JA
3093 },
3094 {
3095 .name = "read_iolog",
e8b0e958 3096 .lname = "Read I/O log",
214e1eca 3097 .type = FIO_OPT_STR_STORE,
a609f12a 3098 .off1 = offsetof(struct thread_options, read_iolog_file),
214e1eca 3099 .help = "Playback IO pattern from file",
e8b0e958
JA
3100 .category = FIO_OPT_C_IO,
3101 .group = FIO_OPT_G_IOLOG,
214e1eca 3102 },
64bbb865
DN
3103 {
3104 .name = "replay_no_stall",
e8b0e958 3105 .lname = "Don't stall on replay",
20eb06bd 3106 .type = FIO_OPT_BOOL,
a609f12a 3107 .off1 = offsetof(struct thread_options, no_stall),
64bbb865 3108 .def = "0",
87e7a972 3109 .parent = "read_iolog",
d71c154c 3110 .hide = 1,
64bbb865 3111 .help = "Playback IO pattern file as fast as possible without stalls",
e8b0e958
JA
3112 .category = FIO_OPT_C_IO,
3113 .group = FIO_OPT_G_IOLOG,
64bbb865 3114 },
d1c46c04
DN
3115 {
3116 .name = "replay_redirect",
e8b0e958 3117 .lname = "Redirect device for replay",
d1c46c04 3118 .type = FIO_OPT_STR_STORE,
a609f12a 3119 .off1 = offsetof(struct thread_options, replay_redirect),
d1c46c04 3120 .parent = "read_iolog",
d71c154c 3121 .hide = 1,
d1c46c04 3122 .help = "Replay all I/O onto this device, regardless of trace device",
e8b0e958
JA
3123 .category = FIO_OPT_C_IO,
3124 .group = FIO_OPT_G_IOLOG,
d1c46c04 3125 },
0c63576e
JA
3126 {
3127 .name = "replay_scale",
3128 .lname = "Replace offset scale factor",
3129 .type = FIO_OPT_INT,
a609f12a 3130 .off1 = offsetof(struct thread_options, replay_scale),
0c63576e
JA
3131 .parent = "read_iolog",
3132 .def = "1",
3133 .help = "Align offsets to this blocksize",
3134 .category = FIO_OPT_C_IO,
3135 .group = FIO_OPT_G_IOLOG,
3136 },
3137 {
3138 .name = "replay_align",
3139 .lname = "Replace alignment",
3140 .type = FIO_OPT_INT,
a609f12a 3141 .off1 = offsetof(struct thread_options, replay_align),
0c63576e
JA
3142 .parent = "read_iolog",
3143 .help = "Scale offset down by this factor",
3144 .category = FIO_OPT_C_IO,
3145 .group = FIO_OPT_G_IOLOG,
3146 .pow2 = 1,
3147 },
6dd7fa77
JA
3148 {
3149 .name = "replay_time_scale",
3150 .lname = "Replay Time Scale",
3151 .type = FIO_OPT_INT,
3152 .off1 = offsetof(struct thread_options, replay_time_scale),
3153 .def = "100",
3154 .minval = 1,
3155 .parent = "read_iolog",
3156 .hide = 1,
3157 .help = "Scale time for replay events",
3158 .category = FIO_OPT_C_IO,
3159 .group = FIO_OPT_G_IOLOG,
3160 },
214e1eca
JA
3161 {
3162 .name = "exec_prerun",
e8b0e958 3163 .lname = "Pre-execute runnable",
214e1eca 3164 .type = FIO_OPT_STR_STORE,
a609f12a 3165 .off1 = offsetof(struct thread_options, exec_prerun),
214e1eca 3166 .help = "Execute this file prior to running job",
e8b0e958
JA
3167 .category = FIO_OPT_C_GENERAL,
3168 .group = FIO_OPT_G_INVALID,
214e1eca
JA
3169 },
3170 {
3171 .name = "exec_postrun",
e8b0e958 3172 .lname = "Post-execute runnable",
214e1eca 3173 .type = FIO_OPT_STR_STORE,
a609f12a 3174 .off1 = offsetof(struct thread_options, exec_postrun),
214e1eca 3175 .help = "Execute this file after running job",
e8b0e958
JA
3176 .category = FIO_OPT_C_GENERAL,
3177 .group = FIO_OPT_G_INVALID,
214e1eca
JA
3178 },
3179#ifdef FIO_HAVE_IOSCHED_SWITCH
3180 {
3181 .name = "ioscheduler",
e8b0e958 3182 .lname = "I/O scheduler",
214e1eca 3183 .type = FIO_OPT_STR_STORE,
a609f12a 3184 .off1 = offsetof(struct thread_options, ioscheduler),
214e1eca 3185 .help = "Use this IO scheduler on the backing device",
e8b0e958
JA
3186 .category = FIO_OPT_C_FILE,
3187 .group = FIO_OPT_G_INVALID,
214e1eca 3188 },
a275c37a
JA
3189#else
3190 {
3191 .name = "ioscheduler",
3192 .lname = "I/O scheduler",
3193 .type = FIO_OPT_UNSUPPORTED,
3194 .help = "Your platform does not support IO scheduler switching",
3195 },
214e1eca
JA
3196#endif
3197 {
3198 .name = "zonesize",
e8b0e958 3199 .lname = "Zone size",
214e1eca 3200 .type = FIO_OPT_STR_VAL,
a609f12a 3201 .off1 = offsetof(struct thread_options, zone_size),
ed335855
SN
3202 .help = "Amount of data to read per zone",
3203 .def = "0",
20eb06bd 3204 .interval = 1024 * 1024,
e8b0e958
JA
3205 .category = FIO_OPT_C_IO,
3206 .group = FIO_OPT_G_ZONE,
ed335855
SN
3207 },
3208 {
3209 .name = "zonerange",
e8b0e958 3210 .lname = "Zone range",
ed335855 3211 .type = FIO_OPT_STR_VAL,
a609f12a 3212 .off1 = offsetof(struct thread_options, zone_range),
214e1eca
JA
3213 .help = "Give size of an IO zone",
3214 .def = "0",
20eb06bd 3215 .interval = 1024 * 1024,
e8b0e958
JA
3216 .category = FIO_OPT_C_IO,
3217 .group = FIO_OPT_G_ZONE,
214e1eca
JA
3218 },
3219 {
3220 .name = "zoneskip",
e8b0e958 3221 .lname = "Zone skip",
214e1eca 3222 .type = FIO_OPT_STR_VAL,
a609f12a 3223 .off1 = offsetof(struct thread_options, zone_skip),
214e1eca
JA
3224 .help = "Space between IO zones",
3225 .def = "0",
20eb06bd 3226 .interval = 1024 * 1024,
e8b0e958
JA
3227 .category = FIO_OPT_C_IO,
3228 .group = FIO_OPT_G_ZONE,
214e1eca
JA
3229 },
3230 {
3231 .name = "lockmem",
e8b0e958 3232 .lname = "Lock memory",
214e1eca 3233 .type = FIO_OPT_STR_VAL,
a609f12a 3234 .off1 = offsetof(struct thread_options, lockmem),
81c6b6cd 3235 .help = "Lock down this amount of memory (per worker)",
214e1eca 3236 .def = "0",
20eb06bd 3237 .interval = 1024 * 1024,
e8b0e958
JA
3238 .category = FIO_OPT_C_GENERAL,
3239 .group = FIO_OPT_G_INVALID,
214e1eca 3240 },
214e1eca
JA
3241 {
3242 .name = "rwmixread",
e8b0e958 3243 .lname = "Read/write mix read",
214e1eca 3244 .type = FIO_OPT_INT,
cb499fc4 3245 .cb = str_rwmix_read_cb,
a609f12a 3246 .off1 = offsetof(struct thread_options, rwmix[DDIR_READ]),
214e1eca
JA
3247 .maxval = 100,
3248 .help = "Percentage of mixed workload that is reads",
3249 .def = "50",
20eb06bd 3250 .interval = 5,
90265353 3251 .inverse = "rwmixwrite",
e8b0e958
JA
3252 .category = FIO_OPT_C_IO,
3253 .group = FIO_OPT_G_RWMIX,
214e1eca
JA
3254 },
3255 {
3256 .name = "rwmixwrite",
e8b0e958 3257 .lname = "Read/write mix write",
214e1eca 3258 .type = FIO_OPT_INT,
cb499fc4 3259 .cb = str_rwmix_write_cb,
a609f12a 3260 .off1 = offsetof(struct thread_options, rwmix[DDIR_WRITE]),
214e1eca
JA
3261 .maxval = 100,
3262 .help = "Percentage of mixed workload that is writes",
3263 .def = "50",
20eb06bd 3264 .interval = 5,
90265353 3265 .inverse = "rwmixread",
e8b0e958
JA
3266 .category = FIO_OPT_C_IO,
3267 .group = FIO_OPT_G_RWMIX,
214e1eca 3268 },
afdf9352
JA
3269 {
3270 .name = "rwmixcycle",
e8b0e958 3271 .lname = "Read/write mix cycle",
15ca150e 3272 .type = FIO_OPT_DEPRECATED,
e8b0e958
JA
3273 .category = FIO_OPT_C_IO,
3274 .group = FIO_OPT_G_RWMIX,
afdf9352 3275 },
214e1eca
JA
3276 {
3277 .name = "nice",
e8b0e958 3278 .lname = "Nice",
214e1eca 3279 .type = FIO_OPT_INT,
a609f12a 3280 .off1 = offsetof(struct thread_options, nice),
214e1eca 3281 .help = "Set job CPU nice value",
11fd6aa8
RC
3282 .minval = -20,
3283 .maxval = 19,
214e1eca 3284 .def = "0",
20eb06bd 3285 .interval = 1,
e8b0e958 3286 .category = FIO_OPT_C_GENERAL,
10860056 3287 .group = FIO_OPT_G_CRED,
214e1eca
JA
3288 },
3289#ifdef FIO_HAVE_IOPRIO
3290 {
3291 .name = "prio",
e8b0e958 3292 .lname = "I/O nice priority",
214e1eca 3293 .type = FIO_OPT_INT,
a609f12a 3294 .off1 = offsetof(struct thread_options, ioprio),
214e1eca 3295 .help = "Set job IO priority value",
1767bd34
TK
3296 .minval = IOPRIO_MIN_PRIO,
3297 .maxval = IOPRIO_MAX_PRIO,
20eb06bd 3298 .interval = 1,
e8b0e958 3299 .category = FIO_OPT_C_GENERAL,
10860056 3300 .group = FIO_OPT_G_CRED,
214e1eca 3301 },
32ef447a
TK
3302#else
3303 {
3304 .name = "prio",
3305 .lname = "I/O nice priority",
3306 .type = FIO_OPT_UNSUPPORTED,
3307 .help = "Your platform does not support IO priorities",
3308 },
3309#endif
3310#ifdef FIO_HAVE_IOPRIO_CLASS
3311#ifndef FIO_HAVE_IOPRIO
3312#error "FIO_HAVE_IOPRIO_CLASS requires FIO_HAVE_IOPRIO"
3313#endif
214e1eca
JA
3314 {
3315 .name = "prioclass",
e8b0e958 3316 .lname = "I/O nice priority class",
214e1eca 3317 .type = FIO_OPT_INT,
a609f12a 3318 .off1 = offsetof(struct thread_options, ioprio_class),
214e1eca 3319 .help = "Set job IO priority class",
1767bd34
TK
3320 .minval = IOPRIO_MIN_PRIO_CLASS,
3321 .maxval = IOPRIO_MAX_PRIO_CLASS,
20eb06bd 3322 .interval = 1,
e8b0e958 3323 .category = FIO_OPT_C_GENERAL,
10860056 3324 .group = FIO_OPT_G_CRED,
214e1eca 3325 },
a275c37a 3326#else
a275c37a
JA
3327 {
3328 .name = "prioclass",
3329 .lname = "I/O nice priority class",
3330 .type = FIO_OPT_UNSUPPORTED,
32ef447a 3331 .help = "Your platform does not support IO priority classes",
a275c37a 3332 },
214e1eca
JA
3333#endif
3334 {
3335 .name = "thinktime",
e8b0e958 3336 .lname = "Thinktime",
214e1eca 3337 .type = FIO_OPT_INT,
a609f12a 3338 .off1 = offsetof(struct thread_options, thinktime),
214e1eca
JA
3339 .help = "Idle time between IO buffers (usec)",
3340 .def = "0",
88038bc7 3341 .is_time = 1,
e8b0e958 3342 .category = FIO_OPT_C_IO,
3ceb458f 3343 .group = FIO_OPT_G_THINKTIME,
214e1eca
JA
3344 },
3345 {
3346 .name = "thinktime_spin",
e8b0e958 3347 .lname = "Thinktime spin",
214e1eca 3348 .type = FIO_OPT_INT,
a609f12a 3349 .off1 = offsetof(struct thread_options, thinktime_spin),
214e1eca
JA
3350 .help = "Start think time by spinning this amount (usec)",
3351 .def = "0",
88038bc7 3352 .is_time = 1,
afdf9352 3353 .parent = "thinktime",
d71c154c 3354 .hide = 1,
e8b0e958 3355 .category = FIO_OPT_C_IO,
3ceb458f 3356 .group = FIO_OPT_G_THINKTIME,
214e1eca
JA
3357 },
3358 {
3359 .name = "thinktime_blocks",
e8b0e958 3360 .lname = "Thinktime blocks",
214e1eca 3361 .type = FIO_OPT_INT,
a609f12a 3362 .off1 = offsetof(struct thread_options, thinktime_blocks),
214e1eca
JA
3363 .help = "IO buffer period between 'thinktime'",
3364 .def = "1",
afdf9352 3365 .parent = "thinktime",
d71c154c 3366 .hide = 1,
e8b0e958 3367 .category = FIO_OPT_C_IO,
3ceb458f 3368 .group = FIO_OPT_G_THINKTIME,
214e1eca
JA
3369 },
3370 {
3371 .name = "rate",
e8b0e958 3372 .lname = "I/O rate",
e01b22b8 3373 .type = FIO_OPT_INT,
a609f12a
JA
3374 .off1 = offsetof(struct thread_options, rate[DDIR_READ]),
3375 .off2 = offsetof(struct thread_options, rate[DDIR_WRITE]),
3376 .off3 = offsetof(struct thread_options, rate[DDIR_TRIM]),
214e1eca 3377 .help = "Set bandwidth rate",
e8b0e958
JA
3378 .category = FIO_OPT_C_IO,
3379 .group = FIO_OPT_G_RATE,
214e1eca
JA
3380 },
3381 {
6d428bcd
JA
3382 .name = "rate_min",
3383 .alias = "ratemin",
e8b0e958 3384 .lname = "I/O min rate",
e01b22b8 3385 .type = FIO_OPT_INT,
a609f12a
JA
3386 .off1 = offsetof(struct thread_options, ratemin[DDIR_READ]),
3387 .off2 = offsetof(struct thread_options, ratemin[DDIR_WRITE]),
3388 .off3 = offsetof(struct thread_options, ratemin[DDIR_TRIM]),
4e991c23 3389 .help = "Job must meet this rate or it will be shutdown",
afdf9352 3390 .parent = "rate",
d71c154c 3391 .hide = 1,
e8b0e958
JA
3392 .category = FIO_OPT_C_IO,
3393 .group = FIO_OPT_G_RATE,
4e991c23
JA
3394 },
3395 {
3396 .name = "rate_iops",
e8b0e958 3397 .lname = "I/O rate IOPS",
e01b22b8 3398 .type = FIO_OPT_INT,
a609f12a
JA
3399 .off1 = offsetof(struct thread_options, rate_iops[DDIR_READ]),
3400 .off2 = offsetof(struct thread_options, rate_iops[DDIR_WRITE]),
3401 .off3 = offsetof(struct thread_options, rate_iops[DDIR_TRIM]),
4e991c23 3402 .help = "Limit IO used to this number of IO operations/sec",
d71c154c 3403 .hide = 1,
e8b0e958
JA
3404 .category = FIO_OPT_C_IO,
3405 .group = FIO_OPT_G_RATE,
4e991c23
JA
3406 },
3407 {
3408 .name = "rate_iops_min",
e8b0e958 3409 .lname = "I/O min rate IOPS",
e01b22b8 3410 .type = FIO_OPT_INT,
a609f12a
JA
3411 .off1 = offsetof(struct thread_options, rate_iops_min[DDIR_READ]),
3412 .off2 = offsetof(struct thread_options, rate_iops_min[DDIR_WRITE]),
3413 .off3 = offsetof(struct thread_options, rate_iops_min[DDIR_TRIM]),
03e20d68 3414 .help = "Job must meet this rate or it will be shut down",
afdf9352 3415 .parent = "rate_iops",
d71c154c 3416 .hide = 1,
e8b0e958
JA
3417 .category = FIO_OPT_C_IO,
3418 .group = FIO_OPT_G_RATE,
214e1eca 3419 },
ff6bb260 3420 {
6de65959
JA
3421 .name = "rate_process",
3422 .lname = "Rate Process",
3423 .type = FIO_OPT_STR,
a609f12a 3424 .off1 = offsetof(struct thread_options, rate_process),
6de65959
JA
3425 .help = "What process controls how rated IO is managed",
3426 .def = "linear",
ff6bb260
SL
3427 .category = FIO_OPT_C_IO,
3428 .group = FIO_OPT_G_RATE,
6de65959
JA
3429 .posval = {
3430 { .ival = "linear",
3431 .oval = RATE_PROCESS_LINEAR,
3432 .help = "Linear rate of IO",
3433 },
3434 {
3435 .ival = "poisson",
3436 .oval = RATE_PROCESS_POISSON,
3437 .help = "Rate follows Poisson process",
3438 },
3439 },
3440 .parent = "rate",
ff6bb260 3441 },
214e1eca 3442 {
6d428bcd
JA
3443 .name = "rate_cycle",
3444 .alias = "ratecycle",
e8b0e958 3445 .lname = "I/O rate cycle",
214e1eca 3446 .type = FIO_OPT_INT,
a609f12a 3447 .off1 = offsetof(struct thread_options, ratecycle),
214e1eca
JA
3448 .help = "Window average for rate limits (msec)",
3449 .def = "1000",
afdf9352 3450 .parent = "rate",
d71c154c 3451 .hide = 1,
e8b0e958
JA
3452 .category = FIO_OPT_C_IO,
3453 .group = FIO_OPT_G_RATE,
214e1eca 3454 },
1a9bf814
JA
3455 {
3456 .name = "rate_igno