options: we don't need the crc32c verify include
[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>
921c766f 7#include <libgen.h>
5921e80c
JA
8#include <fcntl.h>
9#include <sys/types.h>
10#include <sys/stat.h>
e13c3b50 11#include <netinet/in.h>
214e1eca
JA
12
13#include "fio.h"
4f5af7b2 14#include "verify.h"
214e1eca 15#include "parse.h"
eef32359 16#include "lib/fls.h"
61b9861d 17#include "lib/pattern.h"
9f988e2e 18#include "options.h"
d220c761 19#include "optgroup.h"
214e1eca 20
e13c3b50 21char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
72a703da 22
61b9861d
RP
23struct pattern_fmt_desc fmt_desc[] = {
24 {
25 .fmt = "%o",
26 .len = FIELD_SIZE(struct io_u *, offset),
27 .paste = paste_blockoff
28 }
29};
30
214e1eca
JA
31/*
32 * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
33 */
34static char *get_opt_postfix(const char *str)
35{
36 char *p = strstr(str, ":");
37
38 if (!p)
39 return NULL;
40
41 p++;
42 strip_blank_front(&p);
43 strip_blank_end(p);
44 return strdup(p);
45}
46
564ca972
JA
47static int bs_cmp(const void *p1, const void *p2)
48{
49 const struct bssplit *bsp1 = p1;
50 const struct bssplit *bsp2 = p2;
51
52 return bsp1->perc < bsp2->perc;
53}
54
83ea422a 55static int bssplit_ddir(struct thread_options *o, int ddir, char *str)
564ca972 56{
720e84ad 57 struct bssplit *bssplit;
564ca972
JA
58 unsigned int i, perc, perc_missing;
59 unsigned int max_bs, min_bs;
60 long long val;
720e84ad 61 char *fname;
564ca972 62
83ea422a 63 o->bssplit_nr[ddir] = 4;
720e84ad 64 bssplit = malloc(4 * sizeof(struct bssplit));
564ca972
JA
65
66 i = 0;
67 max_bs = 0;
68 min_bs = -1;
69 while ((fname = strsep(&str, ":")) != NULL) {
70 char *perc_str;
71
72 if (!strlen(fname))
73 break;
74
75 /*
76 * grow struct buffer, if needed
77 */
83ea422a
JA
78 if (i == o->bssplit_nr[ddir]) {
79 o->bssplit_nr[ddir] <<= 1;
80 bssplit = realloc(bssplit, o->bssplit_nr[ddir]
5ec10eaa 81 * sizeof(struct bssplit));
564ca972
JA
82 }
83
84 perc_str = strstr(fname, "/");
85 if (perc_str) {
86 *perc_str = '\0';
87 perc_str++;
88 perc = atoi(perc_str);
89 if (perc > 100)
90 perc = 100;
91 else if (!perc)
d711cce5 92 perc = -1U;
564ca972 93 } else
d711cce5 94 perc = -1U;
564ca972 95
88038bc7 96 if (str_to_decimal(fname, &val, 1, o, 0, 0)) {
564ca972 97 log_err("fio: bssplit conversion failed\n");
d8b97c8e 98 free(bssplit);
564ca972
JA
99 return 1;
100 }
101
102 if (val > max_bs)
103 max_bs = val;
104 if (val < min_bs)
105 min_bs = val;
106
720e84ad
JA
107 bssplit[i].bs = val;
108 bssplit[i].perc = perc;
564ca972
JA
109 i++;
110 }
111
83ea422a 112 o->bssplit_nr[ddir] = i;
564ca972
JA
113
114 /*
115 * Now check if the percentages add up, and how much is missing
116 */
117 perc = perc_missing = 0;
83ea422a 118 for (i = 0; i < o->bssplit_nr[ddir]; i++) {
720e84ad 119 struct bssplit *bsp = &bssplit[i];
564ca972 120
d711cce5 121 if (bsp->perc == -1U)
564ca972
JA
122 perc_missing++;
123 else
124 perc += bsp->perc;
125 }
126
40bafa33 127 if (perc > 100 && perc_missing > 1) {
564ca972 128 log_err("fio: bssplit percentages add to more than 100%%\n");
720e84ad 129 free(bssplit);
564ca972
JA
130 return 1;
131 }
d711cce5 132
564ca972
JA
133 /*
134 * If values didn't have a percentage set, divide the remains between
135 * them.
136 */
137 if (perc_missing) {
d711cce5 138 if (perc_missing == 1 && o->bssplit_nr[ddir] == 1)
40bafa33 139 perc = 100;
83ea422a 140 for (i = 0; i < o->bssplit_nr[ddir]; i++) {
720e84ad 141 struct bssplit *bsp = &bssplit[i];
564ca972 142
d711cce5 143 if (bsp->perc == -1U)
564ca972
JA
144 bsp->perc = (100 - perc) / perc_missing;
145 }
146 }
147
83ea422a
JA
148 o->min_bs[ddir] = min_bs;
149 o->max_bs[ddir] = max_bs;
564ca972
JA
150
151 /*
152 * now sort based on percentages, for ease of lookup
153 */
83ea422a
JA
154 qsort(bssplit, o->bssplit_nr[ddir], sizeof(struct bssplit), bs_cmp);
155 o->bssplit[ddir] = bssplit;
720e84ad 156 return 0;
720e84ad
JA
157}
158
159static int str_bssplit_cb(void *data, const char *input)
160{
161 struct thread_data *td = data;
6eaf09d6 162 char *str, *p, *odir, *ddir;
720e84ad
JA
163 int ret = 0;
164
52c0cea3
JA
165 if (parse_dryrun())
166 return 0;
167
720e84ad
JA
168 p = str = strdup(input);
169
170 strip_blank_front(&str);
171 strip_blank_end(str);
172
173 odir = strchr(str, ',');
174 if (odir) {
6eaf09d6
SL
175 ddir = strchr(odir + 1, ',');
176 if (ddir) {
d79db122 177 ret = bssplit_ddir(&td->o, DDIR_TRIM, ddir + 1);
6eaf09d6
SL
178 if (!ret)
179 *ddir = '\0';
180 } else {
181 char *op;
182
183 op = strdup(odir + 1);
d79db122 184 ret = bssplit_ddir(&td->o, DDIR_TRIM, op);
6eaf09d6
SL
185
186 free(op);
187 }
d79db122
JA
188 if (!ret)
189 ret = bssplit_ddir(&td->o, DDIR_WRITE, odir + 1);
720e84ad
JA
190 if (!ret) {
191 *odir = '\0';
83ea422a 192 ret = bssplit_ddir(&td->o, DDIR_READ, str);
720e84ad
JA
193 }
194 } else {
195 char *op;
196
197 op = strdup(str);
d79db122 198 ret = bssplit_ddir(&td->o, DDIR_WRITE, op);
6eaf09d6 199 free(op);
720e84ad 200
6eaf09d6
SL
201 if (!ret) {
202 op = strdup(str);
d79db122 203 ret = bssplit_ddir(&td->o, DDIR_TRIM, op);
6eaf09d6
SL
204 free(op);
205 }
f0c9c217
JA
206 if (!ret)
207 ret = bssplit_ddir(&td->o, DDIR_READ, str);
720e84ad 208 }
564ca972
JA
209
210 free(p);
720e84ad 211 return ret;
564ca972
JA
212}
213
8b28bd41
DM
214static int str2error(char *str)
215{
a94eb99a 216 const char *err[] = { "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO",
8b28bd41
DM
217 "ENXIO", "E2BIG", "ENOEXEC", "EBADF",
218 "ECHILD", "EAGAIN", "ENOMEM", "EACCES",
219 "EFAULT", "ENOTBLK", "EBUSY", "EEXIST",
220 "EXDEV", "ENODEV", "ENOTDIR", "EISDIR",
221 "EINVAL", "ENFILE", "EMFILE", "ENOTTY",
222 "ETXTBSY","EFBIG", "ENOSPC", "ESPIPE",
a94eb99a 223 "EROFS","EMLINK", "EPIPE", "EDOM", "ERANGE" };
8b28bd41
DM
224 int i = 0, num = sizeof(err) / sizeof(void *);
225
a94eb99a 226 while (i < num) {
8b28bd41
DM
227 if (!strcmp(err[i], str))
228 return i + 1;
229 i++;
230 }
231 return 0;
232}
233
234static int ignore_error_type(struct thread_data *td, int etype, char *str)
235{
236 unsigned int i;
237 int *error;
238 char *fname;
239
240 if (etype >= ERROR_TYPE_CNT) {
241 log_err("Illegal error type\n");
242 return 1;
243 }
244
245 td->o.ignore_error_nr[etype] = 4;
246 error = malloc(4 * sizeof(struct bssplit));
247
248 i = 0;
249 while ((fname = strsep(&str, ":")) != NULL) {
250
251 if (!strlen(fname))
252 break;
253
254 /*
255 * grow struct buffer, if needed
256 */
257 if (i == td->o.ignore_error_nr[etype]) {
258 td->o.ignore_error_nr[etype] <<= 1;
259 error = realloc(error, td->o.ignore_error_nr[etype]
260 * sizeof(int));
261 }
262 if (fname[0] == 'E') {
263 error[i] = str2error(fname);
264 } else {
265 error[i] = atoi(fname);
266 if (error[i] < 0)
1616e025 267 error[i] = -error[i];
8b28bd41
DM
268 }
269 if (!error[i]) {
270 log_err("Unknown error %s, please use number value \n",
271 fname);
0fddbf7a 272 free(error);
8b28bd41
DM
273 return 1;
274 }
275 i++;
276 }
277 if (i) {
278 td->o.continue_on_error |= 1 << etype;
279 td->o.ignore_error_nr[etype] = i;
280 td->o.ignore_error[etype] = error;
c7b086be
JA
281 } else
282 free(error);
283
8b28bd41
DM
284 return 0;
285
286}
287
288static int str_ignore_error_cb(void *data, const char *input)
289{
290 struct thread_data *td = data;
291 char *str, *p, *n;
292 int type = 0, ret = 1;
52c0cea3
JA
293
294 if (parse_dryrun())
295 return 0;
296
8b28bd41
DM
297 p = str = strdup(input);
298
299 strip_blank_front(&str);
300 strip_blank_end(str);
301
302 while (p) {
303 n = strchr(p, ',');
304 if (n)
305 *n++ = '\0';
306 ret = ignore_error_type(td, type, p);
307 if (ret)
308 break;
309 p = n;
310 type++;
311 }
312 free(str);
313 return ret;
314}
315
211097b2
JA
316static int str_rw_cb(void *data, const char *str)
317{
318 struct thread_data *td = data;
83ea422a 319 struct thread_options *o = &td->o;
27ca949f 320 char *nr;
211097b2 321
52c0cea3
JA
322 if (parse_dryrun())
323 return 0;
324
83ea422a
JA
325 o->ddir_seq_nr = 1;
326 o->ddir_seq_add = 0;
059b0802 327
27ca949f 328 nr = get_opt_postfix(str);
059b0802
JA
329 if (!nr)
330 return 0;
331
332 if (td_random(td))
83ea422a 333 o->ddir_seq_nr = atoi(nr);
059b0802
JA
334 else {
335 long long val;
336
88038bc7 337 if (str_to_decimal(nr, &val, 1, o, 0, 0)) {
059b0802
JA
338 log_err("fio: rw postfix parsing failed\n");
339 free(nr);
340 return 1;
341 }
342
83ea422a 343 o->ddir_seq_add = val;
182ec6ee 344 }
211097b2 345
059b0802 346 free(nr);
211097b2
JA
347 return 0;
348}
349
214e1eca
JA
350static int str_mem_cb(void *data, const char *mem)
351{
352 struct thread_data *td = data;
353
217b0f1d
LG
354 if (td->o.mem_type == MEM_MMAPHUGE || td->o.mem_type == MEM_MMAP ||
355 td->o.mem_type == MEM_MMAPSHARED)
836fcc0f 356 td->o.mmapfile = get_opt_postfix(mem);
214e1eca
JA
357
358 return 0;
359}
360
c223da83
JA
361static int fio_clock_source_cb(void *data, const char *str)
362{
363 struct thread_data *td = data;
364
365 fio_clock_source = td->o.clocksource;
fa80feae 366 fio_clock_source_set = 1;
01423eae 367 fio_clock_init();
c223da83
JA
368 return 0;
369}
370
85bc833b 371static int str_rwmix_read_cb(void *data, unsigned long long *val)
cb499fc4
JA
372{
373 struct thread_data *td = data;
374
375 td->o.rwmix[DDIR_READ] = *val;
376 td->o.rwmix[DDIR_WRITE] = 100 - *val;
377 return 0;
378}
379
85bc833b 380static int str_rwmix_write_cb(void *data, unsigned long long *val)
cb499fc4
JA
381{
382 struct thread_data *td = data;
383
384 td->o.rwmix[DDIR_WRITE] = *val;
385 td->o.rwmix[DDIR_READ] = 100 - *val;
386 return 0;
387}
388
214e1eca
JA
389static int str_exitall_cb(void)
390{
391 exitall_on_terminate = 1;
392 return 0;
393}
394
214e1eca 395#ifdef FIO_HAVE_CPU_AFFINITY
50b5860b 396int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu_index)
c2acfbac 397{
50b5860b 398 unsigned int i, index, cpus_in_mask;
c2acfbac 399 const long max_cpu = cpus_online();
c2acfbac 400
50b5860b
JA
401 cpus_in_mask = fio_cpu_count(mask);
402 cpu_index = cpu_index % cpus_in_mask;
403
404 index = 0;
c2acfbac 405 for (i = 0; i < max_cpu; i++) {
50b5860b 406 if (!fio_cpu_isset(mask, i))
c2acfbac 407 continue;
50b5860b
JA
408
409 if (cpu_index != index)
410 fio_cpu_clear(mask, i);
411
412 index++;
c2acfbac
JA
413 }
414
415 return fio_cpu_count(mask);
416}
417
85bc833b 418static int str_cpumask_cb(void *data, unsigned long long *val)
d2e268b0
JA
419{
420 struct thread_data *td = data;
214e1eca 421 unsigned int i;
b03daafb 422 long max_cpu;
d2ce18b5
JA
423 int ret;
424
52c0cea3
JA
425 if (parse_dryrun())
426 return 0;
427
d2ce18b5
JA
428 ret = fio_cpuset_init(&td->o.cpumask);
429 if (ret < 0) {
430 log_err("fio: cpuset_init failed\n");
431 td_verror(td, ret, "fio_cpuset_init");
432 return 1;
433 }
214e1eca 434
c00a2289 435 max_cpu = cpus_online();
214e1eca 436
62a7273d
JA
437 for (i = 0; i < sizeof(int) * 8; i++) {
438 if ((1 << i) & *val) {
b8411399 439 if (i >= max_cpu) {
b03daafb 440 log_err("fio: CPU %d too large (max=%ld)\n", i,
b8411399 441 max_cpu - 1);
b03daafb
JA
442 return 1;
443 }
62a7273d 444 dprint(FD_PARSE, "set cpu allowed %d\n", i);
6d459ee7 445 fio_cpu_set(&td->o.cpumask, i);
62a7273d
JA
446 }
447 }
d2e268b0 448
d2e268b0 449 return 0;
214e1eca
JA
450}
451
e8462bd8
JA
452static int set_cpus_allowed(struct thread_data *td, os_cpu_mask_t *mask,
453 const char *input)
214e1eca 454{
d2e268b0 455 char *cpu, *str, *p;
b03daafb 456 long max_cpu;
19608d6c 457 int ret = 0;
d2e268b0 458
e8462bd8 459 ret = fio_cpuset_init(mask);
d2ce18b5
JA
460 if (ret < 0) {
461 log_err("fio: cpuset_init failed\n");
462 td_verror(td, ret, "fio_cpuset_init");
463 return 1;
464 }
d2e268b0
JA
465
466 p = str = strdup(input);
214e1eca 467
d2e268b0
JA
468 strip_blank_front(&str);
469 strip_blank_end(str);
470
c00a2289 471 max_cpu = cpus_online();
b03daafb 472
d2e268b0 473 while ((cpu = strsep(&str, ",")) != NULL) {
62a7273d
JA
474 char *str2, *cpu2;
475 int icpu, icpu2;
476
d2e268b0
JA
477 if (!strlen(cpu))
478 break;
62a7273d
JA
479
480 str2 = cpu;
481 icpu2 = -1;
482 while ((cpu2 = strsep(&str2, "-")) != NULL) {
483 if (!strlen(cpu2))
484 break;
485
486 icpu2 = atoi(cpu2);
487 }
488
489 icpu = atoi(cpu);
490 if (icpu2 == -1)
491 icpu2 = icpu;
492 while (icpu <= icpu2) {
6d459ee7 493 if (icpu >= FIO_MAX_CPUS) {
19608d6c 494 log_err("fio: your OS only supports up to"
6d459ee7 495 " %d CPUs\n", (int) FIO_MAX_CPUS);
19608d6c
JA
496 ret = 1;
497 break;
498 }
9e986889 499 if (icpu >= max_cpu) {
b03daafb 500 log_err("fio: CPU %d too large (max=%ld)\n",
9e986889 501 icpu, max_cpu - 1);
b03daafb
JA
502 ret = 1;
503 break;
504 }
0b9d69ec 505
62a7273d 506 dprint(FD_PARSE, "set cpu allowed %d\n", icpu);
e8462bd8 507 fio_cpu_set(mask, icpu);
62a7273d
JA
508 icpu++;
509 }
19608d6c
JA
510 if (ret)
511 break;
d2e268b0
JA
512 }
513
514 free(p);
19608d6c 515 return ret;
214e1eca 516}
e8462bd8
JA
517
518static int str_cpus_allowed_cb(void *data, const char *input)
519{
520 struct thread_data *td = data;
e8462bd8 521
52c0cea3
JA
522 if (parse_dryrun())
523 return 0;
524
b2a9e649 525 return set_cpus_allowed(td, &td->o.cpumask, input);
e8462bd8
JA
526}
527
528static int str_verify_cpus_allowed_cb(void *data, const char *input)
529{
530 struct thread_data *td = data;
e8462bd8 531
466155e2
JA
532 if (parse_dryrun())
533 return 0;
534
b2a9e649 535 return set_cpus_allowed(td, &td->o.verify_cpumask, input);
e8462bd8 536}
c08f9fe2 537
105157ad 538#ifdef CONFIG_ZLIB
c08f9fe2
JA
539static int str_log_cpus_allowed_cb(void *data, const char *input)
540{
541 struct thread_data *td = data;
542
543 if (parse_dryrun())
544 return 0;
545
546 return set_cpus_allowed(td, &td->o.log_gz_cpumask, input);
547}
105157ad 548#endif /* CONFIG_ZLIB */
c08f9fe2 549
105157ad 550#endif /* FIO_HAVE_CPU_AFFINITY */
214e1eca 551
67bf9823 552#ifdef CONFIG_LIBNUMA
d0b937ed
YR
553static int str_numa_cpunodes_cb(void *data, char *input)
554{
555 struct thread_data *td = data;
43522848 556 struct bitmask *verify_bitmask;
d0b937ed 557
52c0cea3
JA
558 if (parse_dryrun())
559 return 0;
560
d0b937ed
YR
561 /* numa_parse_nodestring() parses a character string list
562 * of nodes into a bit mask. The bit mask is allocated by
563 * numa_allocate_nodemask(), so it should be freed by
564 * numa_free_nodemask().
565 */
43522848
DG
566 verify_bitmask = numa_parse_nodestring(input);
567 if (verify_bitmask == NULL) {
d0b937ed
YR
568 log_err("fio: numa_parse_nodestring failed\n");
569 td_verror(td, 1, "str_numa_cpunodes_cb");
570 return 1;
571 }
43522848 572 numa_free_nodemask(verify_bitmask);
d0b937ed 573
43522848 574 td->o.numa_cpunodes = strdup(input);
d0b937ed
YR
575 return 0;
576}
577
578static int str_numa_mpol_cb(void *data, char *input)
579{
580 struct thread_data *td = data;
581 const char * const policy_types[] =
05d6f44b 582 { "default", "prefer", "bind", "interleave", "local", NULL };
d0b937ed 583 int i;
52c0cea3 584 char *nodelist;
43522848 585 struct bitmask *verify_bitmask;
52c0cea3
JA
586
587 if (parse_dryrun())
588 return 0;
d0b937ed 589
52c0cea3 590 nodelist = strchr(input, ':');
d0b937ed
YR
591 if (nodelist) {
592 /* NUL-terminate mode */
593 *nodelist++ = '\0';
594 }
595
596 for (i = 0; i <= MPOL_LOCAL; i++) {
597 if (!strcmp(input, policy_types[i])) {
598 td->o.numa_mem_mode = i;
599 break;
600 }
601 }
602 if (i > MPOL_LOCAL) {
603 log_err("fio: memory policy should be: default, prefer, bind, interleave, local\n");
604 goto out;
605 }
606
607 switch (td->o.numa_mem_mode) {
608 case MPOL_PREFERRED:
609 /*
610 * Insist on a nodelist of one node only
611 */
612 if (nodelist) {
613 char *rest = nodelist;
614 while (isdigit(*rest))
615 rest++;
616 if (*rest) {
617 log_err("fio: one node only for \'prefer\'\n");
618 goto out;
619 }
620 } else {
621 log_err("fio: one node is needed for \'prefer\'\n");
622 goto out;
623 }
624 break;
625 case MPOL_INTERLEAVE:
626 /*
627 * Default to online nodes with memory if no nodelist
628 */
629 if (!nodelist)
630 nodelist = strdup("all");
631 break;
632 case MPOL_LOCAL:
633 case MPOL_DEFAULT:
634 /*
635 * Don't allow a nodelist
636 */
637 if (nodelist) {
638 log_err("fio: NO nodelist for \'local\'\n");
639 goto out;
640 }
641 break;
642 case MPOL_BIND:
643 /*
644 * Insist on a nodelist
645 */
646 if (!nodelist) {
647 log_err("fio: a nodelist is needed for \'bind\'\n");
648 goto out;
649 }
650 break;
651 }
652
653
654 /* numa_parse_nodestring() parses a character string list
655 * of nodes into a bit mask. The bit mask is allocated by
656 * numa_allocate_nodemask(), so it should be freed by
657 * numa_free_nodemask().
658 */
659 switch (td->o.numa_mem_mode) {
660 case MPOL_PREFERRED:
661 td->o.numa_mem_prefer_node = atoi(nodelist);
662 break;
663 case MPOL_INTERLEAVE:
664 case MPOL_BIND:
43522848
DG
665 verify_bitmask = numa_parse_nodestring(nodelist);
666 if (verify_bitmask == NULL) {
d0b937ed
YR
667 log_err("fio: numa_parse_nodestring failed\n");
668 td_verror(td, 1, "str_numa_memnodes_cb");
669 return 1;
670 }
43522848
DG
671 td->o.numa_memnodes = strdup(nodelist);
672 numa_free_nodemask(verify_bitmask);
b74e419e 673
d0b937ed
YR
674 break;
675 case MPOL_LOCAL:
676 case MPOL_DEFAULT:
677 default:
678 break;
679 }
680
d0b937ed 681 return 0;
d0b937ed
YR
682out:
683 return 1;
684}
685#endif
686
214e1eca
JA
687static int str_fst_cb(void *data, const char *str)
688{
689 struct thread_data *td = data;
690 char *nr = get_opt_postfix(str);
691
692 td->file_service_nr = 1;
182ec6ee 693 if (nr) {
214e1eca 694 td->file_service_nr = atoi(nr);
182ec6ee
JA
695 free(nr);
696 }
214e1eca
JA
697
698 return 0;
699}
700
67bf9823 701#ifdef CONFIG_SYNC_FILE_RANGE
44f29692
JA
702static int str_sfr_cb(void *data, const char *str)
703{
704 struct thread_data *td = data;
705 char *nr = get_opt_postfix(str);
706
707 td->sync_file_range_nr = 1;
708 if (nr) {
709 td->sync_file_range_nr = atoi(nr);
710 free(nr);
711 }
712
713 return 0;
714}
3ae06371 715#endif
44f29692 716
e25839d4
JA
717static int str_random_distribution_cb(void *data, const char *str)
718{
719 struct thread_data *td = data;
720 double val;
721 char *nr;
722
52c0cea3
JA
723 if (parse_dryrun())
724 return 0;
725
925fee33 726 if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
c95f9404 727 val = FIO_DEF_ZIPF;
925fee33 728 else if (td->o.random_distribution == FIO_RAND_DIST_PARETO)
c95f9404 729 val = FIO_DEF_PARETO;
56d9fa4b
JA
730 else if (td->o.random_distribution == FIO_RAND_DIST_GAUSS)
731 val = 0.0;
925fee33 732 else
e25839d4
JA
733 return 0;
734
735 nr = get_opt_postfix(str);
88038bc7 736 if (nr && !str_to_float(nr, &val, 0)) {
e25839d4
JA
737 log_err("fio: random postfix parsing failed\n");
738 free(nr);
739 return 1;
740 }
741
078189c1
JA
742 free(nr);
743
18ded917
JA
744 if (td->o.random_distribution == FIO_RAND_DIST_ZIPF) {
745 if (val == 1.00) {
746 log_err("fio: zipf theta must different than 1.0\n");
747 return 1;
748 }
1e5324e7 749 td->o.zipf_theta.u.f = val;
56d9fa4b 750 } else if (td->o.random_distribution == FIO_RAND_DIST_PARETO) {
078189c1
JA
751 if (val <= 0.00 || val >= 1.00) {
752 log_err("fio: pareto input out of range (0 < input < 1.0)\n");
753 return 1;
754 }
1e5324e7 755 td->o.pareto_h.u.f = val;
3cdb8cf3
JA
756 } else {
757 if (val <= 0.00 || val >= 100.0) {
758 log_err("fio: normal deviation out of range (0 < input < 100.0)\n");
759 return 1;
760 }
f88cd222 761 td->o.gauss_dev.u.f = val;
3cdb8cf3 762 }
921c766f
JA
763
764 return 0;
765}
766
8e827d35 767/*
bcbfeefa 768 * Return next name in the string. Files are separated with ':'. If the ':'
8e827d35
JA
769 * is escaped with a '\', then that ':' is part of the filename and does not
770 * indicate a new file.
771 */
bcbfeefa 772static char *get_next_name(char **ptr)
8e827d35
JA
773{
774 char *str = *ptr;
775 char *p, *start;
776
777 if (!str || !strlen(str))
778 return NULL;
779
780 start = str;
781 do {
782 /*
783 * No colon, we are done
784 */
785 p = strchr(str, ':');
786 if (!p) {
787 *ptr = NULL;
788 break;
789 }
790
791 /*
792 * We got a colon, but it's the first character. Skip and
793 * continue
794 */
795 if (p == start) {
796 str = ++start;
797 continue;
798 }
799
800 if (*(p - 1) != '\\') {
801 *p = '\0';
802 *ptr = p + 1;
803 break;
804 }
805
806 memmove(p - 1, p, strlen(p) + 1);
807 str = p;
808 } while (1);
809
810 return start;
811}
812
bcbfeefa
CE
813
814static int get_max_name_idx(char *input)
815{
816 unsigned int cur_idx;
817 char *str, *p;
818
819 p = str = strdup(input);
820 for (cur_idx = 0; ; cur_idx++)
821 if (get_next_name(&str) == NULL)
822 break;
823
824 free(p);
825 return cur_idx;
826}
827
828/*
829 * Returns the directory at the index, indexes > entires will be
830 * assigned via modulo division of the index
831 */
e13c3b50 832int set_name_idx(char *target, size_t tlen, char *input, int index)
bcbfeefa
CE
833{
834 unsigned int cur_idx;
835 int len;
836 char *fname, *str, *p;
837
838 p = str = strdup(input);
839
840 index %= get_max_name_idx(input);
841 for (cur_idx = 0; cur_idx <= index; cur_idx++)
842 fname = get_next_name(&str);
843
72a703da 844 if (client_sockaddr_str[0]) {
e13c3b50
JA
845 len = snprintf(target, tlen, "%s/%s.", fname,
846 client_sockaddr_str);
847 } else
848 len = snprintf(target, tlen, "%s/", fname);
72a703da 849
e13c3b50 850 target[tlen - 1] = '\0';
bcbfeefa
CE
851 free(p);
852
853 return len;
854}
855
214e1eca
JA
856static int str_filename_cb(void *data, const char *input)
857{
858 struct thread_data *td = data;
859 char *fname, *str, *p;
860
861 p = str = strdup(input);
862
863 strip_blank_front(&str);
864 strip_blank_end(str);
865
866 if (!td->files_index)
2dc1bbeb 867 td->o.nr_files = 0;
214e1eca 868
bcbfeefa 869 while ((fname = get_next_name(&str)) != NULL) {
214e1eca
JA
870 if (!strlen(fname))
871 break;
5903e7b7 872 add_file(td, fname, 0, 1);
214e1eca
JA
873 }
874
875 free(p);
876 return 0;
877}
878
bcbfeefa 879static int str_directory_cb(void *data, const char fio_unused *unused)
214e1eca
JA
880{
881 struct thread_data *td = data;
882 struct stat sb;
bcbfeefa
CE
883 char *dirname, *str, *p;
884 int ret = 0;
214e1eca 885
f9633d72
JA
886 if (parse_dryrun())
887 return 0;
888
bcbfeefa
CE
889 p = str = strdup(td->o.directory);
890 while ((dirname = get_next_name(&str)) != NULL) {
891 if (lstat(dirname, &sb) < 0) {
892 ret = errno;
921c766f 893
bcbfeefa
CE
894 log_err("fio: %s is not a directory\n", dirname);
895 td_verror(td, ret, "lstat");
896 goto out;
897 }
898 if (!S_ISDIR(sb.st_mode)) {
899 log_err("fio: %s is not a directory\n", dirname);
900 ret = 1;
901 goto out;
902 }
214e1eca
JA
903 }
904
bcbfeefa
CE
905out:
906 free(p);
907 return ret;
214e1eca
JA
908}
909
910static int str_opendir_cb(void *data, const char fio_unused *str)
911{
912 struct thread_data *td = data;
913
52c0cea3
JA
914 if (parse_dryrun())
915 return 0;
916
214e1eca 917 if (!td->files_index)
2dc1bbeb 918 td->o.nr_files = 0;
214e1eca 919
2dc1bbeb 920 return add_dir_files(td, td->o.opendir);
214e1eca
JA
921}
922
ce35b1ec
JA
923static int str_buffer_pattern_cb(void *data, const char *input)
924{
925 struct thread_data *td = data;
926 int ret;
927
61b9861d
RP
928 /* FIXME: for now buffer pattern does not support formats */
929 ret = parse_and_fill_pattern(input, strlen(input), td->o.buffer_pattern,
930 MAX_PATTERN_SIZE, NULL, 0, NULL, NULL);
931 if (ret < 0)
932 return 1;
ce35b1ec 933
61b9861d
RP
934 assert(ret != 0);
935 td->o.buffer_pattern_bytes = ret;
936 if (!td->o.compress_percentage)
937 td->o.refill_buffers = 0;
938 td->o.scramble_buffers = 0;
939 td->o.zero_buffers = 0;
efcd9dcc 940
61b9861d 941 return 0;
ce35b1ec
JA
942}
943
bedc9dc2
JA
944static int str_buffer_compress_cb(void *data, unsigned long long *il)
945{
946 struct thread_data *td = data;
947
948 td->flags |= TD_F_COMPRESS;
949 td->o.compress_percentage = *il;
950 return 0;
951}
952
5c94b008
JA
953static int str_dedupe_cb(void *data, unsigned long long *il)
954{
955 struct thread_data *td = data;
956
957 td->flags |= TD_F_COMPRESS;
958 td->o.dedupe_percentage = *il;
959 td->o.refill_buffers = 1;
960 return 0;
961}
962
ce35b1ec
JA
963static int str_verify_pattern_cb(void *data, const char *input)
964{
965 struct thread_data *td = data;
966 int ret;
967
61b9861d
RP
968 td->o.verify_fmt_sz = ARRAY_SIZE(td->o.verify_fmt);
969 ret = parse_and_fill_pattern(input, strlen(input), td->o.verify_pattern,
970 MAX_PATTERN_SIZE, fmt_desc, sizeof(fmt_desc),
971 td->o.verify_fmt, &td->o.verify_fmt_sz);
972 if (ret < 0)
973 return 1;
efcd9dcc 974
61b9861d
RP
975 assert(ret != 0);
976 td->o.verify_pattern_bytes = ret;
92bf48d5 977 /*
b638d82f 978 * VERIFY_* could already be set
92bf48d5 979 */
61b9861d 980 if (!fio_option_is_set(&td->o, verify))
92bf48d5 981 td->o.verify = VERIFY_PATTERN;
efcd9dcc 982
61b9861d 983 return 0;
90059d65 984}
214e1eca 985
993bf48b
JA
986static int str_gtod_reduce_cb(void *data, int *il)
987{
988 struct thread_data *td = data;
989 int val = *il;
990
02af0988 991 td->o.disable_lat = !!val;
993bf48b
JA
992 td->o.disable_clat = !!val;
993 td->o.disable_slat = !!val;
994 td->o.disable_bw = !!val;
0dc1bc03 995 td->o.clat_percentiles = !val;
993bf48b
JA
996 if (val)
997 td->tv_cache_mask = 63;
998
999 return 0;
1000}
1001
7bb59102
JA
1002static int str_size_cb(void *data, unsigned long long *__val)
1003{
1004 struct thread_data *td = data;
1005 unsigned long long v = *__val;
1006
1007 if (parse_is_percent(v)) {
1008 td->o.size = 0;
1009 td->o.size_percent = -1ULL - v;
1010 } else
1011 td->o.size = v;
1012
1013 return 0;
1014}
1015
896cac2a
JA
1016static int rw_verify(struct fio_option *o, void *data)
1017{
1018 struct thread_data *td = data;
1019
1020 if (read_only && td_write(td)) {
1021 log_err("fio: job <%s> has write bit set, but fio is in"
1022 " read-only mode\n", td->o.name);
1023 return 1;
1024 }
1025
1026 return 0;
1027}
1028
276ca4f7 1029static int gtod_cpu_verify(struct fio_option *o, void *data)
29d43ff9 1030{
276ca4f7 1031#ifndef FIO_HAVE_CPU_AFFINITY
29d43ff9
JA
1032 struct thread_data *td = data;
1033
29d43ff9
JA
1034 if (td->o.gtod_cpu) {
1035 log_err("fio: platform must support CPU affinity for"
1036 "gettimeofday() offloading\n");
1037 return 1;
1038 }
1039#endif
1040
1041 return 0;
1042}
1043
214e1eca
JA
1044/*
1045 * Map of job/command line options
1046 */
9af4a244 1047struct fio_option fio_options[FIO_MAX_OPTS] = {
214e1eca
JA
1048 {
1049 .name = "description",
e8b0e958 1050 .lname = "Description of job",
214e1eca
JA
1051 .type = FIO_OPT_STR_STORE,
1052 .off1 = td_var_offset(description),
1053 .help = "Text job description",
e8b0e958 1054 .category = FIO_OPT_C_GENERAL,
0626037e 1055 .group = FIO_OPT_G_DESC,
214e1eca
JA
1056 },
1057 {
1058 .name = "name",
e8b0e958 1059 .lname = "Job name",
214e1eca
JA
1060 .type = FIO_OPT_STR_STORE,
1061 .off1 = td_var_offset(name),
1062 .help = "Name of this job",
e8b0e958 1063 .category = FIO_OPT_C_GENERAL,
0626037e 1064 .group = FIO_OPT_G_DESC,
214e1eca 1065 },
9cc8cb91
AK
1066 {
1067 .name = "wait_for",
1068 .lname = "Waitee name",
1069 .type = FIO_OPT_STR_STORE,
1070 .off1 = td_var_offset(wait_for),
1071 .help = "Name of the job this one wants to wait for before starting",
1072 .category = FIO_OPT_C_GENERAL,
1073 .group = FIO_OPT_G_DESC,
1074 },
214e1eca
JA
1075 {
1076 .name = "filename",
e8b0e958 1077 .lname = "Filename(s)",
214e1eca
JA
1078 .type = FIO_OPT_STR_STORE,
1079 .off1 = td_var_offset(filename),
1080 .cb = str_filename_cb,
f0d524b0 1081 .prio = -1, /* must come after "directory" */
214e1eca 1082 .help = "File(s) to use for the workload",
e8b0e958 1083 .category = FIO_OPT_C_FILE,
0626037e 1084 .group = FIO_OPT_G_FILENAME,
214e1eca 1085 },
90fef2d1 1086 {
e8b0e958
JA
1087 .name = "directory",
1088 .lname = "Directory",
1089 .type = FIO_OPT_STR_STORE,
1090 .off1 = td_var_offset(directory),
1091 .cb = str_directory_cb,
1092 .help = "Directory to store files in",
1093 .category = FIO_OPT_C_FILE,
0626037e 1094 .group = FIO_OPT_G_FILENAME,
90fef2d1 1095 },
de98bd30
JA
1096 {
1097 .name = "filename_format",
1098 .type = FIO_OPT_STR_STORE,
1099 .off1 = td_var_offset(filename_format),
1100 .prio = -1, /* must come after "directory" */
1101 .help = "Override default $jobname.$jobnum.$filenum naming",
1102 .def = "$jobname.$jobnum.$filenum",
93bb626a
JA
1103 .category = FIO_OPT_C_FILE,
1104 .group = FIO_OPT_G_FILENAME,
ad705bcb 1105 },
29c1349f
JA
1106 {
1107 .name = "lockfile",
e8b0e958 1108 .lname = "Lockfile",
4d4e80f2 1109 .type = FIO_OPT_STR,
4d4e80f2 1110 .off1 = td_var_offset(file_lock_mode),
29c1349f 1111 .help = "Lock file when doing IO to it",
bc6a0a5d 1112 .prio = 1,
29c1349f 1113 .parent = "filename",
d71c154c 1114 .hide = 0,
4d4e80f2 1115 .def = "none",
e8b0e958 1116 .category = FIO_OPT_C_FILE,
0626037e 1117 .group = FIO_OPT_G_FILENAME,
4d4e80f2
JA
1118 .posval = {
1119 { .ival = "none",
1120 .oval = FILE_LOCK_NONE,
1121 .help = "No file locking",
1122 },
1123 { .ival = "exclusive",
1124 .oval = FILE_LOCK_EXCLUSIVE,
1125 .help = "Exclusive file lock",
1126 },
1127 {
1128 .ival = "readwrite",
1129 .oval = FILE_LOCK_READWRITE,
1130 .help = "Read vs write lock",
1131 },
1132 },
29c1349f 1133 },
214e1eca
JA
1134 {
1135 .name = "opendir",
e8b0e958 1136 .lname = "Open directory",
214e1eca
JA
1137 .type = FIO_OPT_STR_STORE,
1138 .off1 = td_var_offset(opendir),
1139 .cb = str_opendir_cb,
1140 .help = "Recursively add files from this directory and down",
e8b0e958 1141 .category = FIO_OPT_C_FILE,
0626037e 1142 .group = FIO_OPT_G_FILENAME,
214e1eca
JA
1143 },
1144 {
1145 .name = "rw",
e8b0e958 1146 .lname = "Read/write",
d3aad8f2 1147 .alias = "readwrite",
214e1eca 1148 .type = FIO_OPT_STR,
211097b2 1149 .cb = str_rw_cb,
214e1eca
JA
1150 .off1 = td_var_offset(td_ddir),
1151 .help = "IO direction",
1152 .def = "read",
896cac2a 1153 .verify = rw_verify,
e8b0e958 1154 .category = FIO_OPT_C_IO,
0626037e 1155 .group = FIO_OPT_G_IO_BASIC,
214e1eca
JA
1156 .posval = {
1157 { .ival = "read",
1158 .oval = TD_DDIR_READ,
1159 .help = "Sequential read",
1160 },
1161 { .ival = "write",
1162 .oval = TD_DDIR_WRITE,
1163 .help = "Sequential write",
1164 },
6eaf09d6
SL
1165 { .ival = "trim",
1166 .oval = TD_DDIR_TRIM,
1167 .help = "Sequential trim",
1168 },
214e1eca
JA
1169 { .ival = "randread",
1170 .oval = TD_DDIR_RANDREAD,
1171 .help = "Random read",
1172 },
1173 { .ival = "randwrite",
1174 .oval = TD_DDIR_RANDWRITE,
1175 .help = "Random write",
1176 },
6eaf09d6
SL
1177 { .ival = "randtrim",
1178 .oval = TD_DDIR_RANDTRIM,
1179 .help = "Random trim",
1180 },
214e1eca
JA
1181 { .ival = "rw",
1182 .oval = TD_DDIR_RW,
1183 .help = "Sequential read and write mix",
1184 },
10b023db
JA
1185 { .ival = "readwrite",
1186 .oval = TD_DDIR_RW,
1187 .help = "Sequential read and write mix",
1188 },
214e1eca
JA
1189 { .ival = "randrw",
1190 .oval = TD_DDIR_RANDRW,
1191 .help = "Random read and write mix"
1192 },
82a90686
JA
1193 { .ival = "trimwrite",
1194 .oval = TD_DDIR_TRIMWRITE,
1195 .help = "Trim and write mix, trims preceding writes"
0e4dd95c 1196 },
214e1eca
JA
1197 },
1198 },
38dad62d
JA
1199 {
1200 .name = "rw_sequencer",
e8b0e958 1201 .lname = "RW Sequencer",
38dad62d
JA
1202 .type = FIO_OPT_STR,
1203 .off1 = td_var_offset(rw_seq),
1204 .help = "IO offset generator modifier",
1205 .def = "sequential",
e8b0e958 1206 .category = FIO_OPT_C_IO,
0626037e 1207 .group = FIO_OPT_G_IO_BASIC,
38dad62d
JA
1208 .posval = {
1209 { .ival = "sequential",
1210 .oval = RW_SEQ_SEQ,
1211 .help = "Generate sequential offsets",
1212 },
1213 { .ival = "identical",
1214 .oval = RW_SEQ_IDENT,
1215 .help = "Generate identical offsets",
1216 },
1217 },
1218 },
1219
214e1eca
JA
1220 {
1221 .name = "ioengine",
e8b0e958 1222 .lname = "IO Engine",
214e1eca
JA
1223 .type = FIO_OPT_STR_STORE,
1224 .off1 = td_var_offset(ioengine),
1225 .help = "IO engine to use",
58483fa4 1226 .def = FIO_PREFERRED_ENGINE,
e8b0e958 1227 .category = FIO_OPT_C_IO,
0626037e 1228 .group = FIO_OPT_G_IO_BASIC,
214e1eca
JA
1229 .posval = {
1230 { .ival = "sync",
1231 .help = "Use read/write",
1232 },
a31041ea 1233 { .ival = "psync",
1234 .help = "Use pread/pwrite",
1235 },
1d2af02a 1236 { .ival = "vsync",
03e20d68 1237 .help = "Use readv/writev",
1d2af02a 1238 },
07fc0acd
JA
1239#ifdef CONFIG_PWRITEV
1240 { .ival = "pvsync",
1241 .help = "Use preadv/pwritev",
1242 },
1243#endif
67bf9823 1244#ifdef CONFIG_LIBAIO
214e1eca
JA
1245 { .ival = "libaio",
1246 .help = "Linux native asynchronous IO",
1247 },
1248#endif
67bf9823 1249#ifdef CONFIG_POSIXAIO
214e1eca
JA
1250 { .ival = "posixaio",
1251 .help = "POSIX asynchronous IO",
1252 },
417f0068 1253#endif
997843cb 1254#ifdef CONFIG_SOLARISAIO
417f0068
JA
1255 { .ival = "solarisaio",
1256 .help = "Solaris native asynchronous IO",
1257 },
214e1eca 1258#endif
4700b234 1259#ifdef CONFIG_WINDOWSAIO
03e20d68 1260 { .ival = "windowsaio",
3be80071 1261 .help = "Windows native asynchronous IO"
de890a1e 1262 },
fc5c0345
DG
1263#endif
1264#ifdef CONFIG_RBD
1265 { .ival = "rbd",
1266 .help = "Rados Block Device asynchronous IO"
1267 },
3be80071 1268#endif
214e1eca 1269 { .ival = "mmap",
03e20d68 1270 .help = "Memory mapped IO"
214e1eca 1271 },
67bf9823 1272#ifdef CONFIG_LINUX_SPLICE
214e1eca
JA
1273 { .ival = "splice",
1274 .help = "splice/vmsplice based IO",
1275 },
9cce02e8
JA
1276 { .ival = "netsplice",
1277 .help = "splice/vmsplice to/from the network",
1278 },
214e1eca
JA
1279#endif
1280#ifdef FIO_HAVE_SGIO
1281 { .ival = "sg",
1282 .help = "SCSI generic v3 IO",
1283 },
1284#endif
1285 { .ival = "null",
1286 .help = "Testing engine (no data transfer)",
1287 },
1288 { .ival = "net",
1289 .help = "Network IO",
1290 },
214e1eca 1291 { .ival = "cpuio",
03e20d68 1292 .help = "CPU cycle burner engine",
214e1eca 1293 },
67bf9823 1294#ifdef CONFIG_GUASI
b8c82a46
JA
1295 { .ival = "guasi",
1296 .help = "GUASI IO engine",
1297 },
79a43187
JA
1298#endif
1299#ifdef FIO_HAVE_BINJECT
1300 { .ival = "binject",
1301 .help = "binject direct inject block engine",
1302 },
21b8aee8 1303#endif
67bf9823 1304#ifdef CONFIG_RDMA
21b8aee8 1305 { .ival = "rdma",
1306 .help = "RDMA IO engine",
1307 },
8200b8c7 1308#endif
67bf9823 1309#ifdef CONFIG_FUSION_AW
8200b8c7
JA
1310 { .ival = "fusion-aw-sync",
1311 .help = "Fusion-io atomic write engine",
1312 },
1ecc95ca 1313#endif
997843cb 1314#ifdef CONFIG_LINUX_EXT4_MOVE_EXTENT
1ecc95ca
JA
1315 { .ival = "e4defrag",
1316 .help = "ext4 defrag engine",
1317 },
1318#endif
997843cb 1319#ifdef CONFIG_LINUX_FALLOCATE
1ecc95ca
JA
1320 { .ival = "falloc",
1321 .help = "fallocate() file based engine",
1322 },
b8c82a46 1323#endif
a7c386f4 1324#ifdef CONFIG_GFAPI
1325 { .ival = "gfapi",
cc47f094 1326 .help = "Glusterfs libgfapi(sync) based engine"
1327 },
1328 { .ival = "gfapi_async",
1329 .help = "Glusterfs libgfapi(async) based engine"
a7c386f4 1330 },
1331#endif
1b10477b 1332#ifdef CONFIG_LIBHDFS
b74e419e 1333 { .ival = "libhdfs",
1b10477b
MM
1334 .help = "Hadoop Distributed Filesystem (HDFS) engine"
1335 },
1336#endif
214e1eca
JA
1337 { .ival = "external",
1338 .help = "Load external engine (append name)",
1339 },
1340 },
1341 },
1342 {
1343 .name = "iodepth",
e8b0e958 1344 .lname = "IO Depth",
214e1eca
JA
1345 .type = FIO_OPT_INT,
1346 .off1 = td_var_offset(iodepth),
03e20d68 1347 .help = "Number of IO buffers to keep in flight",
757aff4f 1348 .minval = 1,
20eb06bd 1349 .interval = 1,
214e1eca 1350 .def = "1",
e8b0e958 1351 .category = FIO_OPT_C_IO,
0626037e 1352 .group = FIO_OPT_G_IO_BASIC,
214e1eca
JA
1353 },
1354 {
1355 .name = "iodepth_batch",
e8b0e958 1356 .lname = "IO Depth batch",
4950421a 1357 .alias = "iodepth_batch_submit",
214e1eca
JA
1358 .type = FIO_OPT_INT,
1359 .off1 = td_var_offset(iodepth_batch),
d65db441 1360 .help = "Number of IO buffers to submit in one go",
afdf9352 1361 .parent = "iodepth",
d71c154c 1362 .hide = 1,
a2e6f8ac 1363 .minval = 1,
20eb06bd 1364 .interval = 1,
a2e6f8ac 1365 .def = "1",
e8b0e958 1366 .category = FIO_OPT_C_IO,
0626037e 1367 .group = FIO_OPT_G_IO_BASIC,
4950421a
JA
1368 },
1369 {
82407585
RP
1370 .name = "iodepth_batch_complete_min",
1371 .lname = "Min IO depth batch complete",
1372 .alias = "iodepth_batch_complete",
4950421a 1373 .type = FIO_OPT_INT,
82407585
RP
1374 .off1 = td_var_offset(iodepth_batch_complete_min),
1375 .help = "Min number of IO buffers to retrieve in one go",
4950421a 1376 .parent = "iodepth",
d71c154c 1377 .hide = 1,
4950421a 1378 .minval = 0,
20eb06bd 1379 .interval = 1,
4950421a 1380 .def = "1",
e8b0e958 1381 .category = FIO_OPT_C_IO,
0626037e 1382 .group = FIO_OPT_G_IO_BASIC,
214e1eca 1383 },
82407585
RP
1384 {
1385 .name = "iodepth_batch_complete_max",
1386 .lname = "Max IO depth batch complete",
1387 .type = FIO_OPT_INT,
1388 .off1 = td_var_offset(iodepth_batch_complete_max),
1389 .help = "Max number of IO buffers to retrieve in one go",
1390 .parent = "iodepth",
1391 .hide = 1,
1392 .minval = 0,
1393 .interval = 1,
1394 .category = FIO_OPT_C_IO,
1395 .group = FIO_OPT_G_IO_BASIC,
1396 },
214e1eca
JA
1397 {
1398 .name = "iodepth_low",
e8b0e958 1399 .lname = "IO Depth batch low",
214e1eca
JA
1400 .type = FIO_OPT_INT,
1401 .off1 = td_var_offset(iodepth_low),
1402 .help = "Low water mark for queuing depth",
afdf9352 1403 .parent = "iodepth",
d71c154c 1404 .hide = 1,
20eb06bd 1405 .interval = 1,
e8b0e958 1406 .category = FIO_OPT_C_IO,
0626037e 1407 .group = FIO_OPT_G_IO_BASIC,
214e1eca 1408 },
a9da8ab2
JA
1409 {
1410 .name = "io_submit_mode",
1411 .lname = "IO submit mode",
1412 .type = FIO_OPT_STR,
1413 .off1 = td_var_offset(io_submit_mode),
1414 .help = "How IO submissions and completions are done",
1415 .def = "inline",
1416 .category = FIO_OPT_C_IO,
1417 .group = FIO_OPT_G_IO_BASIC,
1418 .posval = {
1419 { .ival = "inline",
1420 .oval = IO_MODE_INLINE,
1421 .help = "Submit and complete IO inline",
1422 },
1423 { .ival = "offload",
1424 .oval = IO_MODE_OFFLOAD,
1425 .help = "Offload submit and complete to threads",
1426 },
1427 },
1428 },
214e1eca
JA
1429 {
1430 .name = "size",
e8b0e958 1431 .lname = "Size",
214e1eca 1432 .type = FIO_OPT_STR_VAL,
7bb59102 1433 .cb = str_size_cb,
a8523a6a 1434 .off1 = td_var_offset(size),
214e1eca 1435 .help = "Total size of device or files",
20eb06bd 1436 .interval = 1024 * 1024,
e8b0e958
JA
1437 .category = FIO_OPT_C_IO,
1438 .group = FIO_OPT_G_INVALID,
214e1eca 1439 },
77731b29 1440 {
a4d3b4db
JA
1441 .name = "io_size",
1442 .alias = "io_limit",
1443 .lname = "IO Size",
77731b29
JA
1444 .type = FIO_OPT_STR_VAL,
1445 .off1 = td_var_offset(io_limit),
1446 .interval = 1024 * 1024,
1447 .category = FIO_OPT_C_IO,
1448 .group = FIO_OPT_G_INVALID,
1449 },
aa31f1f1
SL
1450 {
1451 .name = "fill_device",
e8b0e958 1452 .lname = "Fill device",
74586c1e 1453 .alias = "fill_fs",
aa31f1f1
SL
1454 .type = FIO_OPT_BOOL,
1455 .off1 = td_var_offset(fill_device),
1456 .help = "Write until an ENOSPC error occurs",
1457 .def = "0",
e8b0e958
JA
1458 .category = FIO_OPT_C_FILE,
1459 .group = FIO_OPT_G_INVALID,
aa31f1f1 1460 },
214e1eca
JA
1461 {
1462 .name = "filesize",
e8b0e958 1463 .lname = "File size",
214e1eca
JA
1464 .type = FIO_OPT_STR_VAL,
1465 .off1 = td_var_offset(file_size_low),
1466 .off2 = td_var_offset(file_size_high),
c3edbdba 1467 .minval = 1,
214e1eca 1468 .help = "Size of individual files",
20eb06bd 1469 .interval = 1024 * 1024,
e8b0e958
JA
1470 .category = FIO_OPT_C_FILE,
1471 .group = FIO_OPT_G_INVALID,
214e1eca 1472 },
bedc9dc2
JA
1473 {
1474 .name = "file_append",
1475 .lname = "File append",
1476 .type = FIO_OPT_BOOL,
1477 .off1 = td_var_offset(file_append),
1478 .help = "IO will start at the end of the file(s)",
1479 .def = "0",
1480 .category = FIO_OPT_C_FILE,
1481 .group = FIO_OPT_G_INVALID,
1482 },
67a1000f
JA
1483 {
1484 .name = "offset",
e8b0e958 1485 .lname = "IO offset",
67a1000f
JA
1486 .alias = "fileoffset",
1487 .type = FIO_OPT_STR_VAL,
1488 .off1 = td_var_offset(start_offset),
1489 .help = "Start IO from this offset",
1490 .def = "0",
20eb06bd 1491 .interval = 1024 * 1024,
e8b0e958
JA
1492 .category = FIO_OPT_C_IO,
1493 .group = FIO_OPT_G_INVALID,
67a1000f 1494 },
2d7cd868
JA
1495 {
1496 .name = "offset_increment",
e8b0e958 1497 .lname = "IO offset increment",
2d7cd868
JA
1498 .type = FIO_OPT_STR_VAL,
1499 .off1 = td_var_offset(offset_increment),
1500 .help = "What is the increment from one offset to the next",
1501 .parent = "offset",
d71c154c 1502 .hide = 1,
2d7cd868 1503 .def = "0",
20eb06bd 1504 .interval = 1024 * 1024,
e8b0e958
JA
1505 .category = FIO_OPT_C_IO,
1506 .group = FIO_OPT_G_INVALID,
2d7cd868 1507 },
ddf24e42
JA
1508 {
1509 .name = "number_ios",
1510 .lname = "Number of IOs to perform",
1511 .type = FIO_OPT_STR_VAL,
1512 .off1 = td_var_offset(number_ios),
be3fec7d 1513 .help = "Force job completion after this number of IOs",
ddf24e42
JA
1514 .def = "0",
1515 .category = FIO_OPT_C_IO,
1516 .group = FIO_OPT_G_INVALID,
1517 },
214e1eca
JA
1518 {
1519 .name = "bs",
e8b0e958 1520 .lname = "Block size",
d3aad8f2 1521 .alias = "blocksize",
e01b22b8 1522 .type = FIO_OPT_INT,
214e1eca
JA
1523 .off1 = td_var_offset(bs[DDIR_READ]),
1524 .off2 = td_var_offset(bs[DDIR_WRITE]),
6eaf09d6 1525 .off3 = td_var_offset(bs[DDIR_TRIM]),
c3edbdba 1526 .minval = 1,
214e1eca
JA
1527 .help = "Block size unit",
1528 .def = "4k",
67a1000f 1529 .parent = "rw",
d71c154c 1530 .hide = 1,
20eb06bd 1531 .interval = 512,
e8b0e958
JA
1532 .category = FIO_OPT_C_IO,
1533 .group = FIO_OPT_G_INVALID,
214e1eca 1534 },
2b7a01d0
JA
1535 {
1536 .name = "ba",
e8b0e958 1537 .lname = "Block size align",
2b7a01d0 1538 .alias = "blockalign",
e01b22b8 1539 .type = FIO_OPT_INT,
2b7a01d0
JA
1540 .off1 = td_var_offset(ba[DDIR_READ]),
1541 .off2 = td_var_offset(ba[DDIR_WRITE]),
6eaf09d6 1542 .off3 = td_var_offset(ba[DDIR_TRIM]),
2b7a01d0
JA
1543 .minval = 1,
1544 .help = "IO block offset alignment",
1545 .parent = "rw",
d71c154c 1546 .hide = 1,
20eb06bd 1547 .interval = 512,
e8b0e958
JA
1548 .category = FIO_OPT_C_IO,
1549 .group = FIO_OPT_G_INVALID,
2b7a01d0 1550 },
214e1eca
JA
1551 {
1552 .name = "bsrange",
e8b0e958 1553 .lname = "Block size range",
d3aad8f2 1554 .alias = "blocksize_range",
214e1eca
JA
1555 .type = FIO_OPT_RANGE,
1556 .off1 = td_var_offset(min_bs[DDIR_READ]),
1557 .off2 = td_var_offset(max_bs[DDIR_READ]),
1558 .off3 = td_var_offset(min_bs[DDIR_WRITE]),
1559 .off4 = td_var_offset(max_bs[DDIR_WRITE]),
6eaf09d6
SL
1560 .off5 = td_var_offset(min_bs[DDIR_TRIM]),
1561 .off6 = td_var_offset(max_bs[DDIR_TRIM]),
c3edbdba 1562 .minval = 1,
214e1eca 1563 .help = "Set block size range (in more detail than bs)",
67a1000f 1564 .parent = "rw",
d71c154c 1565 .hide = 1,
20eb06bd 1566 .interval = 4096,
e8b0e958
JA
1567 .category = FIO_OPT_C_IO,
1568 .group = FIO_OPT_G_INVALID,
214e1eca 1569 },
564ca972
JA
1570 {
1571 .name = "bssplit",
e8b0e958 1572 .lname = "Block size split",
564ca972
JA
1573 .type = FIO_OPT_STR,
1574 .cb = str_bssplit_cb,
a8523a6a 1575 .off1 = td_var_offset(bssplit),
564ca972
JA
1576 .help = "Set a specific mix of block sizes",
1577 .parent = "rw",
d71c154c 1578 .hide = 1,
e8b0e958
JA
1579 .category = FIO_OPT_C_IO,
1580 .group = FIO_OPT_G_INVALID,
564ca972 1581 },
214e1eca
JA
1582 {
1583 .name = "bs_unaligned",
e8b0e958 1584 .lname = "Block size unaligned",
d3aad8f2 1585 .alias = "blocksize_unaligned",
214e1eca
JA
1586 .type = FIO_OPT_STR_SET,
1587 .off1 = td_var_offset(bs_unaligned),
1588 .help = "Don't sector align IO buffer sizes",
67a1000f 1589 .parent = "rw",
d71c154c 1590 .hide = 1,
e8b0e958
JA
1591 .category = FIO_OPT_C_IO,
1592 .group = FIO_OPT_G_INVALID,
214e1eca 1593 },
6aca9b3d
JA
1594 {
1595 .name = "bs_is_seq_rand",
1596 .lname = "Block size division is seq/random (not read/write)",
1597 .type = FIO_OPT_BOOL,
1598 .off1 = td_var_offset(bs_is_seq_rand),
86d59660 1599 .help = "Consider any blocksize setting to be sequential,random",
6aca9b3d
JA
1600 .def = "0",
1601 .parent = "blocksize",
1602 .category = FIO_OPT_C_IO,
1603 .group = FIO_OPT_G_INVALID,
1604 },
214e1eca
JA
1605 {
1606 .name = "randrepeat",
e8b0e958 1607 .lname = "Random repeatable",
214e1eca
JA
1608 .type = FIO_OPT_BOOL,
1609 .off1 = td_var_offset(rand_repeatable),
1610 .help = "Use repeatable random IO pattern",
1611 .def = "1",
67a1000f 1612 .parent = "rw",
d71c154c 1613 .hide = 1,
e8b0e958 1614 .category = FIO_OPT_C_IO,
3ceb458f 1615 .group = FIO_OPT_G_RANDOM,
214e1eca 1616 },
04778baf
JA
1617 {
1618 .name = "randseed",
1619 .lname = "The random generator seed",
363cffa7 1620 .type = FIO_OPT_STR_VAL,
04778baf
JA
1621 .off1 = td_var_offset(rand_seed),
1622 .help = "Set the random generator seed value",
40fe5e7b 1623 .def = "0x89",
04778baf
JA
1624 .parent = "rw",
1625 .category = FIO_OPT_C_IO,
1626 .group = FIO_OPT_G_RANDOM,
1627 },
2615cc4b
JA
1628 {
1629 .name = "use_os_rand",
e8b0e958 1630 .lname = "Use OS random",
54a21917
JA
1631 .type = FIO_OPT_DEPRECATED,
1632 .off1 = td_var_offset(dep_use_os_rand),
e8b0e958 1633 .category = FIO_OPT_C_IO,
3ceb458f 1634 .group = FIO_OPT_G_RANDOM,
2615cc4b 1635 },
214e1eca
JA
1636 {
1637 .name = "norandommap",
e8b0e958 1638 .lname = "No randommap",
214e1eca
JA
1639 .type = FIO_OPT_STR_SET,
1640 .off1 = td_var_offset(norandommap),
1641 .help = "Accept potential duplicate random blocks",
67a1000f 1642 .parent = "rw",
d71c154c 1643 .hide = 1,
b2452a43 1644 .hide_on_set = 1,
e8b0e958 1645 .category = FIO_OPT_C_IO,
3ceb458f 1646 .group = FIO_OPT_G_RANDOM,
214e1eca 1647 },
2b386d25
JA
1648 {
1649 .name = "softrandommap",
e8b0e958 1650 .lname = "Soft randommap",
2b386d25
JA
1651 .type = FIO_OPT_BOOL,
1652 .off1 = td_var_offset(softrandommap),
f66ab3c8 1653 .help = "Set norandommap if randommap allocation fails",
2b386d25 1654 .parent = "norandommap",
d71c154c 1655 .hide = 1,
2b386d25 1656 .def = "0",
e8b0e958 1657 .category = FIO_OPT_C_IO,
3ceb458f 1658 .group = FIO_OPT_G_RANDOM,
2b386d25 1659 },
8055e41d
JA
1660 {
1661 .name = "random_generator",
1662 .type = FIO_OPT_STR,
1663 .off1 = td_var_offset(random_generator),
1664 .help = "Type of random number generator to use",
1665 .def = "tausworthe",
1666 .posval = {
1667 { .ival = "tausworthe",
1668 .oval = FIO_RAND_GEN_TAUSWORTHE,
1669 .help = "Strong Tausworthe generator",
1670 },
1671 { .ival = "lfsr",
1672 .oval = FIO_RAND_GEN_LFSR,
1673 .help = "Variable length LFSR",
1674 },
c3546b53
JA
1675 {
1676 .ival = "tausworthe64",
1677 .oval = FIO_RAND_GEN_TAUSWORTHE64,
1678 .help = "64-bit Tausworthe variant",
1679 },
8055e41d 1680 },
48107598
JA
1681 .category = FIO_OPT_C_IO,
1682 .group = FIO_OPT_G_RANDOM,
8055e41d 1683 },
e25839d4
JA
1684 {
1685 .name = "random_distribution",
1686 .type = FIO_OPT_STR,
1687 .off1 = td_var_offset(random_distribution),
1688 .cb = str_random_distribution_cb,
1689 .help = "Random offset distribution generator",
1690 .def = "random",
1691 .posval = {
1692 { .ival = "random",
1693 .oval = FIO_RAND_DIST_RANDOM,
1694 .help = "Completely random",
1695 },
1696 { .ival = "zipf",
1697 .oval = FIO_RAND_DIST_ZIPF,
1698 .help = "Zipf distribution",
1699 },
925fee33
JA
1700 { .ival = "pareto",
1701 .oval = FIO_RAND_DIST_PARETO,
1702 .help = "Pareto distribution",
1703 },
56d9fa4b
JA
1704 { .ival = "normal",
1705 .oval = FIO_RAND_DIST_GAUSS,
1706 .help = "Normal (gaussian) distribution",
1707 },
e25839d4 1708 },
48107598
JA
1709 .category = FIO_OPT_C_IO,
1710 .group = FIO_OPT_G_RANDOM,
e25839d4 1711 },
211c9b89
JA
1712 {
1713 .name = "percentage_random",
1714 .lname = "Percentage Random",
1715 .type = FIO_OPT_INT,
d9472271
JA
1716 .off1 = td_var_offset(perc_rand[DDIR_READ]),
1717 .off2 = td_var_offset(perc_rand[DDIR_WRITE]),
1718 .off3 = td_var_offset(perc_rand[DDIR_TRIM]),
211c9b89
JA
1719 .maxval = 100,
1720 .help = "Percentage of seq/random mix that should be random",
d9472271 1721 .def = "100,100,100",
211c9b89
JA
1722 .interval = 5,
1723 .inverse = "percentage_sequential",
1724 .category = FIO_OPT_C_IO,
1725 .group = FIO_OPT_G_RANDOM,
1726 },
1727 {
1728 .name = "percentage_sequential",
1729 .lname = "Percentage Sequential",
d9472271 1730 .type = FIO_OPT_DEPRECATED,
211c9b89
JA
1731 .category = FIO_OPT_C_IO,
1732 .group = FIO_OPT_G_RANDOM,
1733 },
56e2a5fc
CE
1734 {
1735 .name = "allrandrepeat",
1736 .type = FIO_OPT_BOOL,
1737 .off1 = td_var_offset(allrand_repeatable),
1738 .help = "Use repeatable random numbers for everything",
1739 .def = "0",
a869d9c6
JA
1740 .category = FIO_OPT_C_IO,
1741 .group = FIO_OPT_G_RANDOM,
56e2a5fc 1742 },
214e1eca
JA
1743 {
1744 .name = "nrfiles",
e8b0e958 1745 .lname = "Number of files",
d7c8be03 1746 .alias = "nr_files",
214e1eca
JA
1747 .type = FIO_OPT_INT,
1748 .off1 = td_var_offset(nr_files),
1749 .help = "Split job workload between this number of files",
1750 .def = "1",
20eb06bd 1751 .interval = 1,
e8b0e958
JA
1752 .category = FIO_OPT_C_FILE,
1753 .group = FIO_OPT_G_INVALID,
214e1eca
JA
1754 },
1755 {
1756 .name = "openfiles",
e8b0e958 1757 .lname = "Number of open files",
214e1eca
JA
1758 .type = FIO_OPT_INT,
1759 .off1 = td_var_offset(open_files),
1760 .help = "Number of files to keep open at the same time",
e8b0e958
JA
1761 .category = FIO_OPT_C_FILE,
1762 .group = FIO_OPT_G_INVALID,
214e1eca
JA
1763 },
1764 {
1765 .name = "file_service_type",
e8b0e958 1766 .lname = "File service type",
214e1eca
JA
1767 .type = FIO_OPT_STR,
1768 .cb = str_fst_cb,
1769 .off1 = td_var_offset(file_service_type),
1770 .help = "How to select which file to service next",
1771 .def = "roundrobin",
e8b0e958
JA
1772 .category = FIO_OPT_C_FILE,
1773 .group = FIO_OPT_G_INVALID,
214e1eca
JA
1774 .posval = {
1775 { .ival = "random",
1776 .oval = FIO_FSERVICE_RANDOM,
1777 .help = "Choose a file at random",
1778 },
1779 { .ival = "roundrobin",
1780 .oval = FIO_FSERVICE_RR,
1781 .help = "Round robin select files",
1782 },
a086c257
JA
1783 { .ival = "sequential",
1784 .oval = FIO_FSERVICE_SEQ,
1785 .help = "Finish one file before moving to the next",
1786 },
214e1eca 1787 },
67a1000f 1788 .parent = "nrfiles",
d71c154c 1789 .hide = 1,
67a1000f 1790 },
97ac992c 1791#ifdef CONFIG_POSIX_FALLOCATE
7bc8c2cf
JA
1792 {
1793 .name = "fallocate",
e8b0e958 1794 .lname = "Fallocate",
a596f047
EG
1795 .type = FIO_OPT_STR,
1796 .off1 = td_var_offset(fallocate_mode),
1797 .help = "Whether pre-allocation is performed when laying out files",
1798 .def = "posix",
e8b0e958
JA
1799 .category = FIO_OPT_C_FILE,
1800 .group = FIO_OPT_G_INVALID,
a596f047
EG
1801 .posval = {
1802 { .ival = "none",
1803 .oval = FIO_FALLOCATE_NONE,
1804 .help = "Do not pre-allocate space",
1805 },
1806 { .ival = "posix",
1807 .oval = FIO_FALLOCATE_POSIX,
1808 .help = "Use posix_fallocate()",
1809 },
97ac992c 1810#ifdef CONFIG_LINUX_FALLOCATE
a596f047
EG
1811 { .ival = "keep",
1812 .oval = FIO_FALLOCATE_KEEP_SIZE,
1813 .help = "Use fallocate(..., FALLOC_FL_KEEP_SIZE, ...)",
1814 },
7bc8c2cf 1815#endif
a596f047
EG
1816 /* Compatibility with former boolean values */
1817 { .ival = "0",
1818 .oval = FIO_FALLOCATE_NONE,
1819 .help = "Alias for 'none'",
1820 },
1821 { .ival = "1",
1822 .oval = FIO_FALLOCATE_POSIX,
1823 .help = "Alias for 'posix'",
1824 },
1825 },
1826 },
97ac992c 1827#endif /* CONFIG_POSIX_FALLOCATE */
67a1000f
JA
1828 {
1829 .name = "fadvise_hint",
e8b0e958 1830 .lname = "Fadvise hint",
67a1000f
JA
1831 .type = FIO_OPT_BOOL,
1832 .off1 = td_var_offset(fadvise_hint),
1833 .help = "Use fadvise() to advise the kernel on IO pattern",
1834 .def = "1",
e8b0e958
JA
1835 .category = FIO_OPT_C_FILE,
1836 .group = FIO_OPT_G_INVALID,
214e1eca 1837 },
37659335
JA
1838#ifdef FIO_HAVE_STREAMID
1839 {
1840 .name = "fadvise_stream",
1841 .lname = "Fadvise stream",
1842 .type = FIO_OPT_INT,
1843 .off1 = td_var_offset(fadvise_stream),
1844 .help = "Use fadvise() to set stream ID",
1845 .category = FIO_OPT_C_FILE,
1846 .group = FIO_OPT_G_INVALID,
1847 },
1848#endif
214e1eca
JA
1849 {
1850 .name = "fsync",
e8b0e958 1851 .lname = "Fsync",
214e1eca
JA
1852 .type = FIO_OPT_INT,
1853 .off1 = td_var_offset(fsync_blocks),
1854 .help = "Issue fsync for writes every given number of blocks",
1855 .def = "0",
20eb06bd 1856 .interval = 1,
e8b0e958
JA
1857 .category = FIO_OPT_C_FILE,
1858 .group = FIO_OPT_G_INVALID,
214e1eca 1859 },
5f9099ea
JA
1860 {
1861 .name = "fdatasync",
e8b0e958 1862 .lname = "Fdatasync",
5f9099ea
JA
1863 .type = FIO_OPT_INT,
1864 .off1 = td_var_offset(fdatasync_blocks),
1865 .help = "Issue fdatasync for writes every given number of blocks",
1866 .def = "0",
20eb06bd 1867 .interval = 1,
e8b0e958
JA
1868 .category = FIO_OPT_C_FILE,
1869 .group = FIO_OPT_G_INVALID,
5f9099ea 1870 },
1ef2b6be
JA
1871 {
1872 .name = "write_barrier",
e8b0e958 1873 .lname = "Write barrier",
1ef2b6be
JA
1874 .type = FIO_OPT_INT,
1875 .off1 = td_var_offset(barrier_blocks),
1876 .help = "Make every Nth write a barrier write",
1877 .def = "0",
20eb06bd 1878 .interval = 1,
e8b0e958
JA
1879 .category = FIO_OPT_C_IO,
1880 .group = FIO_OPT_G_INVALID,
1ef2b6be 1881 },
67bf9823 1882#ifdef CONFIG_SYNC_FILE_RANGE
44f29692
JA
1883 {
1884 .name = "sync_file_range",
e8b0e958 1885 .lname = "Sync file range",
44f29692
JA
1886 .posval = {
1887 { .ival = "wait_before",
1888 .oval = SYNC_FILE_RANGE_WAIT_BEFORE,
1889 .help = "SYNC_FILE_RANGE_WAIT_BEFORE",
ebadc0ce 1890 .orval = 1,
44f29692
JA
1891 },
1892 { .ival = "write",
1893 .oval = SYNC_FILE_RANGE_WRITE,
1894 .help = "SYNC_FILE_RANGE_WRITE",
ebadc0ce 1895 .orval = 1,
44f29692
JA
1896 },
1897 {
1898 .ival = "wait_after",
1899 .oval = SYNC_FILE_RANGE_WAIT_AFTER,
1900 .help = "SYNC_FILE_RANGE_WAIT_AFTER",
ebadc0ce 1901 .orval = 1,
44f29692
JA
1902 },
1903 },
3843deb3 1904 .type = FIO_OPT_STR_MULTI,
44f29692
JA
1905 .cb = str_sfr_cb,
1906 .off1 = td_var_offset(sync_file_range),
1907 .help = "Use sync_file_range()",
e8b0e958
JA
1908 .category = FIO_OPT_C_FILE,
1909 .group = FIO_OPT_G_INVALID,
44f29692
JA
1910 },
1911#endif
214e1eca
JA
1912 {
1913 .name = "direct",
e8b0e958 1914 .lname = "Direct I/O",
214e1eca
JA
1915 .type = FIO_OPT_BOOL,
1916 .off1 = td_var_offset(odirect),
1917 .help = "Use O_DIRECT IO (negates buffered)",
1918 .def = "0",
a01a1bc5 1919 .inverse = "buffered",
e8b0e958 1920 .category = FIO_OPT_C_IO,
3ceb458f 1921 .group = FIO_OPT_G_IO_TYPE,
214e1eca 1922 },
d01612f3
CM
1923 {
1924 .name = "atomic",
1925 .lname = "Atomic I/O",
1926 .type = FIO_OPT_BOOL,
1927 .off1 = td_var_offset(oatomic),
1928 .help = "Use Atomic IO with O_DIRECT (implies O_DIRECT)",
1929 .def = "0",
1930 .category = FIO_OPT_C_IO,
1931 .group = FIO_OPT_G_IO_TYPE,
1932 },
214e1eca
JA
1933 {
1934 .name = "buffered",
e8b0e958 1935 .lname = "Buffered I/O",
214e1eca
JA
1936 .type = FIO_OPT_BOOL,
1937 .off1 = td_var_offset(odirect),
1938 .neg = 1,
1939 .help = "Use buffered IO (negates direct)",
1940 .def = "1",
a01a1bc5 1941 .inverse = "direct",
e8b0e958 1942 .category = FIO_OPT_C_IO,
3ceb458f 1943 .group = FIO_OPT_G_IO_TYPE,
214e1eca
JA
1944 },
1945 {
1946 .name = "overwrite",
e8b0e958 1947 .lname = "Overwrite",
214e1eca
JA
1948 .type = FIO_OPT_BOOL,
1949 .off1 = td_var_offset(overwrite),
1950 .help = "When writing, set whether to overwrite current data",
1951 .def = "0",
e8b0e958
JA
1952 .category = FIO_OPT_C_FILE,
1953 .group = FIO_OPT_G_INVALID,
214e1eca
JA
1954 },
1955 {
1956 .name = "loops",
e8b0e958 1957 .lname = "Loops",
214e1eca
JA
1958 .type = FIO_OPT_INT,
1959 .off1 = td_var_offset(loops),
1960 .help = "Number of times to run the job",
1961 .def = "1",
20eb06bd 1962 .interval = 1,
e8b0e958 1963 .category = FIO_OPT_C_GENERAL,
a1f6afec 1964 .group = FIO_OPT_G_RUNTIME,
214e1eca
JA
1965 },
1966 {
1967 .name = "numjobs",
e8b0e958 1968 .lname = "Number of jobs",
214e1eca
JA
1969 .type = FIO_OPT_INT,
1970 .off1 = td_var_offset(numjobs),
1971 .help = "Duplicate this job this many times",
1972 .def = "1",
20eb06bd 1973 .interval = 1,
e8b0e958 1974 .category = FIO_OPT_C_GENERAL,
a1f6afec 1975 .group = FIO_OPT_G_RUNTIME,
214e1eca
JA
1976 },
1977 {
1978 .name = "startdelay",
e8b0e958 1979 .lname = "Start delay",
a5737c93 1980 .type = FIO_OPT_STR_VAL_TIME,
214e1eca 1981 .off1 = td_var_offset(start_delay),
23ed19b0 1982 .off2 = td_var_offset(start_delay_high),
214e1eca
JA
1983 .help = "Only start job when this period has passed",
1984 .def = "0",
0de5b26f 1985 .is_seconds = 1,
88038bc7 1986 .is_time = 1,
e8b0e958 1987 .category = FIO_OPT_C_GENERAL,
a1f6afec 1988 .group = FIO_OPT_G_RUNTIME,
214e1eca
JA
1989 },
1990 {
1991 .name = "runtime",
e8b0e958 1992 .lname = "Runtime",
214e1eca
JA
1993 .alias = "timeout",
1994 .type = FIO_OPT_STR_VAL_TIME,
1995 .off1 = td_var_offset(timeout),
1996 .help = "Stop workload when this amount of time has passed",
1997 .def = "0",
0de5b26f 1998 .is_seconds = 1,
88038bc7 1999 .is_time = 1,
e8b0e958 2000 .category = FIO_OPT_C_GENERAL,
a1f6afec 2001 .group = FIO_OPT_G_RUNTIME,
214e1eca 2002 },
cf4464ca
JA
2003 {
2004 .name = "time_based",
e8b0e958 2005 .lname = "Time based",
cf4464ca
JA
2006 .type = FIO_OPT_STR_SET,
2007 .off1 = td_var_offset(time_based),
2008 .help = "Keep running until runtime/timeout is met",
e8b0e958 2009 .category = FIO_OPT_C_GENERAL,
a1f6afec 2010 .group = FIO_OPT_G_RUNTIME,
cf4464ca 2011 },
62167762
JC
2012 {
2013 .name = "verify_only",
2014 .lname = "Verify only",
2015 .type = FIO_OPT_STR_SET,
2016 .off1 = td_var_offset(verify_only),
2017 .help = "Verifies previously written data is still valid",
2018 .category = FIO_OPT_C_GENERAL,
2019 .group = FIO_OPT_G_RUNTIME,
2020 },
721938ae
JA
2021 {
2022 .name = "ramp_time",
e8b0e958 2023 .lname = "Ramp time",
721938ae
JA
2024 .type = FIO_OPT_STR_VAL_TIME,
2025 .off1 = td_var_offset(ramp_time),
2026 .help = "Ramp up time before measuring performance",
0de5b26f 2027 .is_seconds = 1,
88038bc7 2028 .is_time = 1,
e8b0e958 2029 .category = FIO_OPT_C_GENERAL,
a1f6afec 2030 .group = FIO_OPT_G_RUNTIME,
721938ae 2031 },
c223da83
JA
2032 {
2033 .name = "clocksource",
e8b0e958 2034 .lname = "Clock source",
c223da83
JA
2035 .type = FIO_OPT_STR,
2036 .cb = fio_clock_source_cb,
2037 .off1 = td_var_offset(clocksource),
2038 .help = "What type of timing source to use",
e8b0e958 2039 .category = FIO_OPT_C_GENERAL,
10860056 2040 .group = FIO_OPT_G_CLOCK,
c223da83 2041 .posval = {
67bf9823 2042#ifdef CONFIG_GETTIMEOFDAY
c223da83
JA
2043 { .ival = "gettimeofday",
2044 .oval = CS_GTOD,
2045 .help = "Use gettimeofday(2) for timing",
2046 },
67bf9823
JA
2047#endif
2048#ifdef CONFIG_CLOCK_GETTIME
c223da83
JA
2049 { .ival = "clock_gettime",
2050 .oval = CS_CGETTIME,
2051 .help = "Use clock_gettime(2) for timing",
2052 },
67bf9823 2053#endif
c223da83
JA
2054#ifdef ARCH_HAVE_CPU_CLOCK
2055 { .ival = "cpu",
2056 .oval = CS_CPUCLOCK,
2057 .help = "Use CPU private clock",
2058 },
2059#endif
2060 },
2061 },
214e1eca
JA
2062 {
2063 .name = "mem",
d3aad8f2 2064 .alias = "iomem",
e8b0e958 2065 .lname = "I/O Memory",
214e1eca
JA
2066 .type = FIO_OPT_STR,
2067 .cb = str_mem_cb,
2068 .off1 = td_var_offset(mem_type),
2069 .help = "Backing type for IO buffers",
2070 .def = "malloc",
e8b0e958
JA
2071 .category = FIO_OPT_C_IO,
2072 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2073 .posval = {
2074 { .ival = "malloc",
2075 .oval = MEM_MALLOC,
2076 .help = "Use malloc(3) for IO buffers",
2077 },
c8931876 2078#ifndef CONFIG_NO_SHM
37c8cdfe
JA
2079 { .ival = "shm",
2080 .oval = MEM_SHM,
2081 .help = "Use shared memory segments for IO buffers",
2082 },
214e1eca
JA
2083#ifdef FIO_HAVE_HUGETLB
2084 { .ival = "shmhuge",
2085 .oval = MEM_SHMHUGE,
2086 .help = "Like shm, but use huge pages",
2087 },
c8931876 2088#endif
b370e46a 2089#endif
37c8cdfe
JA
2090 { .ival = "mmap",
2091 .oval = MEM_MMAP,
2092 .help = "Use mmap(2) (file or anon) for IO buffers",
2093 },
217b0f1d
LG
2094 { .ival = "mmapshared",
2095 .oval = MEM_MMAPSHARED,
2096 .help = "Like mmap, but use the shared flag",
2097 },
214e1eca
JA
2098#ifdef FIO_HAVE_HUGETLB
2099 { .ival = "mmaphuge",
2100 .oval = MEM_MMAPHUGE,
2101 .help = "Like mmap, but use huge pages",
2102 },
2103#endif
2104 },
2105 },
d529ee19
JA
2106 {
2107 .name = "iomem_align",
2108 .alias = "mem_align",
e8b0e958 2109 .lname = "I/O memory alignment",
d529ee19
JA
2110 .type = FIO_OPT_INT,
2111 .off1 = td_var_offset(mem_align),
2112 .minval = 0,
2113 .help = "IO memory buffer offset alignment",
2114 .def = "0",
2115 .parent = "iomem",
d71c154c 2116 .hide = 1,
e8b0e958
JA
2117 .category = FIO_OPT_C_IO,
2118 .group = FIO_OPT_G_INVALID,
d529ee19 2119 },
214e1eca
JA
2120 {
2121 .name = "verify",
e8b0e958 2122 .lname = "Verify",
214e1eca
JA
2123 .type = FIO_OPT_STR,
2124 .off1 = td_var_offset(verify),
2125 .help = "Verify data written",
2126 .def = "0",
e8b0e958 2127 .category = FIO_OPT_C_IO,
3ceb458f 2128 .group = FIO_OPT_G_VERIFY,
214e1eca
JA
2129 .posval = {
2130 { .ival = "0",
2131 .oval = VERIFY_NONE,
2132 .help = "Don't do IO verification",
2133 },
fcca4b58
JA
2134 { .ival = "md5",
2135 .oval = VERIFY_MD5,
2136 .help = "Use md5 checksums for verification",
2137 },
d77a7af3
JA
2138 { .ival = "crc64",
2139 .oval = VERIFY_CRC64,
2140 .help = "Use crc64 checksums for verification",
2141 },
214e1eca
JA
2142 { .ival = "crc32",
2143 .oval = VERIFY_CRC32,
2144 .help = "Use crc32 checksums for verification",
2145 },
af497e6a 2146 { .ival = "crc32c-intel",
e3aaafc4
JA
2147 .oval = VERIFY_CRC32C,
2148 .help = "Use crc32c checksums for verification (hw assisted, if available)",
af497e6a 2149 },
bac39e0e
JA
2150 { .ival = "crc32c",
2151 .oval = VERIFY_CRC32C,
e3aaafc4 2152 .help = "Use crc32c checksums for verification (hw assisted, if available)",
bac39e0e 2153 },
969f7ed3
JA
2154 { .ival = "crc16",
2155 .oval = VERIFY_CRC16,
2156 .help = "Use crc16 checksums for verification",
2157 },
1e154bdb
JA
2158 { .ival = "crc7",
2159 .oval = VERIFY_CRC7,
2160 .help = "Use crc7 checksums for verification",
2161 },
7c353ceb
JA
2162 { .ival = "sha1",
2163 .oval = VERIFY_SHA1,
2164 .help = "Use sha1 checksums for verification",
2165 },
cd14cc10
JA
2166 { .ival = "sha256",
2167 .oval = VERIFY_SHA256,
2168 .help = "Use sha256 checksums for verification",
2169 },
2170 { .ival = "sha512",
2171 .oval = VERIFY_SHA512,
2172 .help = "Use sha512 checksums for verification",
2173 },
844ea602
JA
2174 { .ival = "xxhash",
2175 .oval = VERIFY_XXHASH,
2176 .help = "Use xxhash checksums for verification",
2177 },
b638d82f
RP
2178 /* Meta information was included into verify_header,
2179 * 'meta' verification is implied by default. */
7437ee87 2180 { .ival = "meta",
b638d82f
RP
2181 .oval = VERIFY_HDR_ONLY,
2182 .help = "Use io information for verification. "
2183 "Now is implied by default, thus option is obsolete, "
2184 "don't use it",
7437ee87 2185 },
59245381
JA
2186 { .ival = "pattern",
2187 .oval = VERIFY_PATTERN_NO_HDR,
2188 .help = "Verify strict pattern",
2189 },
36690c9b
JA
2190 {
2191 .ival = "null",
2192 .oval = VERIFY_NULL,
2193 .help = "Pretend to verify",
2194 },
214e1eca
JA
2195 },
2196 },
005c565a
JA
2197 {
2198 .name = "do_verify",
e8b0e958 2199 .lname = "Perform verify step",
68e1f29a 2200 .type = FIO_OPT_BOOL,
005c565a
JA
2201 .off1 = td_var_offset(do_verify),
2202 .help = "Run verification stage after write",
2203 .def = "1",
2204 .parent = "verify",
d71c154c 2205 .hide = 1,
e8b0e958
JA
2206 .category = FIO_OPT_C_IO,
2207 .group = FIO_OPT_G_VERIFY,
005c565a 2208 },
160b966d
JA
2209 {
2210 .name = "verifysort",
e8b0e958 2211 .lname = "Verify sort",
160b966d
JA
2212 .type = FIO_OPT_BOOL,
2213 .off1 = td_var_offset(verifysort),
2214 .help = "Sort written verify blocks for read back",
2215 .def = "1",
c83f2df1 2216 .parent = "verify",
d71c154c 2217 .hide = 1,
e8b0e958
JA
2218 .category = FIO_OPT_C_IO,
2219 .group = FIO_OPT_G_VERIFY,
160b966d 2220 },
1ae83d45
JA
2221 {
2222 .name = "verifysort_nr",
2223 .type = FIO_OPT_INT,
2224 .off1 = td_var_offset(verifysort_nr),
2225 .help = "Pre-load and sort verify blocks for a read workload",
2226 .minval = 0,
2227 .maxval = 131072,
2228 .def = "1024",
2229 .parent = "verify",
836fcc0f
JA
2230 .category = FIO_OPT_C_IO,
2231 .group = FIO_OPT_G_VERIFY,
1ae83d45 2232 },
3f9f4e26 2233 {
a59e170d 2234 .name = "verify_interval",
e8b0e958 2235 .lname = "Verify interval",
e01b22b8 2236 .type = FIO_OPT_INT,
a59e170d 2237 .off1 = td_var_offset(verify_interval),
819a9680 2238 .minval = 2 * sizeof(struct verify_header),
a59e170d 2239 .help = "Store verify buffer header every N bytes",
afdf9352 2240 .parent = "verify",
d71c154c 2241 .hide = 1,
20eb06bd 2242 .interval = 2 * sizeof(struct verify_header),
e8b0e958
JA
2243 .category = FIO_OPT_C_IO,
2244 .group = FIO_OPT_G_VERIFY,
3f9f4e26 2245 },
546a9142 2246 {
a59e170d 2247 .name = "verify_offset",
e8b0e958 2248 .lname = "Verify offset",
e01b22b8 2249 .type = FIO_OPT_INT,
a59e170d 2250 .help = "Offset verify header location by N bytes",
203160d5
JA
2251 .off1 = td_var_offset(verify_offset),
2252 .minval = sizeof(struct verify_header),
afdf9352 2253 .parent = "verify",
d71c154c 2254 .hide = 1,
e8b0e958
JA
2255 .category = FIO_OPT_C_IO,
2256 .group = FIO_OPT_G_VERIFY,
546a9142 2257 },
e28218f3
SL
2258 {
2259 .name = "verify_pattern",
e8b0e958 2260 .lname = "Verify pattern",
0e92f873 2261 .type = FIO_OPT_STR,
e28218f3 2262 .cb = str_verify_pattern_cb,
a8523a6a 2263 .off1 = td_var_offset(verify_pattern),
e28218f3
SL
2264 .help = "Fill pattern for IO buffers",
2265 .parent = "verify",
d71c154c 2266 .hide = 1,
e8b0e958
JA
2267 .category = FIO_OPT_C_IO,
2268 .group = FIO_OPT_G_VERIFY,
e28218f3 2269 },
a12a3b4d
JA
2270 {
2271 .name = "verify_fatal",
e8b0e958 2272 .lname = "Verify fatal",
68e1f29a 2273 .type = FIO_OPT_BOOL,
a12a3b4d
JA
2274 .off1 = td_var_offset(verify_fatal),
2275 .def = "0",
2276 .help = "Exit on a single verify failure, don't continue",
2277 .parent = "verify",
d71c154c 2278 .hide = 1,
e8b0e958
JA
2279 .category = FIO_OPT_C_IO,
2280 .group = FIO_OPT_G_VERIFY,
a12a3b4d 2281 },
b463e936
JA
2282 {
2283 .name = "verify_dump",
e8b0e958 2284 .lname = "Verify dump",
b463e936
JA
2285 .type = FIO_OPT_BOOL,
2286 .off1 = td_var_offset(verify_dump),
ef71e317 2287 .def = "0",
b463e936
JA
2288 .help = "Dump contents of good and bad blocks on failure",
2289 .parent = "verify",
d71c154c 2290 .hide = 1,
e8b0e958
JA
2291 .category = FIO_OPT_C_IO,
2292 .group = FIO_OPT_G_VERIFY,
b463e936 2293 },
e8462bd8
JA
2294 {
2295 .name = "verify_async",
e8b0e958 2296 .lname = "Verify asynchronously",
e8462bd8
JA
2297 .type = FIO_OPT_INT,
2298 .off1 = td_var_offset(verify_async),
2299 .def = "0",
2300 .help = "Number of async verifier threads to use",
2301 .parent = "verify",
d71c154c 2302 .hide = 1,
e8b0e958
JA
2303 .category = FIO_OPT_C_IO,
2304 .group = FIO_OPT_G_VERIFY,
e8462bd8 2305 },
9e144189
JA
2306 {
2307 .name = "verify_backlog",
e8b0e958 2308 .lname = "Verify backlog",
9e144189
JA
2309 .type = FIO_OPT_STR_VAL,
2310 .off1 = td_var_offset(verify_backlog),
2311 .help = "Verify after this number of blocks are written",
2312 .parent = "verify",
d71c154c 2313 .hide = 1,
e8b0e958
JA
2314 .category = FIO_OPT_C_IO,
2315 .group = FIO_OPT_G_VERIFY,
9e144189
JA
2316 },
2317 {
2318 .name = "verify_backlog_batch",
e8b0e958 2319 .lname = "Verify backlog batch",
9e144189
JA
2320 .type = FIO_OPT_INT,
2321 .off1 = td_var_offset(verify_batch),
2322 .help = "Verify this number of IO blocks",
0d29de83 2323 .parent = "verify",
d71c154c 2324 .hide = 1,
e8b0e958
JA
2325 .category = FIO_OPT_C_IO,
2326 .group = FIO_OPT_G_VERIFY,
9e144189 2327 },
e8462bd8
JA
2328#ifdef FIO_HAVE_CPU_AFFINITY
2329 {
2330 .name = "verify_async_cpus",
e8b0e958 2331 .lname = "Async verify CPUs",
e8462bd8
JA
2332 .type = FIO_OPT_STR,
2333 .cb = str_verify_cpus_allowed_cb,
a8523a6a 2334 .off1 = td_var_offset(verify_cpumask),
e8462bd8
JA
2335 .help = "Set CPUs allowed for async verify threads",
2336 .parent = "verify_async",
d71c154c 2337 .hide = 1,
e8b0e958
JA
2338 .category = FIO_OPT_C_IO,
2339 .group = FIO_OPT_G_VERIFY,
e8462bd8 2340 },
0d29de83 2341#endif
51aa2da8
JA
2342 {
2343 .name = "experimental_verify",
2344 .off1 = td_var_offset(experimental_verify),
2345 .type = FIO_OPT_BOOL,
b31eaac9 2346 .help = "Enable experimental verification",
ca09be4b
JA
2347 .parent = "verify",
2348 .category = FIO_OPT_C_IO,
2349 .group = FIO_OPT_G_VERIFY,
2350 },
2351 {
2352 .name = "verify_state_load",
2353 .lname = "Load verify state",
2354 .off1 = td_var_offset(verify_state),
2355 .type = FIO_OPT_BOOL,
2356 .help = "Load verify termination state",
2357 .parent = "verify",
2358 .category = FIO_OPT_C_IO,
2359 .group = FIO_OPT_G_VERIFY,
2360 },
2361 {
2362 .name = "verify_state_save",
2363 .lname = "Save verify state",
2364 .off1 = td_var_offset(verify_state_save),
2365 .type = FIO_OPT_BOOL,
2366 .def = "1",
2367 .help = "Save verify state on termination",
2368 .parent = "verify",
836fcc0f
JA
2369 .category = FIO_OPT_C_IO,
2370 .group = FIO_OPT_G_VERIFY,
51aa2da8 2371 },
0d29de83
JA
2372#ifdef FIO_HAVE_TRIM
2373 {
2374 .name = "trim_percentage",
e8b0e958 2375 .lname = "Trim percentage",
0d29de83 2376 .type = FIO_OPT_INT,
203160d5 2377 .off1 = td_var_offset(trim_percentage),
20eb06bd 2378 .minval = 0,
0d29de83
JA
2379 .maxval = 100,
2380 .help = "Number of verify blocks to discard/trim",
2381 .parent = "verify",
2382 .def = "0",
20eb06bd 2383 .interval = 1,
d71c154c 2384 .hide = 1,
e8b0e958
JA
2385 .category = FIO_OPT_C_IO,
2386 .group = FIO_OPT_G_TRIM,
0d29de83
JA
2387 },
2388 {
2389 .name = "trim_verify_zero",
e8b0e958 2390 .lname = "Verify trim zero",
20eb06bd 2391 .type = FIO_OPT_BOOL,
0d29de83
JA
2392 .help = "Verify that trim/discarded blocks are returned as zeroes",
2393 .off1 = td_var_offset(trim_zero),
2394 .parent = "trim_percentage",
d71c154c 2395 .hide = 1,
0d29de83 2396 .def = "1",
e8b0e958
JA
2397 .category = FIO_OPT_C_IO,
2398 .group = FIO_OPT_G_TRIM,
0d29de83
JA
2399 },
2400 {
2401 .name = "trim_backlog",
e8b0e958 2402 .lname = "Trim backlog",
0d29de83
JA
2403 .type = FIO_OPT_STR_VAL,
2404 .off1 = td_var_offset(trim_backlog),
2405 .help = "Trim after this number of blocks are written",
2406 .parent = "trim_percentage",
d71c154c 2407 .hide = 1,
20eb06bd 2408 .interval = 1,
e8b0e958
JA
2409 .category = FIO_OPT_C_IO,
2410 .group = FIO_OPT_G_TRIM,
0d29de83
JA
2411 },
2412 {
2413 .name = "trim_backlog_batch",
e8b0e958 2414 .lname = "Trim backlog batch",
0d29de83
JA
2415 .type = FIO_OPT_INT,
2416 .off1 = td_var_offset(trim_batch),
2417 .help = "Trim this number of IO blocks",
2418 .parent = "trim_percentage",
d71c154c 2419 .hide = 1,
20eb06bd 2420 .interval = 1,
e8b0e958
JA
2421 .category = FIO_OPT_C_IO,
2422 .group = FIO_OPT_G_TRIM,
0d29de83 2423 },
e8462bd8 2424#endif
214e1eca
JA
2425 {
2426 .name = "write_iolog",
e8b0e958 2427 .lname = "Write I/O log",
214e1eca
JA
2428 .type = FIO_OPT_STR_STORE,
2429 .off1 = td_var_offset(write_iolog_file),
2430 .help = "Store IO pattern to file",
e8b0e958
JA
2431 .category = FIO_OPT_C_IO,
2432 .group = FIO_OPT_G_IOLOG,
214e1eca
JA
2433 },
2434 {
2435 .name = "read_iolog",
e8b0e958 2436 .lname = "Read I/O log",
214e1eca
JA
2437 .type = FIO_OPT_STR_STORE,
2438 .off1 = td_var_offset(read_iolog_file),
2439 .help = "Playback IO pattern from file",
e8b0e958
JA
2440 .category = FIO_OPT_C_IO,
2441 .group = FIO_OPT_G_IOLOG,
214e1eca 2442 },
64bbb865
DN
2443 {
2444 .name = "replay_no_stall",
e8b0e958 2445 .lname = "Don't stall on replay",
20eb06bd 2446 .type = FIO_OPT_BOOL,
64bbb865
DN
2447 .off1 = td_var_offset(no_stall),
2448 .def = "0",
87e7a972 2449 .parent = "read_iolog",
d71c154c 2450 .hide = 1,
64bbb865 2451 .help = "Playback IO pattern file as fast as possible without stalls",
e8b0e958
JA
2452 .category = FIO_OPT_C_IO,
2453 .group = FIO_OPT_G_IOLOG,
64bbb865 2454 },
d1c46c04
DN
2455 {
2456 .name = "replay_redirect",
e8b0e958 2457 .lname = "Redirect device for replay",
d1c46c04
DN
2458 .type = FIO_OPT_STR_STORE,
2459 .off1 = td_var_offset(replay_redirect),
2460 .parent = "read_iolog",
d71c154c 2461 .hide = 1,
d1c46c04 2462 .help = "Replay all I/O onto this device, regardless of trace device",
e8b0e958
JA
2463 .category = FIO_OPT_C_IO,
2464 .group = FIO_OPT_G_IOLOG,
d1c46c04 2465 },
0c63576e
JA
2466 {
2467 .name = "replay_scale",
2468 .lname = "Replace offset scale factor",
2469 .type = FIO_OPT_INT,
2470 .off1 = td_var_offset(replay_scale),
2471 .parent = "read_iolog",
2472 .def = "1",
2473 .help = "Align offsets to this blocksize",
2474 .category = FIO_OPT_C_IO,
2475 .group = FIO_OPT_G_IOLOG,
2476 },
2477 {
2478 .name = "replay_align",
2479 .lname = "Replace alignment",
2480 .type = FIO_OPT_INT,
2481 .off1 = td_var_offset(replay_align),
2482 .parent = "read_iolog",
2483 .help = "Scale offset down by this factor",
2484 .category = FIO_OPT_C_IO,
2485 .group = FIO_OPT_G_IOLOG,
2486 .pow2 = 1,
2487 },
214e1eca
JA
2488 {
2489 .name = "exec_prerun",
e8b0e958 2490 .lname = "Pre-execute runnable",
214e1eca
JA
2491 .type = FIO_OPT_STR_STORE,
2492 .off1 = td_var_offset(exec_prerun),
2493 .help = "Execute this file prior to running job",
e8b0e958
JA
2494 .category = FIO_OPT_C_GENERAL,
2495 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2496 },
2497 {
2498 .name = "exec_postrun",
e8b0e958 2499 .lname = "Post-execute runnable",
214e1eca
JA
2500 .type = FIO_OPT_STR_STORE,
2501 .off1 = td_var_offset(exec_postrun),
2502 .help = "Execute this file after running job",
e8b0e958
JA
2503 .category = FIO_OPT_C_GENERAL,
2504 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2505 },
2506#ifdef FIO_HAVE_IOSCHED_SWITCH
2507 {
2508 .name = "ioscheduler",
e8b0e958 2509 .lname = "I/O scheduler",
214e1eca
JA
2510 .type = FIO_OPT_STR_STORE,
2511 .off1 = td_var_offset(ioscheduler),
2512 .help = "Use this IO scheduler on the backing device",
e8b0e958
JA
2513 .category = FIO_OPT_C_FILE,
2514 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2515 },
2516#endif
2517 {
2518 .name = "zonesize",
e8b0e958 2519 .lname = "Zone size",
214e1eca
JA
2520 .type = FIO_OPT_STR_VAL,
2521 .off1 = td_var_offset(zone_size),
ed335855
SN
2522 .help = "Amount of data to read per zone",
2523 .def = "0",
20eb06bd 2524 .interval = 1024 * 1024,
e8b0e958
JA
2525 .category = FIO_OPT_C_IO,
2526 .group = FIO_OPT_G_ZONE,
ed335855
SN
2527 },
2528 {
2529 .name = "zonerange",
e8b0e958 2530 .lname = "Zone range",
ed335855
SN
2531 .type = FIO_OPT_STR_VAL,
2532 .off1 = td_var_offset(zone_range),
214e1eca
JA
2533 .help = "Give size of an IO zone",
2534 .def = "0",
20eb06bd 2535 .interval = 1024 * 1024,
e8b0e958
JA
2536 .category = FIO_OPT_C_IO,
2537 .group = FIO_OPT_G_ZONE,
214e1eca
JA
2538 },
2539 {
2540 .name = "zoneskip",
e8b0e958 2541 .lname = "Zone skip",
214e1eca
JA
2542 .type = FIO_OPT_STR_VAL,
2543 .off1 = td_var_offset(zone_skip),
2544 .help = "Space between IO zones",
2545 .def = "0",
20eb06bd 2546 .interval = 1024 * 1024,
e8b0e958
JA
2547 .category = FIO_OPT_C_IO,
2548 .group = FIO_OPT_G_ZONE,
214e1eca
JA
2549 },
2550 {
2551 .name = "lockmem",
e8b0e958 2552 .lname = "Lock memory",
214e1eca 2553 .type = FIO_OPT_STR_VAL,
1b79a070 2554 .off1 = td_var_offset(lockmem),
81c6b6cd 2555 .help = "Lock down this amount of memory (per worker)",
214e1eca 2556 .def = "0",
20eb06bd 2557 .interval = 1024 * 1024,
e8b0e958
JA
2558 .category = FIO_OPT_C_GENERAL,
2559 .group = FIO_OPT_G_INVALID,
214e1eca 2560 },
214e1eca
JA
2561 {
2562 .name = "rwmixread",
e8b0e958 2563 .lname = "Read/write mix read",
214e1eca 2564 .type = FIO_OPT_INT,
cb499fc4 2565 .cb = str_rwmix_read_cb,
a8523a6a 2566 .off1 = td_var_offset(rwmix[DDIR_READ]),
214e1eca
JA
2567 .maxval = 100,
2568 .help = "Percentage of mixed workload that is reads",
2569 .def = "50",
20eb06bd 2570 .interval = 5,
90265353 2571 .inverse = "rwmixwrite",
e8b0e958
JA
2572 .category = FIO_OPT_C_IO,
2573 .group = FIO_OPT_G_RWMIX,
214e1eca
JA
2574 },
2575 {
2576 .name = "rwmixwrite",
e8b0e958 2577 .lname = "Read/write mix write",
214e1eca 2578 .type = FIO_OPT_INT,
cb499fc4 2579 .cb = str_rwmix_write_cb,
a8523a6a 2580 .off1 = td_var_offset(rwmix[DDIR_WRITE]),
214e1eca
JA
2581 .maxval = 100,
2582 .help = "Percentage of mixed workload that is writes",
2583 .def = "50",
20eb06bd 2584 .interval = 5,
90265353 2585 .inverse = "rwmixread",
e8b0e958
JA
2586 .category = FIO_OPT_C_IO,
2587 .group = FIO_OPT_G_RWMIX,
214e1eca 2588 },
afdf9352
JA
2589 {
2590 .name = "rwmixcycle",
e8b0e958 2591 .lname = "Read/write mix cycle",
15ca150e 2592 .type = FIO_OPT_DEPRECATED,
e8b0e958
JA
2593 .category = FIO_OPT_C_IO,
2594 .group = FIO_OPT_G_RWMIX,
afdf9352 2595 },
214e1eca
JA
2596 {
2597 .name = "nice",
e8b0e958 2598 .lname = "Nice",
214e1eca
JA
2599 .type = FIO_OPT_INT,
2600 .off1 = td_var_offset(nice),
2601 .help = "Set job CPU nice value",
2602 .minval = -19,
2603 .maxval = 20,
2604 .def = "0",
20eb06bd 2605 .interval = 1,
e8b0e958 2606 .category = FIO_OPT_C_GENERAL,
10860056 2607 .group = FIO_OPT_G_CRED,
214e1eca
JA
2608 },
2609#ifdef FIO_HAVE_IOPRIO
2610 {
2611 .name = "prio",
e8b0e958 2612 .lname = "I/O nice priority",
214e1eca 2613 .type = FIO_OPT_INT,
28727df7 2614 .off1 = td_var_offset(ioprio),
214e1eca
JA
2615 .help = "Set job IO priority value",
2616 .minval = 0,
2617 .maxval = 7,
20eb06bd 2618 .interval = 1,
e8b0e958 2619 .category = FIO_OPT_C_GENERAL,
10860056 2620 .group = FIO_OPT_G_CRED,
214e1eca
JA
2621 },
2622 {
2623 .name = "prioclass",
e8b0e958 2624 .lname = "I/O nice priority class",
214e1eca 2625 .type = FIO_OPT_INT,
28727df7 2626 .off1 = td_var_offset(ioprio_class),
214e1eca
JA
2627 .help = "Set job IO priority class",
2628 .minval = 0,
2629 .maxval = 3,
20eb06bd 2630 .interval = 1,
e8b0e958 2631 .category = FIO_OPT_C_GENERAL,
10860056 2632 .group = FIO_OPT_G_CRED,
214e1eca
JA
2633 },
2634#endif
2635 {
2636 .name = "thinktime",
e8b0e958 2637 .lname = "Thinktime",
214e1eca
JA
2638 .type = FIO_OPT_INT,
2639 .off1 = td_var_offset(thinktime),
2640 .help = "Idle time between IO buffers (usec)",
2641 .def = "0",
88038bc7 2642 .is_time = 1,
e8b0e958 2643 .category = FIO_OPT_C_IO,
3ceb458f 2644 .group = FIO_OPT_G_THINKTIME,
214e1eca
JA
2645 },
2646 {
2647 .name = "thinktime_spin",
e8b0e958 2648 .lname = "Thinktime spin",
214e1eca
JA
2649 .type = FIO_OPT_INT,
2650 .off1 = td_var_offset(thinktime_spin),
2651 .help = "Start think time by spinning this amount (usec)",
2652 .def = "0",
88038bc7 2653 .is_time = 1,
afdf9352 2654 .parent = "thinktime",
d71c154c 2655 .hide = 1,
e8b0e958 2656 .category = FIO_OPT_C_IO,
3ceb458f 2657 .group = FIO_OPT_G_THINKTIME,
214e1eca
JA
2658 },
2659 {
2660 .name = "thinktime_blocks",
e8b0e958 2661 .lname = "Thinktime blocks",
214e1eca
JA
2662 .type = FIO_OPT_INT,
2663 .off1 = td_var_offset(thinktime_blocks),
2664 .help = "IO buffer period between 'thinktime'",
2665 .def = "1",
afdf9352 2666 .parent = "thinktime",
d71c154c 2667 .hide = 1,
e8b0e958 2668 .category = FIO_OPT_C_IO,
3ceb458f 2669 .group = FIO_OPT_G_THINKTIME,
214e1eca
JA
2670 },
2671 {
2672 .name = "rate",
e8b0e958 2673 .lname = "I/O rate",
e01b22b8 2674 .type = FIO_OPT_INT,
6eaf09d6
SL
2675 .off1 = td_var_offset(rate[DDIR_READ]),
2676 .off2 = td_var_offset(rate[DDIR_WRITE]),
2677 .off3 = td_var_offset(rate[DDIR_TRIM]),
214e1eca 2678 .help = "Set bandwidth rate",
e8b0e958
JA
2679 .category = FIO_OPT_C_IO,
2680 .group = FIO_OPT_G_RATE,
214e1eca
JA
2681 },
2682 {
6d428bcd
JA
2683 .name = "rate_min",
2684 .alias = "ratemin",
e8b0e958 2685 .lname = "I/O min rate",
e01b22b8 2686 .type = FIO_OPT_INT,
6eaf09d6
SL
2687 .off1 = td_var_offset(ratemin[DDIR_READ]),
2688 .off2 = td_var_offset(ratemin[DDIR_WRITE]),
2689 .off3 = td_var_offset(ratemin[DDIR_TRIM]),
4e991c23 2690 .help = "Job must meet this rate or it will be shutdown",
afdf9352 2691 .parent = "rate",
d71c154c 2692 .hide = 1,
e8b0e958
JA
2693 .category = FIO_OPT_C_IO,
2694 .group = FIO_OPT_G_RATE,
4e991c23
JA
2695 },
2696 {
2697 .name = "rate_iops",
e8b0e958 2698 .lname = "I/O rate IOPS",
e01b22b8 2699 .type = FIO_OPT_INT,
6eaf09d6
SL
2700 .off1 = td_var_offset(rate_iops[DDIR_READ]),
2701 .off2 = td_var_offset(rate_iops[DDIR_WRITE]),
2702 .off3 = td_var_offset(rate_iops[DDIR_TRIM]),
4e991c23 2703 .help = "Limit IO used to this number of IO operations/sec",
d71c154c 2704 .hide = 1,
e8b0e958
JA
2705 .category = FIO_OPT_C_IO,
2706 .group = FIO_OPT_G_RATE,
4e991c23
JA
2707 },
2708 {
2709 .name = "rate_iops_min",
e8b0e958 2710 .lname = "I/O min rate IOPS",
e01b22b8 2711 .type = FIO_OPT_INT,
6eaf09d6
SL
2712 .off1 = td_var_offset(rate_iops_min[DDIR_READ]),
2713 .off2 = td_var_offset(rate_iops_min[DDIR_WRITE]),
2714 .off3 = td_var_offset(rate_iops_min[DDIR_TRIM]),
03e20d68 2715 .help = "Job must meet this rate or it will be shut down",
afdf9352 2716 .parent = "rate_iops",
d71c154c 2717 .hide = 1,
e8b0e958
JA
2718 .category = FIO_OPT_C_IO,
2719 .group = FIO_OPT_G_RATE,
214e1eca 2720 },
ff6bb260 2721 {
6de65959
JA
2722 .name = "rate_process",
2723 .lname = "Rate Process",
2724 .type = FIO_OPT_STR,
2725 .off1 = td_var_offset(rate_process),
2726 .help = "What process controls how rated IO is managed",
2727 .def = "linear",
ff6bb260
SL
2728 .category = FIO_OPT_C_IO,
2729 .group = FIO_OPT_G_RATE,
6de65959
JA
2730 .posval = {
2731 { .ival = "linear",
2732 .oval = RATE_PROCESS_LINEAR,
2733 .help = "Linear rate of IO",
2734 },
2735 {
2736 .ival = "poisson",
2737 .oval = RATE_PROCESS_POISSON,
2738 .help = "Rate follows Poisson process",
2739 },
2740 },
2741 .parent = "rate",
ff6bb260 2742 },
214e1eca 2743 {
6d428bcd
JA
2744 .name = "rate_cycle",
2745 .alias = "ratecycle",
e8b0e958 2746 .lname = "I/O rate cycle",
214e1eca
JA
2747 .type = FIO_OPT_INT,
2748 .off1 = td_var_offset(ratecycle),
2749 .help = "Window average for rate limits (msec)",
2750 .def = "1000",
afdf9352 2751 .parent = "rate",
d71c154c 2752 .hide = 1,
e8b0e958
JA
2753 .category = FIO_OPT_C_IO,
2754 .group = FIO_OPT_G_RATE,
214e1eca 2755 },
15501535
JA
2756 {
2757 .name = "max_latency",
2758 .type = FIO_OPT_INT,
2759 .off1 = td_var_offset(max_latency),
2760 .help = "Maximum tolerated IO latency (usec)",
88038bc7 2761 .is_time = 1,
1e5324e7 2762 .category = FIO_OPT_C_IO,
3e260a46
JA
2763 .group = FIO_OPT_G_LATPROF,
2764 },
2765 {
2766 .name = "latency_target",
2767 .lname = "Latency Target (usec)",
2768 .type = FIO_OPT_STR_VAL_TIME,
2769 .off1 = td_var_offset(latency_target),
2770 .help = "Ramp to max queue depth supporting this latency",
88038bc7 2771 .is_time = 1,
3e260a46
JA
2772 .category = FIO_OPT_C_IO,
2773 .group = FIO_OPT_G_LATPROF,
2774 },
2775 {
2776 .name = "latency_window",
2777 .lname = "Latency Window (usec)",
2778 .type = FIO_OPT_STR_VAL_TIME,
2779 .off1 = td_var_offset(latency_window),
2780 .help = "Time to sustain latency_target",
88038bc7 2781 .is_time = 1,
3e260a46
JA
2782 .category = FIO_OPT_C_IO,
2783 .group = FIO_OPT_G_LATPROF,
2784 },
2785 {
2786 .name = "latency_percentile",
2787 .lname = "Latency Percentile",
2788 .type = FIO_OPT_FLOAT_LIST,
2789 .off1 = td_var_offset(latency_percentile),
2790 .help = "Percentile of IOs must be below latency_target",
2791 .def = "100",
2792 .maxlen = 1,
2793 .minfp = 0.0,
2794 .maxfp = 100.0,
2795 .category = FIO_OPT_C_IO,
2796 .group = FIO_OPT_G_LATPROF,
15501535 2797 },
214e1eca
JA
2798 {
2799 .name = "invalidate",
e8b0e958 2800 .lname = "Cache invalidate",
214e1eca
JA
2801 .type = FIO_OPT_BOOL,
2802 .off1 = td_var_offset(invalidate_cache),
2803 .help = "Invalidate buffer/page cache prior to running job",
2804 .def = "1",
e8b0e958 2805 .category = FIO_OPT_C_IO,
3ceb458f 2806 .group = FIO_OPT_G_IO_TYPE,
214e1eca
JA
2807 },
2808 {
2809 .name = "sync",
e8b0e958 2810 .lname = "Synchronous I/O",
214e1eca
JA
2811 .type = FIO_OPT_BOOL,
2812 .off1 = td_var_offset(sync_io),
2813 .help = "Use O_SYNC for buffered writes",
2814 .def = "0",
67a1000f 2815 .parent = "buffered",
d71c154c 2816 .hide = 1,
e8b0e958 2817 .category = FIO_OPT_C_IO,
3ceb458f 2818 .group = FIO_OPT_G_IO_TYPE,
214e1eca 2819 },
214e1eca
JA
2820 {
2821 .name = "create_serialize",
e8b0e958 2822 .lname = "Create serialize",
214e1eca
JA
2823 .type = FIO_OPT_BOOL,
2824 .off1 = td_var_offset(create_serialize),
2825 .help = "Serialize creating of job files",
2826 .def = "1",
e8b0e958
JA
2827 .category = FIO_OPT_C_FILE,
2828 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2829 },
2830 {
2831 .name = "create_fsync",
e8b0e958 2832 .lname = "Create fsync",
214e1eca
JA
2833 .type = FIO_OPT_BOOL,
2834 .off1 = td_var_offset(create_fsync),
03e20d68 2835 .help = "fsync file after creation",
214e1eca 2836 .def = "1",
e8b0e958
JA
2837 .category = FIO_OPT_C_FILE,
2838 .group = FIO_OPT_G_INVALID,
214e1eca 2839 },
814452bd
JA
2840 {
2841 .name = "create_on_open",
e8b0e958 2842 .lname = "Create on open",
814452bd
JA
2843 .type = FIO_OPT_BOOL,
2844 .off1 = td_var_offset(create_on_open),
2845 .help = "Create files when they are opened for IO",
2846 .def = "0",
e8b0e958
JA
2847 .category = FIO_OPT_C_FILE,
2848 .group = FIO_OPT_G_INVALID,
814452bd 2849 },
25460cf6
JA
2850 {
2851 .name = "create_only",
2852 .type = FIO_OPT_BOOL,
2853 .off1 = td_var_offset(create_only),
2854 .help = "Only perform file creation phase",
d17fda71 2855 .category = FIO_OPT_C_FILE,
25460cf6
JA
2856 .def = "0",
2857 },
2378826d
JA
2858 {
2859 .name = "allow_file_create",
e81ecca3 2860 .lname = "Allow file create",
2378826d
JA
2861 .type = FIO_OPT_BOOL,
2862 .off1 = td_var_offset(allow_create),
2863 .help = "Permit fio to create files, if they don't exist",
2864 .def = "1",
2865 .category = FIO_OPT_C_FILE,
2866 .group = FIO_OPT_G_FILENAME,
2867 },
e81ecca3
JA
2868 {
2869 .name = "allow_mounted_write",
2870 .lname = "Allow mounted write",
2871 .type = FIO_OPT_BOOL,
2872 .off1 = td_var_offset(allow_mounted_write),
2873 .help = "Allow writes to a mounted partition",
2874 .def = "0",
2875 .category = FIO_OPT_C_FILE,
2876 .group = FIO_OPT_G_FILENAME,
2877 },
0b9d69ec 2878 {
afad68f7 2879 .name = "pre_read",
e8b0e958 2880 .lname = "Pre-read files",
afad68f7
ZY
2881 .type = FIO_OPT_BOOL,
2882 .off1 = td_var_offset(pre_read),
03e20d68 2883 .help = "Pre-read files before starting official testing",
afad68f7 2884 .def = "0",
e8b0e958
JA
2885 .category = FIO_OPT_C_FILE,
2886 .group = FIO_OPT_G_INVALID,
afad68f7 2887 },
214e1eca
JA
2888#ifdef FIO_HAVE_CPU_AFFINITY
2889 {
2890 .name = "cpumask",
e8b0e958 2891 .lname = "CPU mask",
214e1eca
JA
2892 .type = FIO_OPT_INT,
2893 .cb = str_cpumask_cb,
a8523a6a 2894 .off1 = td_var_offset(cpumask),
214e1eca 2895 .help = "CPU affinity mask",
e8b0e958 2896 .category = FIO_OPT_C_GENERAL,
10860056 2897 .group = FIO_OPT_G_CRED,
214e1eca 2898 },
d2e268b0
JA
2899 {
2900 .name = "cpus_allowed",
e8b0e958 2901 .lname = "CPUs allowed",
d2e268b0
JA
2902 .type = FIO_OPT_STR,
2903 .cb = str_cpus_allowed_cb,
a8523a6a 2904 .off1 = td_var_offset(cpumask),
d2e268b0 2905 .help = "Set CPUs allowed",
e8b0e958 2906 .category = FIO_OPT_C_GENERAL,
10860056 2907 .group = FIO_OPT_G_CRED,
d2e268b0 2908 },
c2acfbac
JA
2909 {
2910 .name = "cpus_allowed_policy",
2911 .lname = "CPUs allowed distribution policy",
2912 .type = FIO_OPT_STR,
2913 .off1 = td_var_offset(cpus_allowed_policy),
2914 .help = "Distribution policy for cpus_allowed",
2915 .parent = "cpus_allowed",
2916 .prio = 1,
2917 .posval = {
2918 { .ival = "shared",
2919 .oval = FIO_CPUS_SHARED,
2920 .help = "Mask shared between threads",
2921 },
2922 { .ival = "split",
2923 .oval = FIO_CPUS_SPLIT,
2924 .help = "Mask split between threads",
2925 },
2926 },
2927 .category = FIO_OPT_C_GENERAL,
2928 .group = FIO_OPT_G_CRED,
2929 },
d0b937ed 2930#endif
67bf9823 2931#ifdef CONFIG_LIBNUMA
d0b937ed
YR
2932 {
2933 .name = "numa_cpu_nodes",
2934 .type = FIO_OPT_STR,
2935 .cb = str_numa_cpunodes_cb,
b2a9e649 2936 .off1 = td_var_offset(numa_cpunodes),
d0b937ed 2937 .help = "NUMA CPU nodes bind",
6be54b2d
JA
2938 .category = FIO_OPT_C_GENERAL,
2939 .group = FIO_OPT_G_INVALID,
d0b937ed
YR
2940 },
2941 {
2942 .name = "numa_mem_policy",
2943 .type = FIO_OPT_STR,
2944 .cb = str_numa_mpol_cb,
b2a9e649 2945 .off1 = td_var_offset(numa_memnodes),
d0b937ed 2946 .help = "NUMA memory policy setup",
6be54b2d
JA
2947 .category = FIO_OPT_C_GENERAL,
2948 .group = FIO_OPT_G_INVALID,
d0b937ed 2949 },
214e1eca
JA
2950#endif
2951 {
2952 .name = "end_fsync",
e8b0e958 2953 .lname = "End fsync",
214e1eca
JA
2954 .type = FIO_OPT_BOOL,
2955 .off1 = td_var_offset(end_fsync),
2956 .help = "Include fsync at the end of job",
2957 .def = "0",
e8b0e958
JA
2958 .category = FIO_OPT_C_FILE,
2959 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2960 },
2961 {
2962 .name = "fsync_on_close",
e8b0e958 2963 .lname = "Fsync on close",
214e1eca
JA
2964 .type = FIO_OPT_BOOL,
2965 .off1 = td_var_offset(fsync_on_close),
2966 .help = "fsync files on close",
2967 .def = "0",
e8b0e958
JA
2968 .category = FIO_OPT_C_FILE,
2969 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2970 },
2971 {
2972 .name = "unlink",
e8b0e958 2973 .lname = "Unlink file",
214e1eca
JA
2974 .type = FIO_OPT_BOOL,
2975 .off1 = td_var_offset(unlink),
2976 .help = "Unlink created files after job has completed",
2977 .def = "0",
e8b0e958
JA
2978 .category = FIO_OPT_C_FILE,
2979 .group = FIO_OPT_G_INVALID,
214e1eca
JA
2980 },
2981 {
2982 .name = "exitall",
e8b0e958 2983 .lname = "Exit-all on terminate",
214e1eca
JA
2984 .type = FIO_OPT_STR_SET,
2985 .cb = str_exitall_cb,
2986 .help = "Terminate all jobs when one exits",
e8b0e958 2987 .category = FIO_OPT_C_GENERAL,
a1f6afec 2988 .group = FIO_OPT_G_PROCESS,
214e1eca 2989 },
f9cafb12
JA
2990 {
2991 .name = "exitall_on_error",
2992 .lname = "Exit-all on terminate in error",
2993 .type = FIO_OPT_BOOL,
2994 .off1 = td_var_offset(unlink),
2995 .help = "Terminate all jobs when one exits in error",
2996 .category = FIO_OPT_C_GENERAL,
2997 .group = FIO_OPT_G_PROCESS,
2998 },
214e1eca
JA
2999 {
3000 .name = "stonewall",
e8b0e958 3001 .lname = "Wait for previous",
d392365e 3002 .alias = "wait_for_previous",
214e1eca
JA
3003 .type = FIO_OPT_STR_SET,
3004 .off1 = td_var_offset(stonewall),
3005 .help = "Insert a hard barrier between this job and previous",
e8b0e958 3006 .category = FIO_OPT_C_GENERAL,
a1f6afec 3007 .group = FIO_OPT_G_PROCESS,
214e1eca 3008 },
b3d62a75
JA
3009 {
3010 .name = "new_group",
e8b0e958 3011 .lname = "New group",
b3d62a75
JA
3012 .type = FIO_OPT_STR_SET,
3013 .off1 = td_var_offset(new_group),
3014 .help = "Mark the start of a new group (for reporting)",
e8b0e958 3015 .category = FIO_OPT_C_GENERAL,
a1f6afec 3016 .group = FIO_OPT_G_PROCESS,
b3d62a75 3017 },
214e1eca
JA
3018 {
3019 .name = "thread",
e8b0e958 3020 .lname = "Thread",
214e1eca
JA
3021 .type = FIO_OPT_STR_SET,
3022 .off1 = td_var_offset(use_thread),
20eb06bd 3023 .help = "Use threads instead of processes",
c8931876
JA
3024#ifdef CONFIG_NO_SHM
3025 .def = "1",
3026 .no_warn_def = 1,
3027#endif
e8b0e958 3028 .category = FIO_OPT_C_GENERAL,
a1f6afec 3029 .group = FIO_OPT_G_PROCESS,
214e1eca 3030 },
3a5db920
JA
3031 {
3032 .name = "per_job_logs",
3033 .type = FIO_OPT_BOOL,
3034 .off1 = td_var_offset(per_job_logs),
3035 .help = "Include job number in generated log files or not",
3036 .def = "1",
3037 .category = FIO_OPT_C_LOG,
3038 .group = FIO_OPT_G_INVALID,
3039 },
214e1eca
JA
3040 {
3041 .name = "write_bw_log",
e8b0e958 3042 .lname = "Write bandwidth log",
203160d5
JA
3043 .type = FIO_OPT_STR_STORE,
3044 .off1 = td_var_offset(bw_log_file),
214e1eca 3045 .help = "Write log of bandwidth during run",
e8b0e958
JA
3046 .category = FIO_OPT_C_LOG,
3047 .group = FIO_OPT_G_INVALID,
214e1eca
JA
3048 },
3049 {
3050 .name = "write_lat_log",
e8b0e958 3051 .lname = "Write latency log",
203160d5
JA
3052 .type = FIO_OPT_STR_STORE,
3053 .off1 = td_var_offset(lat_log_file),
214e1eca 3054 .help = "Write log of latency during run",
e8b0e958
JA
3055 .category = FIO_OPT_C_LOG,
3056 .group = FIO_OPT_G_INVALID,
214e1eca 3057 },
c8eeb9df
JA
3058 {
3059 .name = "write_iops_log",
e8b0e958 3060 .lname = "Write IOPS log",
577c83bd 3061 .type = FIO_OPT_STR_STORE,
203160d5 3062 .off1 = td_var_offset(iops_log_file),
c8eeb9df 3063 .help = "Write log of IOPS during run",
e8b0e958
JA
3064 .category = FIO_OPT_C_LOG,
3065 .group = FIO_OPT_G_INVALID,
c8eeb9df 3066 },
b8bc8cba
JA
3067 {
3068 .name = "log_avg_msec",
e8b0e958 3069 .lname = "Log averaging (msec)",
b8bc8cba
JA
3070 .type = FIO_OPT_INT,
3071 .off1 = td_var_offset(log_avg_msec),
3072 .help = "Average bw/iops/lat logs over this period of time",
3073 .def = "0",
e8b0e958
JA
3074 .category = FIO_OPT_C_LOG,
3075 .group = FIO_OPT_G_INVALID,
b8bc8cba 3076 },
ae588852
JA
3077 {
3078 .name = "log_offset",
3079 .lname = "Log offset of IO",
3080 .type = FIO_OPT_BOOL,
3081 .off1 = td_var_offset(log_offset),
3082 .help = "Include offset of IO for each log entry",
3083 .def = "0",
3084 .category = FIO_OPT_C_LOG,
3085 .group = FIO_OPT_G_INVALID,
3086 },
aee2ab67
JA
3087#ifdef CONFIG_ZLIB
3088 {
3089 .name = "log_compression",
3090 .lname = "Log compression",
3091 .type = FIO_OPT_INT,
3092 .off1 = td_var_offset(log_gz),
3093 .help = "Log in compressed chunks of this size",
9919b27b 3094 .minval = 1024ULL,
aee2ab67
JA
3095 .maxval = 512 * 1024 * 1024ULL,
3096 .category = FIO_OPT_C_LOG,
3097 .group = FIO_OPT_G_INVALID,
3098 },
c08f9fe2
JA
3099#ifdef FIO_HAVE_CPU_AFFINITY
3100 {
3101 .name = "log_compression_cpus",
3102 .lname = "Log Compression CPUs",
3103 .type = FIO_OPT_STR,
3104 .cb = str_log_cpus_allowed_cb,
3105 .off1 = td_var_offset(log_gz_cpumask),
3106 .parent = "log_compression",
3107 .help = "Limit log compression to these CPUs",
3108 .category = FIO_OPT_C_LOG,
3109 .group = FIO_OPT_G_INVALID,
3110 },
3111#endif
b26317c9
JA
3112 {
3113 .name = "log_store_compressed",
3114 .lname = "Log store compressed",
3115 .type = FIO_OPT_BOOL,
3116 .off1 = td_var_offset(log_gz_store),
3117 .help = "Store logs in a compressed format",
3118 .category = FIO_OPT_C_LOG,
3119 .group = FIO_OPT_G_INVALID,
3120 },
aee2ab67 3121#endif
66347cfa
DE
3122 {
3123 .name = "block_error_percentiles",
3124 .lname = "Block error percentiles",
3125 .type = FIO_OPT_BOOL,
3126 .off1 = td_var_offset(block_error_hist),
3127 .help = "Record trim block errors and make a histogram",
3128 .def = "0",
3129 .category = FIO_OPT_C_LOG,
3130 .group = FIO_OPT_G_INVALID,
3131 },
c504ee55
JA
3132 {
3133 .name = "bwavgtime",
3134 .lname = "Bandwidth average time",
3135 .type = FIO_OPT_INT,
3136 .off1 = td_var_offset(bw_avg_time),
3137 .help = "Time window over which to calculate bandwidth"
3138 " (msec)",
3139 .def = "500",
3140 .parent = "write_bw_log",
3141 .hide = 1,
3142 .interval = 100,
3143 .category = FIO_OPT_C_LOG,
3144 .group = FIO_OPT_G_INVALID,
3145 },
3146 {
3147 .name = "iopsavgtime",
3148 .lname = "IOPS average time",
3149 .type = FIO_OPT_INT,
3150 .off1 = td_var_offset(iops_avg_time),
3151 .help = "Time window over which to calculate IOPS (msec)",
3152 .def = "500",
3153 .parent = "write_iops_log",
3154 .hide = 1,
3155 .interval = 100,
3156 .category = FIO_OPT_C_LOG,
3157 .group = FIO_OPT_G_INVALID,
3158 },
214e1eca
JA
3159 {
3160 .name = "group_reporting",
e8b0e958 3161 .lname = "Group reporting",
d2507043 3162 .type = FIO_OPT_STR_SET,
214e1eca
JA
3163 .off1 = td_var_offset(group_reporting),
3164 .help = "Do reporting on a per-group basis",
10860056 3165 .category = FIO_OPT_C_STAT,
e8b0e958 3166 .group = FIO_OPT_G_INVALID,
214e1eca 3167 },
e9459e5a
JA
3168 {
3169 .name = "zero_buffers",
e8b0e958 3170 .lname = "Zero I/O buffers",
e9459e5a
JA
3171 .type = FIO_OPT_STR_SET,
3172 .off1 = td_var_offset(zero_buffers),
3173 .help = "Init IO buffers to all zeroes",
e8b0e958 3174 .category = FIO_OPT_C_IO,
3ceb458f 3175 .group = FIO_OPT_G_IO_BUF,
e9459e5a 3176 },
5973cafb
JA
3177 {
3178 .name = "refill_buffers",
e8b0e958 3179 .lname = "Refill I/O buffers",
5973cafb
JA
3180 .type = FIO_OPT_STR_SET,
3181 .off1 = td_var_offset(refill_buffers),
3182 .help = "Refill IO buffers on every IO submit",
e8b0e958 3183 .category = FIO_OPT_C_IO,
3ceb458f 3184 .group = FIO_OPT_G_IO_BUF,
5973cafb 3185 },
fd68418e
JA
3186 {
3187 .name = "scramble_buffers",
e8b0e958 3188 .lname = "Scramble I/O buffers",
fd68418e
JA
3189 .type = FIO_OPT_BOOL,
3190 .off1 = td_var_offset(scramble_buffers),
3191 .help = "Slightly scramble buffers on every IO submit",
3192 .def = "1",
e8b0e958 3193 .category = FIO_OPT_C_IO,
3ceb458f 3194 .group = FIO_OPT_G_IO_BUF,
fd68418e 3195 },
ce35b1ec
JA
3196 {
3197 .name = "buffer_pattern",
3198 .lname = "Buffer pattern",
3199 .type = FIO_OPT_STR,
3200 .cb = str_buffer_pattern_cb,
a8523a6a 3201 .off1 = td_var_offset(buffer_pattern),
ce35b1ec
JA
3202 .help = "Fill pattern for IO buffers",
3203 .category = FIO_OPT_C_IO,
3204 .group = FIO_OPT_G_IO_BUF,
3205 },
9c42684e
JA
3206 {
3207 .name = "buffer_compress_percentage",
e8b0e958 3208 .lname = "Buffer compression percentage",
9c42684e 3209 .type = FIO_OPT_INT,
bedc9dc2 3210 .cb = str_buffer_compress_cb,
a8523a6a 3211 .off1 = td_var_offset(compress_percentage),
9c42684e 3212 .maxval = 100,
e7f5de90 3213 .minval = 0,
9c42684e 3214 .help = "How compressible the buffer is (approximately)",
20eb06bd 3215 .interval = 5,
e8b0e958 3216 .category = FIO_OPT_C_IO,
3ceb458f 3217 .group = FIO_OPT_G_IO_BUF,
9c42684e 3218 },
f97a43a1
JA
3219 {
3220 .name = "buffer_compress_chunk",
e8b0e958 3221 .lname = "Buffer compression chunk size",
f97a43a1
JA
3222 .type = FIO_OPT_INT,
3223 .off1 = td_var_offset(compress_chunk),
207b18e4 3224 .parent = "buffer_compress_percentage",
d71c154c 3225 .hide = 1,
f97a43a1 3226 .help = "Size of compressible region in buffer",
20eb06bd 3227 .interval = 256,
e8b0e958 3228 .category = FIO_OPT_C_IO,
3ceb458f 3229 .group = FIO_OPT_G_IO_BUF,
f97a43a1 3230 },
5c94b008
JA
3231 {
3232 .name = "dedupe_percentage",
3233 .lname = "Dedupe percentage",
3234 .type = FIO_OPT_INT,
3235 .cb = str_dedupe_cb,
a8523a6a 3236 .off1 = td_var_offset(dedupe_percentage),
5c94b008
JA
3237 .maxval = 100,
3238 .minval = 0,
3239 .help = "Percentage of buffers that are dedupable",
3240 .interval = 1,
3241 .category = FIO_OPT_C_IO,
3242 .group = FIO_OPT_G_IO_BUF,
3243 },
83349190
YH
3244 {
3245 .name = "clat_percentiles",
e8b0e958 3246 .lname = "Completion latency percentiles",
83349190
YH
3247 .type = FIO_OPT_BOOL,
3248 .off1 = td_var_offset(clat_percentiles),
3249 .help = "Enable the reporting of completion latency percentiles",
467b35ed 3250 .def = "1",
e8b0e958
JA
3251 .category = FIO_OPT_C_STAT,
3252 .group = FIO_OPT_G_INVALID,
83349190
YH
3253 },
3254 {
3255 .name = "percentile_list",
66347cfa 3256 .lname = "Percentile list",
83349190
YH
3257 .type = FIO_OPT_FLOAT_LIST,
3258 .off1 = td_var_offset(percentile_list),
435d195a 3259 .off2 = td_var_offset(percentile_precision),
66347cfa
DE
3260 .help = "Specify a custom list of percentiles to report for "
3261 "completion latency and block errors",
fd112d34 3262 .def = "1:5:10:20:30:40:50:60:70:80:90:95:99:99.5:99.9:99.95:99.99",
83349190
YH
3263 .maxlen = FIO_IO_U_LIST_MAX_LEN,
3264 .minfp = 0.0,
3265 .maxfp = 100.0,
e8b0e958
JA
3266 .category = FIO_OPT_C_STAT,
3267 .group = FIO_OPT_G_INVALID,
83349190
YH
3268 },
3269
0a839f30
JA
3270#ifdef FIO_HAVE_DISK_UTIL
3271 {
3272 .name = "disk_util",
e8b0e958 3273 .lname = "Disk utilization",
0a839f30
JA
3274 .type = FIO_OPT_BOOL,
3275 .off1 = td_var_offset(do_disk_util),
f66ab3c8 3276 .help = "Log disk utilization statistics",
0a839f30 3277 .def = "1",
e8b0e958
JA
3278 .category = FIO_OPT_C_STAT,
3279 .group = FIO_OPT_G_INVALID,
0a839f30
JA
3280 },
3281#endif
993bf48b
JA
3282 {
3283 .name = "gtod_reduce",
e8b0e958 3284 .lname = "Reduce gettimeofday() calls",
993bf48b
JA
3285 .type = FIO_OPT_BOOL,
3286 .help = "Greatly reduce number of gettimeofday() calls",
3287 .cb = str_gtod_reduce_cb,
3288 .def = "0",
a4ed77fe 3289 .hide_on_set = 1,
e8b0e958
JA
3290 .category = FIO_OPT_C_STAT,
3291 .group = FIO_OPT_G_INVALID,
993bf48b 3292 },
02af0988
JA
3293 {
3294 .name = "disable_lat",
e8b0e958 3295 .lname = "Disable all latency stats",
02af0988
JA
3296 .type = FIO_OPT_BOOL,
3297 .off1 = td_var_offset(disable_lat),
3298 .help = "Disable latency numbers",
3299 .parent = "gtod_reduce",
d71c154c 3300 .hide = 1,
02af0988 3301 .def = "0",
e8b0e958
JA
3302 .category = FIO_OPT_C_STAT,
3303 .group = FIO_OPT_G_INVALID,
02af0988 3304 },
9520ebb9
JA
3305 {
3306 .name = "disable_clat",
e8b0e958 3307 .lname = "Disable completion latency stats",
9520ebb9
JA
3308 .type = FIO_OPT_BOOL,
3309 .off1 = td_var_offset(disable_clat),
3310 .help = "Disable completion latency numbers",
993bf48b 3311 .parent = "gtod_reduce",
d71c154c 3312 .hide = 1,
9520ebb9 3313 .def = "0",
e8b0e958
JA
3314 .category = FIO_OPT_C_STAT,
3315 .group = FIO_OPT_G_INVALID,
9520ebb9
JA
3316 },
3317 {
3318 .name = "disable_slat",
e8b0e958 3319 .lname = "Disable submission latency stats",
9520ebb9
JA
3320 .type = FIO_OPT_BOOL,
3321 .off1 = td_var_offset(disable_slat),
03e20d68 3322 .help = "Disable submission latency numbers",
993bf48b 3323 .parent = "gtod_reduce",
d71c154c 3324 .hide = 1,
9520ebb9 3325 .def = "0",
e8b0e958
JA
3326 .category = FIO_OPT_C_STAT,
3327 .group = FIO_OPT_G_INVALID,
9520ebb9
JA
3328 },
3329 {
3330 .name = "disable_bw_measurement",
e8b0e958 3331 .lname = "Disable bandwidth stats",
9520ebb9
JA
3332 .type = FIO_OPT_BOOL,
3333 .off1 = td_var_offset(disable_bw),
3334 .help = "Disable bandwidth logging",
993bf48b 3335 .parent = "gtod_reduce",
d71c154c 3336 .hide = 1,
9520ebb9 3337 .def = "0",
e8b0e958
JA
3338 .category = FIO_OPT_C_STAT,
3339 .group = FIO_OPT_G_INVALID,
9520ebb9 3340 },
be4ecfdf
JA
3341 {
3342 .name = "gtod_cpu",
e8b0e958 3343 .lname = "Dedicated gettimeofday() CPU",
be4ecfdf 3344 .type = FIO_OPT_INT,
79c896a1 3345 .off1 = td_var_offset(gtod_cpu),
03e20d68 3346 .help = "Set up dedicated gettimeofday() thread on this CPU",
29d43ff9 3347 .verify = gtod_cpu_verify,
e8b0e958 3348 .category = FIO_OPT_C_GENERAL,
10860056 3349 .group = FIO_OPT_G_CLOCK,
be4ecfdf 3350 },
771e58be
JA
3351 {
3352 .name = "unified_rw_reporting",
3353 .type = FIO_OPT_BOOL,
3354 .off1 = td_var_offset(unified_rw_rep),
3355 .help = "Unify reporting across data direction",
3356 .def = "0",
90b7a96d
JA
3357 .category = FIO_OPT_C_GENERAL,
3358 .group = FIO_OPT_G_INVALID,
771e58be 3359 },
f2bba182
RR
3360 {
3361 .name = "continue_on_error",
e8b0e958 3362 .lname = "Continue on error",
06842027 3363 .type = FIO_OPT_STR,
f2bba182 3364 .off1 = td_var_offset(continue_on_error),
03e20d68 3365 .help = "Continue on non-fatal errors during IO",
06842027 3366 .def = "none",
e8b0e958 3367 .category = FIO_OPT_C_GENERAL,
bc3f552f 3368 .group = FIO_OPT_G_ERR,
06842027
SL
3369 .posval = {
3370 { .ival = "none",
3371 .oval = ERROR_TYPE_NONE,
3372 .help = "Exit when an error is encountered",
3373 },
3374 { .ival = "read",
3375 .oval = ERROR_TYPE_READ,
3376 .help = "Continue on read errors only",
3377 },
3378 { .ival = "write",
3379 .oval = ERROR_TYPE_WRITE,
3380 .help = "Continue on write errors only",
3381 },
3382 { .ival = "io",
3383 .oval = ERROR_TYPE_READ | ERROR_TYPE_WRITE,
3384 .help = "Continue on any IO errors",
3385 },
3386 { .ival = "verify",
3387 .oval = ERROR_TYPE_VERIFY,
3388 .help = "Continue on verify errors only",
3389 },
3390 { .ival = "all",
3391 .oval = ERROR_TYPE_ANY,
3392 .help = "Continue on all io and verify errors",
3393 },
3394 { .ival = "0",
3395 .oval = ERROR_TYPE_NONE,
3396 .help = "Alias for 'none'",
3397 },
3398 { .ival = "1",
3399 .oval = ERROR_TYPE_ANY,
3400 .help = "Alias for 'all'",
3401 },
3402 },
f2bba182 3403 },
8b28bd41
DM
3404 {
3405 .name = "ignore_error",
3406 .type = FIO_OPT_STR,
3407 .cb = str_ignore_error_cb,
a8523a6a 3408 .off1 = td_var_offset(ignore_error_nr),
8b28bd41
DM
3409 .help = "Set a specific list of errors to ignore",
3410 .parent = "rw",
a94eb99a 3411 .category = FIO_OPT_C_GENERAL,
bc3f552f 3412 .group = FIO_OPT_G_ERR,
8b28bd41
DM
3413 },
3414 {
3415 .name = "error_dump",
3416 .type = FIO_OPT_BOOL,
3417 .off1 = td_var_offset(error_dump),
3418 .def = "0",
3419 .help = "Dump info on each error",
a94eb99a 3420 .category = FIO_OPT_C_GENERAL,
bc3f552f 3421 .group = FIO_OPT_G_ERR,
8b28bd41 3422 },
9ac8a797
JA
3423 {
3424 .name = "profile",
e8b0e958 3425 .lname = "Profile",
79d16311 3426 .type = FIO_OPT_STR_STORE,
9ac8a797 3427 .off1 = td_var_offset(profile),
9ac8a797 3428 .help = "Select a specific builtin performance test",
13fca827 3429 .category = FIO_OPT_C_PROFILE,
e8b0e958 3430 .group = FIO_OPT_G_INVALID,
9ac8a797 3431 },
a696fa2a
JA
3432 {
3433 .name = "cgroup",
e8b0e958 3434 .lname = "Cgroup",
a696fa2a
JA
3435 .type = FIO_OPT_STR_STORE,
3436 .off1 = td_var_offset(cgroup),
3437 .help = "Add job to cgroup of this name",
e8b0e958 3438 .category = FIO_OPT_C_GENERAL,
a1f6afec
JA
3439 .group = FIO_OPT_G_CGROUP,
3440 },
3441 {
3442 .name = "cgroup_nodelete",
3443 .lname = "Cgroup no-delete",
3444 .type = FIO_OPT_BOOL,
3445 .off1 = td_var_offset(cgroup_nodelete),
3446 .help = "Do not delete cgroups after job completion",
3447 .def = "0",
3448 .parent = "cgroup",
3449 .category = FIO_OPT_C_GENERAL,
3450 .group = FIO_OPT_G_CGROUP,
a696fa2a
JA
3451 },
3452 {
3453 .name = "cgroup_weight",
e8b0e958 3454 .lname = "Cgroup weight",
a696fa2a
JA
3455 .type = FIO_OPT_INT,
3456 .off1 = td_var_offset(cgroup_weight),
3457 .help = "Use given weight for cgroup",
3458 .minval = 100,
3459 .maxval = 1000,
a1f6afec 3460 .parent = "cgroup",
e8b0e958 3461 .category = FIO_OPT_C_GENERAL,
a1f6afec 3462 .group = FIO_OPT_G_CGROUP,
7de87099 3463 },
e0b0d892
JA
3464 {
3465 .name = "uid",
e8b0e958 3466 .lname = "User ID",
e0b0d892
JA
3467 .type = FIO_OPT_INT,
3468 .off1 = td_var_offset(uid),
3469 .help = "Run job with this user ID",
e8b0e958 3470 .category = FIO_OPT_C_GENERAL,
10860056 3471 .group = FIO_OPT_G_CRED,
e0b0d892
JA
3472 },
3473 {
3474 .name = "gid",
e8b0e958 3475 .lname = "Group ID",
e0b0d892
JA
3476 .type = FIO_OPT_INT,
3477 .off1 = td_var_offset(gid),
3478 .help = "Run job with this group ID",
e8b0e958 3479 .category = FIO_OPT_C_GENERAL,
10860056 3480 .group = FIO_OPT_G_CRED,
e0b0d892 3481 },
a1f6afec
JA
3482 {
3483 .name = "kb_base",
3484 .lname = "KB Base",
3485 .type = FIO_OPT_INT,
3486 .off1 = td_var_offset(kb_base),
a1f6afec
JA
3487 .prio = 1,
3488 .def = "1024",
ba9c7219
JA
3489 .posval = {
3490 { .ival = "1024",
3491 .oval = 1024,
3492 .help = "Use 1024 as the K base",
3493 },
3494 { .ival = "1000",
3495 .oval = 1000,
3496 .help = "Use 1000 as the K base",
3497 },
3498 },
a1f6afec
JA
3499 .help = "How many bytes per KB for reporting (1000 or 1024)",
3500 .category = FIO_OPT_C_GENERAL,
3501 .group = FIO_OPT_G_INVALID,
3502 },
cf3a0518
JA
3503 {
3504 .name = "unit_base",
ba9c7219 3505 .lname = "Base unit for reporting (Bits or Bytes)",
cf3a0518
JA
3506 .type = FIO_OPT_INT,
3507 .off1 = td_var_offset(unit_base),
cf3a0518 3508 .prio = 1,
71a08258
JA
3509 .posval = {
3510 { .ival = "0",
3511 .oval = 0,
3512 .help = "Auto-detect",
3513 },
3514 { .ival = "8",
3515 .oval = 8,
3516 .help = "Normal (byte based)",
3517 },
3518 { .ival = "1",
3519 .oval = 1,
3520 .help = "Bit based",
3521 },
3522 },
cf3a0518
JA
3523 .help = "Bit multiple of result summary data (8 for byte, 1 for bit)",
3524 .category = FIO_OPT_C_GENERAL,
3525 .group = FIO_OPT_G_INVALID,
3526 },
3ceb458f
JA
3527 {
3528 .name = "hugepage-size",
3529 .lname = "Hugepage size",
3530 .type = FIO_OPT_INT,
3531 .off1 = td_var_offset(hugepage_size),
3532 .help = "When using hugepages, specify size of each page",
3533 .def = __fio_stringify(FIO_HUGE_PAGE),
3534 .interval = 1024 * 1024,
3535 .category = FIO_OPT_C_GENERAL,
3536 .group = FIO_OPT_G_INVALID,
3537 },
9e684a49
DE
3538 {
3539 .name = "flow_id",
e8b0e958 3540 .lname = "I/O flow ID",
9e684a49
DE
3541 .type = FIO_OPT_INT,
3542 .off1 = td_var_offset(flow_id),
3543 .help = "The flow index ID to use",
3544 .def = "0",
e8b0e958
JA
3545 .category = FIO_OPT_C_IO,
3546 .group = FIO_OPT_G_IO_FLOW,
9e684a49
DE
3547 },
3548 {
3549 .name = "flow",
e8b0e958 3550 .lname = "I/O flow weight",
9e684a49
DE
3551 .type = FIO_OPT_INT,
3552 .off1 = td_var_offset(flow),
3553 .help = "Weight for flow control of this job",
3554 .parent = "flow_id",
d71c154c 3555 .hide = 1,
9e684a49 3556 .def = "0",
e8b0e958
JA
3557 .category = FIO_OPT_C_IO,
3558 .group = FIO_OPT_G_IO_FLOW,
9e684a49
DE
3559 },
3560 {
3561 .name = "flow_watermark",
e8b0e958 3562 .lname = "I/O flow watermark",
9e684a49
DE
3563 .type = FIO_OPT_INT,
3564 .off1 = td_var_offset(flow_watermark),
3565 .help = "High watermark for flow control. This option"
3566 " should be set to the same value for all threads"
3567 " with non-zero flow.",
3568 .parent = "flow_id",
d71c154c 3569 .hide = 1,
9e684a49 3570 .def = "1024",
e8b0e958
JA
3571 .category = FIO_OPT_C_IO,
3572 .group = FIO_OPT_G_IO_FLOW,
9e684a49
DE
3573 },
3574 {
3575 .name = "flow_sleep",
e8b0e958 3576 .lname = "I/O flow sleep",
9e684a49
DE
3577 .type = FIO_OPT_INT,
3578 .off1 = td_var_offset(flow_sleep),
3579 .help = "How many microseconds to sleep after being held"
3580 " back by the flow control mechanism",
3581 .parent = "flow_id",
d71c154c 3582 .hide = 1,
9e684a49 3583 .def = "0",
e8b0e958
JA
3584 .category = FIO_OPT_C_IO,
3585 .group = FIO_OPT_G_IO_FLOW,
9e684a49 3586 },
65fa28ca
DE
3587 {
3588 .name = "skip_bad",
3589 .lname = "Skip operations against bad blocks",
3590 .type = FIO_OPT_BOOL,
3591 .off1 = td_var_offset(skip_bad),
3592 .help = "Skip operations against known bad blocks.",
3593 .hide = 1,
3594 .def = "0",
3595 .category = FIO_OPT_C_IO,
3596 .group = FIO_OPT_G_MTD,
3597 },
214e1eca
JA
3598 {
3599 .name = NULL,
3600 },
3601};
3602
17af15d4 3603static void add_to_lopt(struct option *lopt, struct fio_option *o,
de890a1e 3604 const char *name, int val)
9f81736c 3605{
17af15d4 3606 lopt->name = (char *) name;
de890a1e 3607 lopt->val = val;
9f81736c 3608 if (o->type == FIO_OPT_STR_SET)
ff52be3d 3609 lopt->has_arg = optional_argument;
9f81736c
JA
3610 else
3611 lopt->has_arg = required_argument;
3612}
3613
de890a1e
SL
3614static void options_to_lopts(struct fio_option *opts,
3615 struct option *long_options,
3616 int i, int option_type)
214e1eca 3617{
de890a1e 3618 struct fio_option *o = &opts[0];
214e1eca 3619 while (o->name) {
de890a1e 3620 add_to_lopt(&long_options[i], o, o->name, option_type);
17af15d4
JA
3621 if (o->alias) {
3622 i++;
de890a1e 3623 add_to_lopt(&long_options[i], o, o->alias, option_type);
17af15d4 3624 }
214e1eca
JA
3625
3626 i++;
3627 o++;
3628 assert(i < FIO_NR_OPTIONS);
3629 }
3630}
3631
de890a1e
SL
3632void fio_options_set_ioengine_opts(struct option *long_options,
3633 struct thread_data *td)
3634{
3635 unsigned int i;
3636
3637 i = 0;
3638 while (long_options[i].name) {
3639 if (long_options[i].val == FIO_GETOPT_IOENGINE) {
3640 memset(&long_options[i], 0, sizeof(*long_options));
3641 break;
3642 }
3643 i++;
3644 }
3645
3646 /*
3647 * Just clear out the prior ioengine options.
3648 */
3649 if (!td || !td->eo)
3650 return;
3651
3652 options_to_lopts(td->io_ops->options, long_options, i,
3653 FIO_GETOPT_IOENGINE);
3654}
3655
3656void fio_options_dup_and_init(struct option *long_options)
3657{
3658 unsigned int i;
3659
9af4a244 3660 options_init(fio_options);
de890a1e
SL
3661
3662 i = 0;
3663 while (long_options[i].name)
3664 i++;
3665
9af4a244 3666 options_to_lopts(fio_options, long_options, i, FIO_GETOPT_JOB);
de890a1e
SL
3667}
3668
74929ac2
JA
3669struct fio_keyword {
3670 const char *word;
3671 const char *desc;
3672 char *replace;
3673};
3674
3675static struct fio_keyword fio_keywords[] = {
3676 {
3677 .word = "$pagesize",
3678 .desc = "Page size in the system",
3679 },
3680 {
3681 .word = "$mb_memory",
3682 .desc = "Megabytes of memory online",
3683 },
3684 {
3685 .word = "$ncpus",
3686 .desc = "Number of CPUs online in the system",
3687 },
3688 {
3689 .word = NULL,
3690 },
3691};
3692
af1dc266
JA
3693void fio_keywords_exit(void)
3694{
3695 struct fio_keyword *kw;
3696
3697 kw = &fio_keywords[0];
3698 while (kw->word) {
3699 free(kw->replace);
3700 kw->replace = NULL;
3701 kw++;
3702 }
3703}
3704
74929ac2
JA
3705void fio_keywords_init(void)
3706{
3b2e1464 3707 unsigned long long mb_memory;
74929ac2
JA
3708 char buf[128];
3709 long l;
3710
a4cfc477 3711 sprintf(buf, "%lu", (unsigned long) page_size);
74929ac2
JA
3712 fio_keywords[0].replace = strdup(buf);
3713
8eb016d3 3714 mb_memory = os_phys_mem() / (1024 * 1024);
3b2e1464 3715 sprintf(buf, "%llu", mb_memory);
74929ac2
JA
3716 fio_keywords[1].replace = strdup(buf);
3717
c00a2289 3718 l = cpus_online();
74929ac2
JA
3719 sprintf(buf, "%lu", l);
3720 fio_keywords[2].replace = strdup(buf);
3721}
3722
892a6ffc
JA
3723#define BC_APP "bc"
3724
3725static char *bc_calc(char *str)
3726{
d0c814ec 3727 char buf[128], *tmp;
892a6ffc
JA
3728 FILE *f;
3729 int ret;
3730
3731 /*
3732 * No math, just return string
3733 */
d0c814ec
SL
3734 if ((!strchr(str, '+') && !strchr(str, '-') && !strchr(str, '*') &&
3735 !strchr(str, '/')) || strchr(str, '\''))
892a6ffc
JA
3736 return str;
3737
3738 /*
3739 * Split option from value, we only need to calculate the value
3740 */
3741 tmp = strchr(str, '=');
3742 if (!tmp)
3743 return str;
3744
3745 tmp++;
892a6ffc 3746
d0c814ec
SL
3747 /*
3748 * Prevent buffer overflows; such a case isn't reasonable anyway
3749 */
3750 if (strlen(str) >= 128 || strlen(tmp) > 100)
3751 return str;
892a6ffc
JA
3752
3753 sprintf(buf, "which %s > /dev/null", BC_APP);
3754 if (system(buf)) {
3755 log_err("fio: bc is needed for performing math\n");
892a6ffc
JA
3756 return NULL;
3757 }
3758
d0c814ec 3759 sprintf(buf, "echo '%s' | %s", tmp, BC_APP);
892a6ffc 3760 f = popen(buf, "r");
3c3ed070 3761 if (!f)
892a6ffc 3762 return NULL;
892a6ffc 3763
d0c814ec 3764 ret = fread(&buf[tmp - str], 1, 128 - (tmp - str), f);
1d824f37
JA
3765 if (ret <= 0) {
3766 pclose(f);
892a6ffc 3767 return NULL;
1d824f37 3768 }
892a6ffc 3769
892a6ffc 3770 pclose(f);
d0c814ec
SL
3771 buf[(tmp - str) + ret - 1] = '\0';
3772 memcpy(buf, str, tmp - str);
892a6ffc 3773 free(str);
d0c814ec
SL
3774 return strdup(buf);
3775}
3776
3777/*
3778 * Return a copy of the input string with substrings of the form ${VARNAME}
3779 * substituted with the value of the environment variable VARNAME. The
3780 * substitution always occurs, even if VARNAME is empty or the corresponding
3781 * environment variable undefined.
3782 */
3783static char *option_dup_subs(const char *opt)
3784{
3785 char out[OPT_LEN_MAX+1];
3786 char in[OPT_LEN_MAX+1];
3787 char *outptr = out;
3788 char *inptr = in;
3789 char *ch1, *ch2, *env;
3790 ssize_t nchr = OPT_LEN_MAX;
3791 size_t envlen;
3792
3793 if (strlen(opt) + 1 > OPT_LEN_MAX) {
3794 log_err("OPT_LEN_MAX (%d) is too small\n", OPT_LEN_MAX);
3795 return NULL;
3796 }
3797
3798 in[OPT_LEN_MAX] = '\0';
3799 strncpy(in, opt, OPT_LEN_MAX);
3800
3801 while (*inptr && nchr > 0) {
3802 if (inptr[0] == '$' && inptr[1] == '{') {
3803 ch2 = strchr(inptr, '}');
3804 if (ch2 && inptr+1 < ch2) {
3805 ch1 = inptr+2;
3806 inptr = ch2+1;
3807 *ch2 = '\0';
3808
3809 env = getenv(ch1);
3810 if (env) {
3811 envlen = strlen(env);
3812 if (envlen <= nchr) {
3813 memcpy(outptr, env, envlen);
3814 outptr += envlen;
3815 nchr -= envlen;
3816 }
3817 }
3818
3819 continue;
3820 }
3821 }
3822
3823 *outptr++ = *inptr++;
3824 --nchr;
3825 }
3826
3827 *outptr = '\0';
3828 return strdup(out);
892a6ffc
JA
3829}
3830
74929ac2
JA
3831/*
3832 * Look for reserved variable names and replace them with real values
3833 */
3834static char *fio_keyword_replace(char *opt)
3835{
3836 char *s;
3837 int i;
d0c814ec 3838 int docalc = 0;
74929ac2
JA
3839
3840 for (i = 0; fio_keywords[i].word != NULL; i++) {
3841 struct fio_keyword *kw = &fio_keywords[i];
3842
3843 while ((s = strstr(opt, kw->word)) != NULL) {
3844 char *new = malloc(strlen(opt) + 1);
3845 char *o_org = opt;
3846 int olen = s - opt;
3847 int len;
3848
3849 /*
3850 * Copy part of the string before the keyword and
3851 * sprintf() the replacement after it.
3852 */
3853 memcpy(new, opt, olen);
3854 len = sprintf(new + olen, "%s", kw->replace);
3855
3856 /*
3857 * If there's more in the original string, copy that
3858 * in too
3859 */
3860 opt += strlen(kw->word) + olen;
3861 if (strlen(opt))
3862 memcpy(new + olen + len, opt, opt - o_org - 1);
3863
3864 /*
3865 * replace opt and free the old opt
3866 */
3867 opt = new;
d0c814ec 3868 free(o_org);
7a958bd5 3869
d0c814ec 3870 docalc = 1;
74929ac2
JA
3871 }
3872 }
3873
d0c814ec
SL
3874 /*
3875 * Check for potential math and invoke bc, if possible
3876 */
3877 if (docalc)
3878 opt = bc_calc(opt);
3879
7a958bd5 3880 return opt;
74929ac2
JA
3881}
3882
d0c814ec
SL
3883static char **dup_and_sub_options(char **opts, int num_opts)
3884{
3885 int i;
3886 char **opts_copy = malloc(num_opts * sizeof(*opts));
3887 for (i = 0; i < num_opts; i++) {
3888 opts_copy[i] = option_dup_subs(opts[i]);
3889 if (!opts_copy[i])
3890 continue;
3891 opts_copy[i] = fio_keyword_replace(opts_copy[i]);
3892 }
3893 return opts_copy;
3894}
3895
e15b023b 3896static void show_closest_option(const char *opt)
a2d027b9
JA
3897{
3898 int best_option, best_distance;
3899 int i, distance;
e15b023b
JA
3900 char *name;
3901
3902 if (!strlen(opt))
3903 return;
3904
3905 name = strdup(opt);
3906 i = 0;
3907 while (name[i] != '\0' && name[i] != '=')
3908 i++;
3909 name[i] = '\0';
a2d027b9
JA
3910
3911 best_option = -1;
3912 best_distance = INT_MAX;
3913 i = 0;
3914 while (fio_options[i].name) {
3915 distance = string_distance(name, fio_options[i].name);
3916 if (distance < best_distance) {
3917 best_distance = distance;
3918 best_option = i;
3919 }
3920 i++;
3921 }
3922
3701636d 3923 if (best_option != -1 && string_distance_ok(name, best_distance))
a2d027b9 3924 log_err("Did you mean %s?\n", fio_options[best_option].name);
e15b023b
JA
3925
3926 free(name);
a2d027b9
JA
3927}
3928
c2292325 3929int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
214e1eca 3930{
de890a1e 3931 int i, ret, unknown;
d0c814ec 3932 char **opts_copy;
3b8b7135 3933
9af4a244 3934 sort_options(opts, fio_options, num_opts);
d0c814ec 3935 opts_copy = dup_and_sub_options(opts, num_opts);
3b8b7135 3936
de890a1e
SL
3937 for (ret = 0, i = 0, unknown = 0; i < num_opts; i++) {
3938 struct fio_option *o;
9af4a244 3939 int newret = parse_option(opts_copy[i], opts[i], fio_options,
66e19a38 3940 &o, td, &td->opt_list);
d0c814ec 3941
a8523a6a
JA
3942 if (!newret && o)
3943 fio_option_mark_set(&td->o, o);
3944
de890a1e
SL
3945 if (opts_copy[i]) {
3946 if (newret && !o) {
3947 unknown++;
3948 continue;
3949 }
d0c814ec 3950 free(opts_copy[i]);
de890a1e
SL
3951 opts_copy[i] = NULL;
3952 }
3953
3954 ret |= newret;
3955 }
3956
3957 if (unknown) {
3958 ret |= ioengine_load(td);
3959 if (td->eo) {
3960 sort_options(opts_copy, td->io_ops->options, num_opts);
3961 opts = opts_copy;
3962 }
3963 for (i = 0; i < num_opts; i++) {
3964 struct fio_option *o = NULL;
3965 int newret = 1;
a2d027b9 3966
de890a1e
SL
3967 if (!opts_copy[i])
3968 continue;
3969
3970 if (td->eo)
3971 newret = parse_option(opts_copy[i], opts[i],
3972 td->io_ops->options, &o,
66e19a38 3973 td->eo, &td->opt_list);
de890a1e
SL
3974
3975 ret |= newret;
a2d027b9 3976 if (!o) {
de890a1e 3977 log_err("Bad option <%s>\n", opts[i]);
a2d027b9
JA
3978 show_closest_option(opts[i]);
3979 }
de890a1e
SL
3980 free(opts_copy[i]);
3981 opts_copy[i] = NULL;
3982 }
74929ac2 3983 }
3b8b7135 3984
d0c814ec 3985 free(opts_copy);
3b8b7135 3986 return ret;
214e1eca
JA
3987}
3988
3989int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val)
3990{
a8523a6a
JA
3991 int ret;
3992
d8b4f395 3993 ret = parse_cmd_option(opt, val, fio_options, td, &td->opt_list);
a8523a6a
JA
3994 if (!ret) {
3995 struct fio_option *o;
3996
3997 o = find_option(fio_options, opt);
3998 if (o)
3999 fio_option_mark_set(&td->o, o);
4000 }
4001
4002 return ret;
214e1eca
JA
4003}
4004
de890a1e
SL
4005int fio_cmd_ioengine_option_parse(struct thread_data *td, const char *opt,
4006 char *val)
4007{
d8b4f395
JA
4008 return parse_cmd_option(opt, val, td->io_ops->options, td->eo,
4009 &td->opt_list);
de890a1e
SL
4010}
4011
214e1eca
JA
4012void fio_fill_default_options(struct thread_data *td)
4013{
cb1402d6 4014 td->o.magic = OPT_MAGIC;
9af4a244 4015 fill_default_options(td, fio_options);
214e1eca
JA
4016}
4017
4018int fio_show_option_help(const char *opt)
4019{
9af4a244 4020 return show_cmd_help(fio_options, opt);
214e1eca 4021}
d23bb327 4022
de890a1e 4023void options_mem_dupe(void *data, struct fio_option *options)
d23bb327 4024{
de890a1e 4025 struct fio_option *o;
d23bb327 4026 char **ptr;
d23bb327 4027
de890a1e
SL
4028 for (o = &options[0]; o->name; o++) {
4029 if (o->type != FIO_OPT_STR_STORE)
d23bb327
JA
4030 continue;
4031
f0fdbcaf 4032 ptr = td_var(data, o, o->off1);
7e356b2d
JA
4033 if (*ptr)
4034 *ptr = strdup(*ptr);
d23bb327
JA
4035 }
4036}
4037
de890a1e
SL
4038/*
4039 * dupe FIO_OPT_STR_STORE options
4040 */
4041void fio_options_mem_dupe(struct thread_data *td)
4042{
9af4a244 4043 options_mem_dupe(&td->o, fio_options);
1647f592
JA
4044
4045 if (td->eo && td->io_ops) {
de890a1e 4046 void *oldeo = td->eo;
1647f592 4047
de890a1e
SL
4048 td->eo = malloc(td->io_ops->option_struct_size);
4049 memcpy(td->eo, oldeo, td->io_ops->option_struct_size);
4050 options_mem_dupe(td->eo, td->io_ops->options);
4051 }
4052}
4053
d6978a32
JA
4054unsigned int fio_get_kb_base(void *data)
4055{
83ea422a 4056 struct thread_options *o = data;
d6978a32
JA
4057 unsigned int kb_base = 0;
4058
cb1402d6
JA
4059 /*
4060 * This is a hack... For private options, *data is not holding
4061 * a pointer to the thread_options, but to private data. This means
4062 * we can't safely dereference it, but magic is first so mem wise
4063 * it is valid. But this also means that if the job first sets
4064 * kb_base and expects that to be honored by private options,
4065 * it will be disappointed. We will return the global default
4066 * for this.
4067 */
4068 if (o && o->magic == OPT_MAGIC)
83ea422a 4069 kb_base = o->kb_base;
d6978a32
JA
4070 if (!kb_base)
4071 kb_base = 1024;
4072
4073 return kb_base;
4074}
9f988e2e 4075
07b3232d 4076int add_option(struct fio_option *o)
9f988e2e 4077{
07b3232d
JA
4078 struct fio_option *__o;
4079 int opt_index = 0;
4080
9af4a244 4081 __o = fio_options;
07b3232d
JA
4082 while (__o->name) {
4083 opt_index++;
4084 __o++;
4085 }
4086
7b504edd
JA
4087 if (opt_index + 1 == FIO_MAX_OPTS) {
4088 log_err("fio: FIO_MAX_OPTS is too small\n");
4089 return 1;
4090 }
4091
9af4a244 4092 memcpy(&fio_options[opt_index], o, sizeof(*o));
7b504edd 4093 fio_options[opt_index + 1].name = NULL;
07b3232d 4094 return 0;
9f988e2e 4095}
e2de69da 4096
07b3232d 4097void invalidate_profile_options(const char *prof_name)
e2de69da 4098{
07b3232d 4099 struct fio_option *o;
e2de69da 4100
9af4a244 4101 o = fio_options;
07b3232d
JA
4102 while (o->name) {
4103 if (o->prof_name && !strcmp(o->prof_name, prof_name)) {
4104 o->type = FIO_OPT_INVALID;
4105 o->prof_name = NULL;
4106 }
4107 o++;
e2de69da
JA
4108 }
4109}
f5b6bb85
JA
4110
4111void add_opt_posval(const char *optname, const char *ival, const char *help)
4112{
4113 struct fio_option *o;
4114 unsigned int i;
4115
9af4a244 4116 o = find_option(fio_options, optname);
f5b6bb85
JA
4117 if (!o)
4118 return;
4119
4120 for (i = 0; i < PARSE_MAX_VP; i++) {
4121 if (o->posval[i].ival)
4122 continue;
4123
4124 o->posval[i].ival = ival;
4125 o->posval[i].help = help;
4126 break;
4127 }
4128}
4129
4130void del_opt_posval(const char *optname, const char *ival)
4131{
4132 struct fio_option *o;
4133 unsigned int i;
4134
9af4a244 4135 o = find_option(fio_options, optname);
f5b6bb85
JA
4136 if (!o)
4137 return;
4138
4139 for (i = 0; i < PARSE_MAX_VP; i++) {
4140 if (!o->posval[i].ival)
4141 continue;
4142 if (strcmp(o->posval[i].ival, ival))
4143 continue;
4144
4145 o->posval[i].ival = NULL;
4146 o->posval[i].help = NULL;
4147 }
4148}
7e356b2d
JA
4149
4150void fio_options_free(struct thread_data *td)
4151{
9af4a244 4152 options_free(fio_options, td);
de890a1e
SL
4153 if (td->eo && td->io_ops && td->io_ops->options) {
4154 options_free(td->io_ops->options, td->eo);
4155 free(td->eo);
4156 td->eo = NULL;
4157 }
7e356b2d 4158}
c504ee55
JA
4159
4160struct fio_option *fio_option_find(const char *name)
4161{
4162 return find_option(fio_options, name);
4163}
4164
f0e7f45a
JA
4165static struct fio_option *find_next_opt(struct thread_options *o,
4166 struct fio_option *from,
4167 unsigned int off1)
a8523a6a 4168{
f0e7f45a 4169 struct fio_option *opt;
a8523a6a 4170
f0e7f45a
JA
4171 if (!from)
4172 from = &fio_options[0];
4173 else
4174 from++;
4175
4176 opt = NULL;
4177 do {
4178 if (off1 == from->off1) {
4179 opt = from;
a8523a6a
JA
4180 break;
4181 }
f0e7f45a
JA
4182 from++;
4183 } while (from->name);
a8523a6a 4184
f0e7f45a
JA
4185 return opt;
4186}
4187
4188static int opt_is_set(struct thread_options *o, struct fio_option *opt)
4189{
4190 unsigned int opt_off, index, offset;
a8523a6a
JA
4191
4192 opt_off = opt - &fio_options[0];
4193 index = opt_off / (8 * sizeof(uint64_t));
4194 offset = opt_off & ((8 * sizeof(uint64_t)) - 1);
e9d686d6 4195 return (o->set_options[index] & ((uint64_t)1 << offset)) != 0;
a8523a6a
JA
4196}
4197
72f39748 4198bool __fio_option_is_set(struct thread_options *o, unsigned int off1)
f0e7f45a
JA
4199{
4200 struct fio_option *opt, *next;
4201
4202 next = NULL;
4203 while ((opt = find_next_opt(o, next, off1)) != NULL) {
4204 if (opt_is_set(o, opt))
72f39748 4205 return true;
f0e7f45a
JA
4206
4207 next = opt;
4208 }
4209
72f39748 4210 return false;
f0e7f45a
JA
4211}
4212
a8523a6a
JA
4213void fio_option_mark_set(struct thread_options *o, struct fio_option *opt)
4214{
4215 unsigned int opt_off, index, offset;
4216
4217 opt_off = opt - &fio_options[0];
4218 index = opt_off / (8 * sizeof(uint64_t));
4219 offset = opt_off & ((8 * sizeof(uint64_t)) - 1);
e9d686d6 4220 o->set_options[index] |= (uint64_t)1 << offset;
a8523a6a 4221}