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