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