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