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