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