96a03d984b08b602ec42e1ac987d90bde322b221
[fio.git] / init.c
1 /*
2  * This file contains job initialization and setup functions.
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <ctype.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <sys/ipc.h>
11 #include <sys/types.h>
12 #include <dlfcn.h>
13 #ifdef CONFIG_VALGRIND_DEV
14 #include <valgrind/drd.h>
15 #else
16 #define DRD_IGNORE_VAR(x) do { } while (0)
17 #endif
18
19 #include "fio.h"
20 #ifndef FIO_NO_HAVE_SHM_H
21 #include <sys/shm.h>
22 #endif
23
24 #include "parse.h"
25 #include "smalloc.h"
26 #include "filehash.h"
27 #include "verify.h"
28 #include "profile.h"
29 #include "server.h"
30 #include "idletime.h"
31 #include "filelock.h"
32 #include "steadystate.h"
33 #include "blktrace.h"
34
35 #include "oslib/asprintf.h"
36 #include "oslib/getopt.h"
37 #include "oslib/strcasestr.h"
38
39 #include "crc/test.h"
40 #include "lib/pow2.h"
41 #include "lib/memcpy.h"
42
43 const char fio_version_string[] = FIO_VERSION;
44
45 #define FIO_RANDSEED            (0xb1899bedUL)
46
47 static char **ini_file;
48 static bool dump_cmdline;
49 static bool parse_only;
50 static bool merge_blktrace_only;
51
52 static struct thread_data def_thread;
53 struct thread_segment segments[REAL_MAX_SEG];
54 static char **job_sections;
55 static int nr_job_sections;
56
57 bool exitall_on_terminate = false;
58 int output_format = FIO_OUTPUT_NORMAL;
59 int eta_print = FIO_ETA_AUTO;
60 unsigned int eta_interval_msec = 1000;
61 int eta_new_line = 0;
62 FILE *f_out = NULL;
63 FILE *f_err = NULL;
64 char *exec_profile = NULL;
65 int warnings_fatal = 0;
66 int terse_version = 3;
67 bool is_backend = false;
68 bool is_local_backend = false;
69 int nr_clients = 0;
70 bool log_syslog = false;
71
72 bool write_bw_log = false;
73 bool read_only = false;
74 int status_interval = 0;
75
76 char *trigger_file = NULL;
77 long long trigger_timeout = 0;
78 char *trigger_cmd = NULL;
79 char *trigger_remote_cmd = NULL;
80
81 char *aux_path = NULL;
82
83 static int prev_group_jobs;
84
85 unsigned long fio_debug = 0;
86 unsigned int fio_debug_jobno = -1;
87 unsigned int *fio_debug_jobp = NULL;
88 unsigned int *fio_warned = NULL;
89
90 static char cmd_optstr[256];
91 static bool did_arg;
92
93 #define FIO_CLIENT_FLAG         (1 << 16)
94
95 /*
96  * Command line options. These will contain the above, plus a few
97  * extra that only pertain to fio itself and not jobs.
98  */
99 static struct option l_opts[FIO_NR_OPTIONS] = {
100         {
101                 .name           = (char *) "output",
102                 .has_arg        = required_argument,
103                 .val            = 'o' | FIO_CLIENT_FLAG,
104         },
105         {
106                 .name           = (char *) "latency-log",
107                 .has_arg        = required_argument,
108                 .val            = 'l' | FIO_CLIENT_FLAG,
109         },
110         {
111                 .name           = (char *) "bandwidth-log",
112                 .has_arg        = no_argument,
113                 .val            = 'b' | FIO_CLIENT_FLAG,
114         },
115         {
116                 .name           = (char *) "minimal",
117                 .has_arg        = no_argument,
118                 .val            = 'm' | FIO_CLIENT_FLAG,
119         },
120         {
121                 .name           = (char *) "output-format",
122                 .has_arg        = required_argument,
123                 .val            = 'F' | FIO_CLIENT_FLAG,
124         },
125         {
126                 .name           = (char *) "append-terse",
127                 .has_arg        = optional_argument,
128                 .val            = 'f',
129         },
130         {
131                 .name           = (char *) "version",
132                 .has_arg        = no_argument,
133                 .val            = 'v' | FIO_CLIENT_FLAG,
134         },
135         {
136                 .name           = (char *) "help",
137                 .has_arg        = no_argument,
138                 .val            = 'h' | FIO_CLIENT_FLAG,
139         },
140         {
141                 .name           = (char *) "cmdhelp",
142                 .has_arg        = optional_argument,
143                 .val            = 'c' | FIO_CLIENT_FLAG,
144         },
145         {
146                 .name           = (char *) "enghelp",
147                 .has_arg        = optional_argument,
148                 .val            = 'i' | FIO_CLIENT_FLAG,
149         },
150         {
151                 .name           = (char *) "showcmd",
152                 .has_arg        = no_argument,
153                 .val            = 's' | FIO_CLIENT_FLAG,
154         },
155         {
156                 .name           = (char *) "readonly",
157                 .has_arg        = no_argument,
158                 .val            = 'r' | FIO_CLIENT_FLAG,
159         },
160         {
161                 .name           = (char *) "eta",
162                 .has_arg        = required_argument,
163                 .val            = 'e' | FIO_CLIENT_FLAG,
164         },
165         {
166                 .name           = (char *) "eta-interval",
167                 .has_arg        = required_argument,
168                 .val            = 'O' | FIO_CLIENT_FLAG,
169         },
170         {
171                 .name           = (char *) "eta-newline",
172                 .has_arg        = required_argument,
173                 .val            = 'E' | FIO_CLIENT_FLAG,
174         },
175         {
176                 .name           = (char *) "debug",
177                 .has_arg        = required_argument,
178                 .val            = 'd' | FIO_CLIENT_FLAG,
179         },
180         {
181                 .name           = (char *) "parse-only",
182                 .has_arg        = no_argument,
183                 .val            = 'P' | FIO_CLIENT_FLAG,
184         },
185         {
186                 .name           = (char *) "section",
187                 .has_arg        = required_argument,
188                 .val            = 'x' | FIO_CLIENT_FLAG,
189         },
190 #ifdef CONFIG_ZLIB
191         {
192                 .name           = (char *) "inflate-log",
193                 .has_arg        = required_argument,
194                 .val            = 'X' | FIO_CLIENT_FLAG,
195         },
196 #endif
197         {
198                 .name           = (char *) "alloc-size",
199                 .has_arg        = required_argument,
200                 .val            = 'a' | FIO_CLIENT_FLAG,
201         },
202         {
203                 .name           = (char *) "profile",
204                 .has_arg        = required_argument,
205                 .val            = 'p' | FIO_CLIENT_FLAG,
206         },
207         {
208                 .name           = (char *) "warnings-fatal",
209                 .has_arg        = no_argument,
210                 .val            = 'w' | FIO_CLIENT_FLAG,
211         },
212         {
213                 .name           = (char *) "max-jobs",
214                 .has_arg        = required_argument,
215                 .val            = 'j' | FIO_CLIENT_FLAG,
216         },
217         {
218                 .name           = (char *) "terse-version",
219                 .has_arg        = required_argument,
220                 .val            = 'V' | FIO_CLIENT_FLAG,
221         },
222         {
223                 .name           = (char *) "server",
224                 .has_arg        = optional_argument,
225                 .val            = 'S',
226         },
227 #ifdef WIN32
228         {
229                 .name           = (char *) "server-internal",
230                 .has_arg        = required_argument,
231                 .val            = 'N',
232         },
233 #endif
234         {       .name           = (char *) "daemonize",
235                 .has_arg        = required_argument,
236                 .val            = 'D',
237         },
238         {
239                 .name           = (char *) "client",
240                 .has_arg        = required_argument,
241                 .val            = 'C',
242         },
243         {
244                 .name           = (char *) "remote-config",
245                 .has_arg        = required_argument,
246                 .val            = 'R',
247         },
248         {
249                 .name           = (char *) "cpuclock-test",
250                 .has_arg        = no_argument,
251                 .val            = 'T',
252         },
253         {
254                 .name           = (char *) "crctest",
255                 .has_arg        = optional_argument,
256                 .val            = 'G',
257         },
258         {
259                 .name           = (char *) "memcpytest",
260                 .has_arg        = optional_argument,
261                 .val            = 'M',
262         },
263         {
264                 .name           = (char *) "idle-prof",
265                 .has_arg        = required_argument,
266                 .val            = 'I',
267         },
268         {
269                 .name           = (char *) "status-interval",
270                 .has_arg        = required_argument,
271                 .val            = 'L' | FIO_CLIENT_FLAG,
272         },
273         {
274                 .name           = (char *) "trigger-file",
275                 .has_arg        = required_argument,
276                 .val            = 'W',
277         },
278         {
279                 .name           = (char *) "trigger-timeout",
280                 .has_arg        = required_argument,
281                 .val            = 'B',
282         },
283         {
284                 .name           = (char *) "trigger",
285                 .has_arg        = required_argument,
286                 .val            = 'H',
287         },
288         {
289                 .name           = (char *) "trigger-remote",
290                 .has_arg        = required_argument,
291                 .val            = 'J',
292         },
293         {
294                 .name           = (char *) "aux-path",
295                 .has_arg        = required_argument,
296                 .val            = 'K',
297         },
298         {
299                 .name           = (char *) "merge-blktrace-only",
300                 .has_arg        = no_argument,
301                 .val            = 'A' | FIO_CLIENT_FLAG,
302         },
303         {
304                 .name           = NULL,
305         },
306 };
307
308 void free_threads_shm(void)
309 {
310         int i;
311
312         for (i = 0; i < nr_segments; i++) {
313                 struct thread_segment *seg = &segments[i];
314
315                 if (seg->threads) {
316                         void *tp = seg->threads;
317 #ifndef CONFIG_NO_SHM
318                         struct shmid_ds sbuf;
319
320                         seg->threads = NULL;
321                         shmdt(tp);
322                         shmctl(seg->shm_id, IPC_RMID, &sbuf);
323                         seg->shm_id = -1;
324 #else
325                         seg->threads = NULL;
326                         free(tp);
327 #endif
328                 }
329         }
330
331         nr_segments = 0;
332         cur_segment = 0;
333 }
334
335 static void free_shm(void)
336 {
337 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
338         if (nr_segments) {
339                 flow_exit();
340                 fio_debug_jobp = NULL;
341                 fio_warned = NULL;
342                 free_threads_shm();
343         }
344
345         free(trigger_file);
346         free(trigger_cmd);
347         free(trigger_remote_cmd);
348         trigger_file = trigger_cmd = trigger_remote_cmd = NULL;
349
350         options_free(fio_options, &def_thread.o);
351         fio_filelock_exit();
352         file_hash_exit();
353         scleanup();
354 #endif
355 }
356
357 static int add_thread_segment(void)
358 {
359         struct thread_segment *seg = &segments[nr_segments];
360         size_t size = JOBS_PER_SEG * sizeof(struct thread_data);
361         int i;
362
363         if (nr_segments + 1 >= REAL_MAX_SEG) {
364                 log_err("error: maximum number of jobs reached.\n");
365                 return -1;
366         }
367
368         size += 2 * sizeof(unsigned int);
369
370 #ifndef CONFIG_NO_SHM
371         seg->shm_id = shmget(0, size, IPC_CREAT | 0600);
372         if (seg->shm_id == -1) {
373                 if (errno != EINVAL && errno != ENOMEM && errno != ENOSPC)
374                         perror("shmget");
375                 return -1;
376         }
377 #else
378         seg->threads = malloc(size);
379         if (!seg->threads)
380                 return -1;
381 #endif
382
383 #ifndef CONFIG_NO_SHM
384         seg->threads = shmat(seg->shm_id, NULL, 0);
385         if (seg->threads == (void *) -1) {
386                 perror("shmat");
387                 return 1;
388         }
389         if (shm_attach_to_open_removed())
390                 shmctl(seg->shm_id, IPC_RMID, NULL);
391 #endif
392
393         nr_segments++;
394
395         memset(seg->threads, 0, JOBS_PER_SEG * sizeof(struct thread_data));
396         for (i = 0; i < JOBS_PER_SEG; i++)
397                 DRD_IGNORE_VAR(seg->threads[i]);
398         seg->nr_threads = 0;
399
400         /* Not first segment, we're done */
401         if (nr_segments != 1) {
402                 cur_segment++;
403                 return 0;
404         }
405
406         fio_debug_jobp = (unsigned int *)(seg->threads + JOBS_PER_SEG);
407         *fio_debug_jobp = -1;
408         fio_warned = fio_debug_jobp + 1;
409         *fio_warned = 0;
410
411         flow_init();
412         return 0;
413 }
414
415 /*
416  * The thread areas are shared between the main process and the job
417  * threads/processes, and is split into chunks of JOBS_PER_SEG. If the current
418  * segment has no more room, add a new chunk.
419  */
420 static int expand_thread_area(void)
421 {
422         struct thread_segment *seg = &segments[cur_segment];
423
424         if (nr_segments && seg->nr_threads < JOBS_PER_SEG)
425                 return 0;
426
427         return add_thread_segment();
428 }
429
430 static void dump_print_option(struct print_option *p)
431 {
432         const char *delim;
433
434         if (!strcmp("description", p->name))
435                 delim = "\"";
436         else
437                 delim = "";
438
439         log_info("--%s%s", p->name, p->value ? "" : " ");
440         if (p->value)
441                 log_info("=%s%s%s ", delim, p->value, delim);
442 }
443
444 static void dump_opt_list(struct thread_data *td)
445 {
446         struct flist_head *entry;
447         struct print_option *p;
448
449         if (flist_empty(&td->opt_list))
450                 return;
451
452         flist_for_each(entry, &td->opt_list) {
453                 p = flist_entry(entry, struct print_option, list);
454                 dump_print_option(p);
455         }
456 }
457
458 static void copy_opt_list(struct thread_data *dst, struct thread_data *src)
459 {
460         struct flist_head *entry;
461
462         if (flist_empty(&src->opt_list))
463                 return;
464
465         flist_for_each(entry, &src->opt_list) {
466                 struct print_option *srcp, *dstp;
467
468                 srcp = flist_entry(entry, struct print_option, list);
469                 dstp = malloc(sizeof(*dstp));
470                 dstp->name = strdup(srcp->name);
471                 if (srcp->value)
472                         dstp->value = strdup(srcp->value);
473                 else
474                         dstp->value = NULL;
475                 flist_add_tail(&dstp->list, &dst->opt_list);
476         }
477 }
478
479 /*
480  * Return a free job structure.
481  */
482 static struct thread_data *get_new_job(bool global, struct thread_data *parent,
483                                        bool preserve_eo, const char *jobname)
484 {
485         struct thread_segment *seg;
486         struct thread_data *td;
487
488         if (global)
489                 return &def_thread;
490         if (expand_thread_area()) {
491                 log_err("error: failed to setup shm segment\n");
492                 return NULL;
493         }
494
495         seg = &segments[cur_segment];
496         td = &seg->threads[seg->nr_threads++];
497         thread_number++;
498         *td = *parent;
499
500         INIT_FLIST_HEAD(&td->opt_list);
501         if (parent != &def_thread)
502                 copy_opt_list(td, parent);
503
504         td->io_ops = NULL;
505         td->io_ops_init = 0;
506         if (!preserve_eo)
507                 td->eo = NULL;
508
509         td->o.uid = td->o.gid = -1U;
510
511         dup_files(td, parent);
512         fio_options_mem_dupe(td);
513
514         profile_add_hooks(td);
515
516         td->thread_number = thread_number;
517         td->subjob_number = 0;
518
519         if (jobname)
520                 td->o.name = strdup(jobname);
521
522         if (!parent->o.group_reporting || parent == &def_thread)
523                 stat_number++;
524
525         return td;
526 }
527
528 static void put_job(struct thread_data *td)
529 {
530         if (td == &def_thread)
531                 return;
532
533         profile_td_exit(td);
534         flow_exit_job(td);
535
536         if (td->error)
537                 log_info("fio: %s\n", td->verror);
538
539         fio_options_free(td);
540         fio_dump_options_free(td);
541         if (td->io_ops)
542                 free_ioengine(td);
543
544         if (td->o.name)
545                 free(td->o.name);
546
547         memset(td, 0, sizeof(*td));
548         segments[cur_segment].nr_threads--;
549         thread_number--;
550 }
551
552 static int __setup_rate(struct thread_data *td, enum fio_ddir ddir)
553 {
554         unsigned long long bs = td->o.min_bs[ddir];
555
556         assert(ddir_rw(ddir));
557
558         if (td->o.rate[ddir])
559                 td->rate_bps[ddir] = td->o.rate[ddir];
560         else
561                 td->rate_bps[ddir] = (uint64_t) td->o.rate_iops[ddir] * bs;
562
563         if (!td->rate_bps[ddir]) {
564                 log_err("rate lower than supported\n");
565                 return -1;
566         }
567
568         td->rate_next_io_time[ddir] = 0;
569         td->rate_io_issue_bytes[ddir] = 0;
570         td->last_usec[ddir] = 0;
571         return 0;
572 }
573
574 static int setup_rate(struct thread_data *td)
575 {
576         int ret = 0;
577
578         for_each_rw_ddir(ddir) {
579                 if (td->o.rate[ddir] || td->o.rate_iops[ddir]) {
580                         ret |= __setup_rate(td, ddir);
581                 }
582         }
583         return ret;
584 }
585
586 static int fixed_block_size(struct thread_options *o)
587 {
588         return o->min_bs[DDIR_READ] == o->max_bs[DDIR_READ] &&
589                 o->min_bs[DDIR_WRITE] == o->max_bs[DDIR_WRITE] &&
590                 o->min_bs[DDIR_TRIM] == o->max_bs[DDIR_TRIM] &&
591                 o->min_bs[DDIR_READ] == o->min_bs[DDIR_WRITE] &&
592                 o->min_bs[DDIR_READ] == o->min_bs[DDIR_TRIM];
593 }
594
595 /*
596  * <3 Johannes
597  */
598 static unsigned int gcd(unsigned int m, unsigned int n)
599 {
600         if (!n)
601                 return m;
602
603         return gcd(n, m % n);
604 }
605
606 /*
607  * Lazy way of fixing up options that depend on each other. We could also
608  * define option callback handlers, but this is easier.
609  */
610 static int fixup_options(struct thread_data *td)
611 {
612         struct thread_options *o = &td->o;
613         int ret = 0;
614
615         if (read_only && (td_write(td) || td_trim(td))) {
616                 log_err("fio: trim and write operations are not allowed"
617                          " with the --readonly parameter.\n");
618                 ret |= 1;
619         }
620
621         if (td_trimwrite(td) && o->num_range > 1) {
622                 log_err("fio: trimwrite cannot be used with multiple"
623                         " ranges.\n");
624                 ret |= 1;
625         }
626
627         if (td_trim(td) && o->num_range > 1 &&
628             !td_ioengine_flagged(td, FIO_MULTI_RANGE_TRIM)) {
629                 log_err("fio: can't use multiple ranges with IO engine %s\n",
630                         td->io_ops->name);
631                 ret |= 1;
632         }
633
634 #ifndef CONFIG_PSHARED
635         if (!o->use_thread) {
636                 log_info("fio: this platform does not support process shared"
637                          " mutexes, forcing use of threads. Use the 'thread'"
638                          " option to get rid of this warning.\n");
639                 o->use_thread = 1;
640                 ret |= warnings_fatal;
641         }
642 #endif
643
644         if (o->write_iolog_file && o->read_iolog_file) {
645                 log_err("fio: read iolog overrides write_iolog\n");
646                 free(o->write_iolog_file);
647                 o->write_iolog_file = NULL;
648                 ret |= warnings_fatal;
649         }
650
651         if (o->zone_mode == ZONE_MODE_NONE && o->zone_size) {
652                 log_err("fio: --zonemode=none and --zonesize are not compatible.\n");
653                 ret |= 1;
654         }
655
656         if (o->zone_mode == ZONE_MODE_ZBD && !o->create_serialize) {
657                 log_err("fio: --zonemode=zbd and --create_serialize=0 are not compatible.\n");
658                 ret |= 1;
659         }
660
661         if (o->zone_mode == ZONE_MODE_STRIDED && !o->zone_size) {
662                 log_err("fio: --zonesize must be specified when using --zonemode=strided.\n");
663                 ret |= 1;
664         }
665
666         if (o->zone_mode == ZONE_MODE_NOT_SPECIFIED) {
667                 if (o->zone_size)
668                         o->zone_mode = ZONE_MODE_STRIDED;
669                 else
670                         o->zone_mode = ZONE_MODE_NONE;
671         }
672
673         /*
674          * Strided zone mode only really works with 1 file.
675          */
676         if (o->zone_mode == ZONE_MODE_STRIDED && o->open_files > 1)
677                 o->zone_mode = ZONE_MODE_NONE;
678
679         /*
680          * If zone_range isn't specified, backward compatibility dictates it
681          * should be made equal to zone_size.
682          */
683         if (o->zone_mode == ZONE_MODE_STRIDED && !o->zone_range)
684                 o->zone_range = o->zone_size;
685
686         /*
687          * Reads can do overwrites, we always need to pre-create the file
688          */
689         if (td_read(td))
690                 o->overwrite = 1;
691
692         for_each_rw_ddir(ddir) {
693                 if (!o->min_bs[ddir])
694                         o->min_bs[ddir] = o->bs[ddir];
695                 if (!o->max_bs[ddir])
696                         o->max_bs[ddir] = o->bs[ddir];
697         }
698
699         o->rw_min_bs = -1;
700         for_each_rw_ddir(ddir) {
701                 o->rw_min_bs = min(o->rw_min_bs, o->min_bs[ddir]);
702         }
703
704         /*
705          * For random IO, allow blockalign offset other than min_bs.
706          */
707         for_each_rw_ddir(ddir) {
708                 if (!o->ba[ddir] || !td_random(td))
709                         o->ba[ddir] = o->min_bs[ddir];
710         }
711
712         if ((o->ba[DDIR_READ] != o->min_bs[DDIR_READ] ||
713             o->ba[DDIR_WRITE] != o->min_bs[DDIR_WRITE] ||
714             o->ba[DDIR_TRIM] != o->min_bs[DDIR_TRIM]) &&
715             !o->norandommap) {
716                 log_err("fio: Any use of blockalign= turns off randommap\n");
717                 o->norandommap = 1;
718                 ret |= warnings_fatal;
719         }
720
721         if (!o->file_size_high)
722                 o->file_size_high = o->file_size_low;
723
724         if (o->start_delay_high) {
725                 if (!o->start_delay_orig)
726                         o->start_delay_orig = o->start_delay;
727                 o->start_delay = rand_between(&td->delay_state,
728                                                 o->start_delay_orig,
729                                                 o->start_delay_high);
730         }
731
732         if (o->norandommap && o->verify != VERIFY_NONE
733             && !fixed_block_size(o))  {
734                 log_err("fio: norandommap given for variable block sizes, "
735                         "verify limited\n");
736                 ret |= warnings_fatal;
737         }
738         if (o->bs_unaligned && (o->odirect || td_ioengine_flagged(td, FIO_RAWIO)))
739                 log_err("fio: bs_unaligned may not work with raw io\n");
740
741         /*
742          * thinktime_spin must be less than thinktime
743          */
744         if (o->thinktime_spin > o->thinktime)
745                 o->thinktime_spin = o->thinktime;
746
747         /*
748          * The low water mark cannot be bigger than the iodepth
749          */
750         if (o->iodepth_low > o->iodepth || !o->iodepth_low)
751                 o->iodepth_low = o->iodepth;
752
753         /*
754          * If batch number isn't set, default to the same as iodepth
755          */
756         if (o->iodepth_batch > o->iodepth || !o->iodepth_batch)
757                 o->iodepth_batch = o->iodepth;
758
759         /*
760          * If max batch complete number isn't set or set incorrectly,
761          * default to the same as iodepth_batch_complete_min
762          */
763         if (o->iodepth_batch_complete_min > o->iodepth_batch_complete_max)
764                 o->iodepth_batch_complete_max = o->iodepth_batch_complete_min;
765
766         /*
767          * There's no need to check for in-flight overlapping IOs if the job
768          * isn't changing data or the maximum iodepth is guaranteed to be 1
769          * when we are not in offload mode
770          */
771         if (o->serialize_overlap && !(td->flags & TD_F_READ_IOLOG) &&
772             (!(td_write(td) || td_trim(td)) || o->iodepth == 1) &&
773             o->io_submit_mode != IO_MODE_OFFLOAD)
774                 o->serialize_overlap = 0;
775
776         if (o->nr_files > td->files_index)
777                 o->nr_files = td->files_index;
778
779         if (o->open_files > o->nr_files || !o->open_files)
780                 o->open_files = o->nr_files;
781
782         if (((o->rate[DDIR_READ] + o->rate[DDIR_WRITE] + o->rate[DDIR_TRIM]) &&
783             (o->rate_iops[DDIR_READ] + o->rate_iops[DDIR_WRITE] + o->rate_iops[DDIR_TRIM])) ||
784             ((o->ratemin[DDIR_READ] + o->ratemin[DDIR_WRITE] + o->ratemin[DDIR_TRIM]) &&
785             (o->rate_iops_min[DDIR_READ] + o->rate_iops_min[DDIR_WRITE] + o->rate_iops_min[DDIR_TRIM]))) {
786                 log_err("fio: rate and rate_iops are mutually exclusive\n");
787                 ret |= 1;
788         }
789         for_each_rw_ddir(ddir) {
790                 if ((o->rate[ddir] && (o->rate[ddir] < o->ratemin[ddir])) ||
791                     (o->rate_iops[ddir] && (o->rate_iops[ddir] < o->rate_iops_min[ddir]))) {
792                         log_err("fio: minimum rate exceeds rate, ddir %d\n", +ddir);
793                         ret |= 1;
794                 }
795         }
796
797         if (!o->timeout && o->time_based) {
798                 log_err("fio: time_based requires a runtime/timeout setting\n");
799                 o->time_based = 0;
800                 ret |= warnings_fatal;
801         }
802
803         if (o->fill_device && !o->size)
804                 o->size = -1ULL;
805
806         if (o->verify != VERIFY_NONE) {
807                 if (td_write(td) && o->do_verify && o->numjobs > 1 &&
808                     (o->filename ||
809                      !(o->unique_filename &&
810                        strstr(o->filename_format, "$jobname") &&
811                        strstr(o->filename_format, "$jobnum") &&
812                        strstr(o->filename_format, "$filenum")))) {
813                         log_info("fio: multiple writers may overwrite blocks "
814                                 "that belong to other jobs. This can cause "
815                                 "verification failures.\n");
816                         ret |= warnings_fatal;
817                 }
818
819                 /*
820                  * Warn if verification is requested but no verification of any
821                  * kind can be started due to time constraints
822                  */
823                 if (td_write(td) && o->do_verify && o->timeout &&
824                     o->time_based && !td_read(td) && !o->verify_backlog) {
825                         log_info("fio: verification read phase will never "
826                                  "start because write phase uses all of "
827                                  "runtime\n");
828                         ret |= warnings_fatal;
829                 }
830
831                 if (!fio_option_is_set(o, refill_buffers))
832                         o->refill_buffers = 1;
833
834                 if (o->max_bs[DDIR_WRITE] != o->min_bs[DDIR_WRITE] &&
835                     !o->verify_interval)
836                         o->verify_interval = o->min_bs[DDIR_WRITE];
837
838                 /*
839                  * Verify interval must be smaller or equal to the
840                  * write size.
841                  */
842                 if (o->verify_interval > o->min_bs[DDIR_WRITE])
843                         o->verify_interval = o->min_bs[DDIR_WRITE];
844                 else if (td_read(td) && o->verify_interval > o->min_bs[DDIR_READ])
845                         o->verify_interval = o->min_bs[DDIR_READ];
846
847                 /*
848                  * Verify interval must be a factor of both min and max
849                  * write size
850                  */
851                 if (!o->verify_interval ||
852                     (o->min_bs[DDIR_WRITE] % o->verify_interval) ||
853                     (o->max_bs[DDIR_WRITE] % o->verify_interval))
854                         o->verify_interval = gcd(o->min_bs[DDIR_WRITE],
855                                                         o->max_bs[DDIR_WRITE]);
856
857                 if (td->o.verify_only)
858                         o->verify_write_sequence = 0;
859         }
860
861         if (td->o.oatomic) {
862                 if (!td_ioengine_flagged(td, FIO_ATOMICWRITES)) {
863                         log_err("fio: engine does not support atomic writes\n");
864                         td->o.oatomic = 0;
865                         ret |= 1;
866                 }
867
868                 if (!td_write(td))
869                         td->o.oatomic = 0;
870         }
871
872         if (o->pre_read) {
873                 if (o->invalidate_cache)
874                         o->invalidate_cache = 0;
875                 if (td_ioengine_flagged(td, FIO_PIPEIO)) {
876                         log_info("fio: cannot pre-read files with an IO engine"
877                                  " that isn't seekable. Pre-read disabled.\n");
878                         ret |= warnings_fatal;
879                 }
880         }
881
882         if (o->unit_base == N2S_NONE) {
883                 if (td_ioengine_flagged(td, FIO_BIT_BASED))
884                         o->unit_base = N2S_BITPERSEC;
885                 else
886                         o->unit_base = N2S_BYTEPERSEC;
887         }
888
889 #ifndef CONFIG_FDATASYNC
890         if (o->fdatasync_blocks) {
891                 log_info("fio: this platform does not support fdatasync()"
892                          " falling back to using fsync().  Use the 'fsync'"
893                          " option instead of 'fdatasync' to get rid of"
894                          " this warning\n");
895                 o->fsync_blocks = o->fdatasync_blocks;
896                 o->fdatasync_blocks = 0;
897                 ret |= warnings_fatal;
898         }
899 #endif
900
901 #ifdef WIN32
902         /*
903          * Windows doesn't support O_DIRECT or O_SYNC with the _open interface,
904          * so fail if we're passed those flags
905          */
906         if (td_ioengine_flagged(td, FIO_SYNCIO) && (o->odirect || o->sync_io)) {
907                 log_err("fio: Windows does not support direct or non-buffered io with"
908                                 " the synchronous ioengines. Use the 'windowsaio' ioengine"
909                                 " with 'direct=1' and 'iodepth=1' instead.\n");
910                 ret |= 1;
911         }
912 #endif
913
914         /*
915          * For fully compressible data, just zero them at init time.
916          * It's faster than repeatedly filling it. For non-zero
917          * compression, we should have refill_buffers set. Set it, unless
918          * the job file already changed it.
919          */
920         if (o->compress_percentage) {
921                 if (o->compress_percentage == 100) {
922                         o->zero_buffers = 1;
923                         o->compress_percentage = 0;
924                 } else if (!fio_option_is_set(o, refill_buffers)) {
925                         o->refill_buffers = 1;
926                         td->flags |= TD_F_REFILL_BUFFERS;
927                 }
928         }
929
930         /*
931          * Using a non-uniform random distribution excludes usage of
932          * a random map
933          */
934         if (o->random_distribution != FIO_RAND_DIST_RANDOM)
935                 o->norandommap = 1;
936
937         /*
938          * If size is set but less than the min block size, complain
939          */
940         if (o->size && o->size < td_min_bs(td)) {
941                 log_err("fio: size too small, must not be less than minimum block size: %llu < %llu\n",
942                         (unsigned long long) o->size, td_min_bs(td));
943                 ret |= 1;
944         }
945
946         /*
947          * If randseed is set, that overrides randrepeat
948          */
949         if (fio_option_is_set(o, rand_seed))
950                 o->rand_repeatable = 0;
951
952         if (td_ioengine_flagged(td, FIO_NOEXTEND) && o->file_append) {
953                 log_err("fio: can't append/extent with IO engine %s\n", td->io_ops->name);
954                 ret |= 1;
955         }
956
957         if (fio_option_is_set(o, gtod_cpu)) {
958                 fio_gtod_init();
959                 fio_gtod_set_cpu(o->gtod_cpu);
960                 fio_gtod_offload = 1;
961         }
962
963         td->loops = o->loops;
964         if (!td->loops)
965                 td->loops = 1;
966
967         if (o->block_error_hist && o->nr_files != 1) {
968                 log_err("fio: block error histogram only available "
969                         "with a single file per job, but %d files "
970                         "provided\n", o->nr_files);
971                 ret |= 1;
972         }
973
974         if (o->disable_lat)
975                 o->lat_percentiles = 0;
976         if (o->disable_clat)
977                 o->clat_percentiles = 0;
978         if (o->disable_slat)
979                 o->slat_percentiles = 0;
980
981         /* Do this only for the parent job */
982         if (!td->subjob_number) {
983                 /*
984                  * Fix these up to be nsec internally
985                  */
986                 for_each_rw_ddir(ddir)
987                         o->max_latency[ddir] *= 1000ULL;
988
989                 o->latency_target *= 1000ULL;
990         }
991
992         /*
993          * Dedupe working set verifications
994          */
995         if (o->dedupe_percentage && o->dedupe_mode == DEDUPE_MODE_WORKING_SET) {
996                 if (!fio_option_is_set(o, size)) {
997                         log_err("fio: pregenerated dedupe working set "
998                                         "requires size to be set\n");
999                         ret |= 1;
1000                 } else if (o->nr_files != 1) {
1001                         log_err("fio: dedupe working set mode supported with "
1002                                         "single file per job, but %d files "
1003                                         "provided\n", o->nr_files);
1004                         ret |= 1;
1005                 } else if (o->dedupe_working_set_percentage + o->dedupe_percentage > 100) {
1006                         log_err("fio: impossible to reach expected dedupe percentage %u "
1007                                         "since %u percentage of size is reserved to dedupe working set "
1008                                         "(those are unique pages)\n",
1009                                         o->dedupe_percentage, o->dedupe_working_set_percentage);
1010                         ret |= 1;
1011                 }
1012         }
1013
1014         for_each_td(td2) {
1015                 if (td->o.ss_check_interval != td2->o.ss_check_interval) {
1016                         log_err("fio: conflicting ss_check_interval: %llu and %llu, must be globally equal\n",
1017                                         td->o.ss_check_interval, td2->o.ss_check_interval);
1018                         ret |= 1;
1019                 }
1020         } end_for_each();
1021         if (td->o.ss_dur && td->o.ss_check_interval / 1000L < 1000) {
1022                 log_err("fio: ss_check_interval must be at least 1s\n");
1023                 ret |= 1;
1024
1025         }
1026         if (td->o.ss_dur && (td->o.ss_dur % td->o.ss_check_interval != 0 || td->o.ss_dur <= td->o.ss_check_interval)) {
1027                 log_err("fio: ss_duration %lluus must be multiple of ss_check_interval %lluus\n",
1028                                 td->o.ss_dur, td->o.ss_check_interval);
1029                 ret |= 1;
1030         }
1031
1032         if (td->o.fdp) {
1033                 if (fio_option_is_set(&td->o, dp_type) &&
1034                         (td->o.dp_type == FIO_DP_STREAMS || td->o.dp_type == FIO_DP_NONE)) {
1035                         log_err("fio: fdp=1 is not compatible with dataplacement={streams, none}\n");
1036                         ret |= 1;
1037                 } else {
1038                         td->o.dp_type = FIO_DP_FDP;
1039                 }
1040         }
1041         return ret;
1042 }
1043
1044 static void init_rand_file_service(struct thread_data *td)
1045 {
1046         unsigned long nranges = td->o.nr_files << FIO_FSERVICE_SHIFT;
1047         const unsigned int seed = td->rand_seeds[FIO_RAND_FILE_OFF];
1048
1049         if (td->o.file_service_type == FIO_FSERVICE_ZIPF) {
1050                 zipf_init(&td->next_file_zipf, nranges, td->zipf_theta, td->random_center, seed);
1051                 zipf_disable_hash(&td->next_file_zipf);
1052         } else if (td->o.file_service_type == FIO_FSERVICE_PARETO) {
1053                 pareto_init(&td->next_file_zipf, nranges, td->pareto_h, td->random_center, seed);
1054                 zipf_disable_hash(&td->next_file_zipf);
1055         } else if (td->o.file_service_type == FIO_FSERVICE_GAUSS) {
1056                 gauss_init(&td->next_file_gauss, nranges, td->gauss_dev, td->random_center, seed);
1057                 gauss_disable_hash(&td->next_file_gauss);
1058         }
1059 }
1060
1061 void td_fill_rand_seeds(struct thread_data *td)
1062 {
1063         uint64_t read_seed = td->rand_seeds[FIO_RAND_BS_OFF];
1064         uint64_t write_seed = td->rand_seeds[FIO_RAND_BS1_OFF];
1065         uint64_t trim_seed = td->rand_seeds[FIO_RAND_BS2_OFF];
1066         int i;
1067         bool use64;
1068
1069         if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
1070                 use64 = true;
1071         else
1072                 use64 = false;
1073
1074         /*
1075          * trimwrite is special in that we need to generate the same
1076          * offsets to get the "write after trim" effect. If we are
1077          * using bssplit to set buffer length distributions, ensure that
1078          * we seed the trim and write generators identically. Ditto for
1079          * verify, read and writes must have the same seed, if we are doing
1080          * read verify.
1081          */
1082         if (td->o.verify != VERIFY_NONE)
1083                 write_seed = read_seed;
1084         if (td_trimwrite(td))
1085                 trim_seed = write_seed;
1086         init_rand_seed(&td->bsrange_state[DDIR_READ], read_seed, use64);
1087         init_rand_seed(&td->bsrange_state[DDIR_WRITE], write_seed, use64);
1088         init_rand_seed(&td->bsrange_state[DDIR_TRIM], trim_seed, use64);
1089
1090         init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF],
1091                 use64);
1092         init_rand_seed(&td->rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF], false);
1093
1094         if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
1095                 init_rand_seed(&td->next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF], use64);
1096         else if (td->o.file_service_type & __FIO_FSERVICE_NONUNIFORM)
1097                 init_rand_file_service(td);
1098
1099         init_rand_seed(&td->file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], use64);
1100         init_rand_seed(&td->trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF], use64);
1101         init_rand_seed(&td->delay_state, td->rand_seeds[FIO_RAND_START_DELAY], use64);
1102         init_rand_seed(&td->poisson_state[0], td->rand_seeds[FIO_RAND_POISSON_OFF], 0);
1103         init_rand_seed(&td->poisson_state[1], td->rand_seeds[FIO_RAND_POISSON2_OFF], 0);
1104         init_rand_seed(&td->poisson_state[2], td->rand_seeds[FIO_RAND_POISSON3_OFF], 0);
1105         init_rand_seed(&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF], false);
1106         init_rand_seed(&td->zone_state, td->rand_seeds[FIO_RAND_ZONE_OFF], false);
1107         init_rand_seed(&td->prio_state, td->rand_seeds[FIO_RAND_PRIO_CMDS], false);
1108         init_rand_seed(&td->dedupe_working_set_index_state, td->rand_seeds[FIO_RAND_DEDUPE_WORKING_SET_IX], use64);
1109
1110         init_rand_seed(&td->random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF], use64);
1111
1112         for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1113                 struct frand_state *s = &td->seq_rand_state[i];
1114
1115                 init_rand_seed(s, td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF], false);
1116         }
1117
1118         init_rand_seed(&td->buf_state, td->rand_seeds[FIO_RAND_BUF_OFF], use64);
1119         frand_copy(&td->buf_state_prev, &td->buf_state);
1120
1121         init_rand_seed(&td->fdp_state, td->rand_seeds[FIO_RAND_FDP_OFF], use64);
1122 }
1123
1124 static int setup_random_seeds(struct thread_data *td)
1125 {
1126         uint64_t seed;
1127         unsigned int i;
1128
1129         if (!td->o.rand_repeatable && !fio_option_is_set(&td->o, rand_seed)) {
1130                 int ret = init_random_seeds(td->rand_seeds, sizeof(td->rand_seeds));
1131                 dprint(FD_RANDOM, "using system RNG for random seeds\n");
1132                 if (ret)
1133                         return ret;
1134         } else {
1135                 seed = td->o.rand_seed;
1136                 for (i = 0; i < 4; i++)
1137                         seed *= 0x9e370001UL;
1138
1139                 for (i = 0; i < FIO_RAND_NR_OFFS; i++) {
1140                         td->rand_seeds[i] = seed * td->thread_number + i;
1141                         seed *= 0x9e370001UL;
1142                 }
1143         }
1144
1145         td_fill_rand_seeds(td);
1146
1147         dprint(FD_RANDOM, "FIO_RAND_NR_OFFS=%d\n", FIO_RAND_NR_OFFS);
1148         for (int i = 0; i < FIO_RAND_NR_OFFS; i++)
1149                 dprint(FD_RANDOM, "rand_seeds[%d]=%" PRIu64 "\n", i, td->rand_seeds[i]);
1150
1151         return 0;
1152 }
1153
1154 /*
1155  * Initializes the ioengine configured for a job, if it has not been done so
1156  * already.
1157  */
1158 int ioengine_load(struct thread_data *td)
1159 {
1160         if (!td->o.ioengine) {
1161                 log_err("fio: internal fault, no IO engine specified\n");
1162                 return 1;
1163         }
1164
1165         if (td->io_ops) {
1166                 struct ioengine_ops *ops;
1167                 void *dlhandle;
1168
1169                 /* An engine is loaded, but the requested ioengine
1170                  * may have changed.
1171                  */
1172                 if (!strcmp(td->io_ops->name, td->o.ioengine)) {
1173                         /* The right engine is already loaded */
1174                         return 0;
1175                 }
1176
1177                 /*
1178                  * Name of file and engine may be different, load ops
1179                  * for this name and see if they match. If they do, then
1180                  * the engine is unchanged.
1181                  */
1182                 dlhandle = td->io_ops->dlhandle;
1183                 ops = load_ioengine(td);
1184                 if (!ops)
1185                         goto fail;
1186
1187                 if (ops == td->io_ops && dlhandle == td->io_ops->dlhandle)
1188                         return 0;
1189
1190                 if (dlhandle && dlhandle != td->io_ops->dlhandle)
1191                         dlclose(dlhandle);
1192
1193                 /* Unload the old engine. */
1194                 free_ioengine(td);
1195         }
1196
1197         td->io_ops = load_ioengine(td);
1198         if (!td->io_ops)
1199                 goto fail;
1200
1201         if (td->io_ops->option_struct_size && td->io_ops->options) {
1202                 /*
1203                  * In cases where td->eo is set, clone it for a child thread.
1204                  * This requires that the parent thread has the same ioengine,
1205                  * but that requirement must be enforced by the code which
1206                  * cloned the thread.
1207                  */
1208                 void *origeo = td->eo;
1209                 /*
1210                  * Otherwise use the default thread options.
1211                  */
1212                 if (!origeo && td != &def_thread && def_thread.eo &&
1213                     def_thread.io_ops->options == td->io_ops->options)
1214                         origeo = def_thread.eo;
1215
1216                 options_init(td->io_ops->options);
1217                 td->eo = malloc(td->io_ops->option_struct_size);
1218                 /*
1219                  * Use the default thread as an option template if this uses the
1220                  * same options structure and there are non-default options
1221                  * used.
1222                  */
1223                 if (origeo) {
1224                         memcpy(td->eo, origeo, td->io_ops->option_struct_size);
1225                         options_mem_dupe(td->io_ops->options, td->eo);
1226                 } else {
1227                         memset(td->eo, 0, td->io_ops->option_struct_size);
1228                         fill_default_options(td->eo, td->io_ops->options);
1229                 }
1230                 *(struct thread_data **)td->eo = td;
1231         }
1232
1233         if (td->o.odirect)
1234                 td->io_ops->flags |= FIO_RAWIO;
1235
1236         td_set_ioengine_flags(td);
1237         return 0;
1238
1239 fail:
1240         log_err("fio: failed to load engine\n");
1241         return 1;
1242
1243 }
1244
1245 static void init_flags(struct thread_data *td)
1246 {
1247         struct thread_options *o = &td->o;
1248         int i;
1249
1250         if (o->verify_backlog)
1251                 td->flags |= TD_F_VER_BACKLOG;
1252         if (o->trim_backlog)
1253                 td->flags |= TD_F_TRIM_BACKLOG;
1254         if (o->read_iolog_file)
1255                 td->flags |= TD_F_READ_IOLOG;
1256         if (o->refill_buffers)
1257                 td->flags |= TD_F_REFILL_BUFFERS;
1258         /*
1259          * Always scramble buffers if asked to
1260          */
1261         if (o->scramble_buffers && fio_option_is_set(o, scramble_buffers))
1262                 td->flags |= TD_F_SCRAMBLE_BUFFERS;
1263         /*
1264          * But also scramble buffers, unless we were explicitly asked
1265          * to zero them.
1266          */
1267         if (o->scramble_buffers && !(o->zero_buffers &&
1268             fio_option_is_set(o, zero_buffers)))
1269                 td->flags |= TD_F_SCRAMBLE_BUFFERS;
1270         if (o->verify != VERIFY_NONE)
1271                 td->flags |= TD_F_DO_VERIFY;
1272
1273         if (o->verify_async || o->io_submit_mode == IO_MODE_OFFLOAD)
1274                 td->flags |= TD_F_NEED_LOCK;
1275
1276         if (o->mem_type == MEM_CUDA_MALLOC)
1277                 td->flags &= ~TD_F_SCRAMBLE_BUFFERS;
1278
1279         for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1280                 if (option_check_rate(td, i)) {
1281                         td->flags |= TD_F_CHECK_RATE;
1282                         break;
1283                 }
1284         }
1285 }
1286
1287 enum {
1288         FPRE_NONE = 0,
1289         FPRE_JOBNAME,
1290         FPRE_JOBNUM,
1291         FPRE_FILENUM,
1292         FPRE_CLIENTUID
1293 };
1294
1295 static struct fpre_keyword {
1296         const char *keyword;
1297         size_t strlen;
1298         int key;
1299 } fpre_keywords[] = {
1300         { .keyword = "$jobname",        .key = FPRE_JOBNAME, },
1301         { .keyword = "$jobnum",         .key = FPRE_JOBNUM, },
1302         { .keyword = "$filenum",        .key = FPRE_FILENUM, },
1303         { .keyword = "$clientuid",      .key = FPRE_CLIENTUID, },
1304         { .keyword = NULL, },
1305         };
1306
1307 static char *make_filename(char *buf, size_t buf_size,struct thread_options *o,
1308                            const char *jobname, int jobnum, int filenum)
1309 {
1310         struct fpre_keyword *f;
1311         char copy[PATH_MAX];
1312         size_t dst_left = PATH_MAX - 1;
1313
1314         if (!o->filename_format || !strlen(o->filename_format)) {
1315                 sprintf(buf, "%s.%d.%d", jobname, jobnum, filenum);
1316                 return buf;
1317         }
1318
1319         for (f = &fpre_keywords[0]; f->keyword; f++)
1320                 f->strlen = strlen(f->keyword);
1321
1322         snprintf(buf, buf_size, "%s", o->filename_format);
1323
1324         memset(copy, 0, sizeof(copy));
1325         for (f = &fpre_keywords[0]; f->keyword; f++) {
1326                 do {
1327                         size_t pre_len, post_start = 0;
1328                         char *str, *dst = copy;
1329
1330                         str = strcasestr(buf, f->keyword);
1331                         if (!str)
1332                                 break;
1333
1334                         pre_len = str - buf;
1335                         if (strlen(str) != f->strlen)
1336                                 post_start = pre_len + f->strlen;
1337
1338                         if (pre_len) {
1339                                 strncpy(dst, buf, pre_len);
1340                                 dst += pre_len;
1341                                 dst_left -= pre_len;
1342                         }
1343
1344                         switch (f->key) {
1345                         case FPRE_JOBNAME: {
1346                                 int ret;
1347
1348                                 ret = snprintf(dst, dst_left, "%s", jobname);
1349                                 if (ret < 0)
1350                                         break;
1351                                 else if (ret > dst_left) {
1352                                         log_err("fio: truncated filename\n");
1353                                         dst += dst_left;
1354                                         dst_left = 0;
1355                                 } else {
1356                                         dst += ret;
1357                                         dst_left -= ret;
1358                                 }
1359                                 break;
1360                                 }
1361                         case FPRE_JOBNUM: {
1362                                 int ret;
1363
1364                                 ret = snprintf(dst, dst_left, "%d", jobnum);
1365                                 if (ret < 0)
1366                                         break;
1367                                 else if (ret > dst_left) {
1368                                         log_err("fio: truncated filename\n");
1369                                         dst += dst_left;
1370                                         dst_left = 0;
1371                                 } else {
1372                                         dst += ret;
1373                                         dst_left -= ret;
1374                                 }
1375                                 break;
1376                                 }
1377                         case FPRE_FILENUM: {
1378                                 int ret;
1379
1380                                 ret = snprintf(dst, dst_left, "%d", filenum);
1381                                 if (ret < 0)
1382                                         break;
1383                                 else if (ret > dst_left) {
1384                                         log_err("fio: truncated filename\n");
1385                                         dst += dst_left;
1386                                         dst_left = 0;
1387                                 } else {
1388                                         dst += ret;
1389                                         dst_left -= ret;
1390                                 }
1391                                 break;
1392                                 }
1393                         case FPRE_CLIENTUID: {
1394                                 int ret;
1395                                 ret = snprintf(dst, dst_left, "%s", client_sockaddr_str);
1396                                 if (ret < 0)
1397                                         break;
1398                                 else if (ret > dst_left) {
1399                                         log_err("fio: truncated filename\n");
1400                                         dst += dst_left;
1401                                         dst_left = 0;
1402                                 } else {
1403                                         dst += ret;
1404                                         dst_left -= ret;
1405                                 }
1406                                 break;
1407                                 }
1408                         default:
1409                                 assert(0);
1410                                 break;
1411                         }
1412
1413                         if (post_start)
1414                                 strncpy(dst, buf + post_start, dst_left);
1415
1416                         snprintf(buf, buf_size, "%s", copy);
1417                 } while (1);
1418         }
1419
1420         return buf;
1421 }
1422
1423 bool parse_dryrun(void)
1424 {
1425         return dump_cmdline || parse_only;
1426 }
1427
1428 static void gen_log_name(char *name, size_t size, const char *logtype,
1429                          const char *logname, unsigned int num,
1430                          const char *suf, int per_job)
1431 {
1432         if (per_job)
1433                 snprintf(name, size, "%s_%s.%d.%s", logname, logtype, num, suf);
1434         else
1435                 snprintf(name, size, "%s_%s.%s", logname, logtype, suf);
1436 }
1437
1438 static int check_waitees(char *waitee)
1439 {
1440         int ret = 0;
1441
1442         for_each_td(td) {
1443                 if (td->subjob_number)
1444                         continue;
1445
1446                 ret += !strcmp(td->o.name, waitee);
1447         } end_for_each();
1448
1449         return ret;
1450 }
1451
1452 static bool wait_for_ok(const char *jobname, struct thread_options *o)
1453 {
1454         int nw;
1455
1456         if (!o->wait_for)
1457                 return true;
1458
1459         if (!strcmp(jobname, o->wait_for)) {
1460                 log_err("%s: a job cannot wait for itself (wait_for=%s).\n",
1461                                 jobname, o->wait_for);
1462                 return false;
1463         }
1464
1465         if (!(nw = check_waitees(o->wait_for))) {
1466                 log_err("%s: waitee job %s unknown.\n", jobname, o->wait_for);
1467                 return false;
1468         }
1469
1470         if (nw > 1) {
1471                 log_err("%s: multiple waitees %s found,\n"
1472                         "please avoid duplicates when using wait_for option.\n",
1473                                 jobname, o->wait_for);
1474                 return false;
1475         }
1476
1477         return true;
1478 }
1479
1480 static int verify_per_group_options(struct thread_data *td, const char *jobname)
1481 {
1482         for_each_td(td2) {
1483                 if (td->groupid != td2->groupid)
1484                         continue;
1485
1486                 if (td->o.stats &&
1487                     td->o.lat_percentiles != td2->o.lat_percentiles) {
1488                         log_err("fio: lat_percentiles in job: %s differs from group\n",
1489                                 jobname);
1490                         return 1;
1491                 }
1492         } end_for_each();
1493
1494         return 0;
1495 }
1496
1497 /*
1498  * Treat an empty log file name the same as a one not given
1499  */
1500 static const char *make_log_name(const char *logname, const char *jobname)
1501 {
1502         if (logname && strcmp(logname, ""))
1503                 return logname;
1504
1505         return jobname;
1506 }
1507
1508 /*
1509  * Adds a job to the list of things todo. Sanitizes the various options
1510  * to make sure we don't have conflicts, and initializes various
1511  * members of td.
1512  */
1513 static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
1514                    int recursed, int client_type)
1515 {
1516         unsigned int i;
1517         char fname[PATH_MAX + 1];
1518         int numjobs, file_alloced;
1519         struct thread_options *o = &td->o;
1520         char logname[PATH_MAX + 32];
1521
1522         /*
1523          * the def_thread is just for options, it's not a real job
1524          */
1525         if (td == &def_thread)
1526                 return 0;
1527
1528         init_flags(td);
1529
1530         /*
1531          * if we are just dumping the output command line, don't add the job
1532          */
1533         if (parse_dryrun()) {
1534                 put_job(td);
1535                 return 0;
1536         }
1537
1538         td->client_type = client_type;
1539
1540         if (profile_td_init(td))
1541                 goto err;
1542
1543         if (ioengine_load(td))
1544                 goto err;
1545
1546         file_alloced = 0;
1547         if (!o->filename && !td->files_index && !o->read_iolog_file) {
1548                 file_alloced = 1;
1549
1550                 if (o->nr_files == 1 && exists_and_not_regfile(jobname))
1551                         add_file(td, jobname, job_add_num, 0);
1552                 else {
1553                         for (i = 0; i < o->nr_files; i++)
1554                                 add_file(td, make_filename(fname, sizeof(fname), o, jobname, job_add_num, i), job_add_num, 0);
1555                 }
1556         }
1557
1558         if (setup_random_seeds(td)) {
1559                 td_verror(td, errno, "setup_random_seeds");
1560                 goto err;
1561         }
1562
1563         if (fixup_options(td))
1564                 goto err;
1565
1566         if (!td->o.dedupe_global && init_dedupe_working_set_seeds(td, 0))
1567                 goto err;
1568
1569         /*
1570          * Belongs to fixup_options, but o->name is not necessarily set as yet
1571          */
1572         if (!wait_for_ok(jobname, o))
1573                 goto err;
1574
1575         flow_init_job(td);
1576
1577         /*
1578          * IO engines only need this for option callbacks, and the address may
1579          * change in subprocesses.
1580          */
1581         if (td->eo)
1582                 *(struct thread_data **)td->eo = NULL;
1583
1584         if (td_ioengine_flagged(td, FIO_DISKLESSIO)) {
1585                 struct fio_file *f;
1586
1587                 for_each_file(td, f, i)
1588                         f->real_file_size = -1ULL;
1589         }
1590
1591         td->sem = fio_sem_init(FIO_SEM_LOCKED);
1592
1593         td->ts.clat_percentiles = o->clat_percentiles;
1594         td->ts.lat_percentiles = o->lat_percentiles;
1595         td->ts.slat_percentiles = o->slat_percentiles;
1596         td->ts.percentile_precision = o->percentile_precision;
1597         memcpy(td->ts.percentile_list, o->percentile_list, sizeof(o->percentile_list));
1598         td->ts.sig_figs = o->sig_figs;
1599
1600         init_thread_stat_min_vals(&td->ts);
1601
1602         /*
1603          * td->>ddir_seq_nr needs to be initialized to 1, NOT o->ddir_seq_nr,
1604          * so that get_next_offset gets a new random offset the first time it
1605          * is called, instead of keeping an initial offset of 0 for the first
1606          * nr-1 calls
1607          */
1608         td->ddir_seq_nr = 1;
1609
1610         if ((o->stonewall || o->new_group) && prev_group_jobs) {
1611                 prev_group_jobs = 0;
1612                 groupid++;
1613                 if (groupid == INT_MAX) {
1614                         log_err("fio: too many groups defined\n");
1615                         goto err;
1616                 }
1617         }
1618
1619         td->groupid = groupid;
1620         prev_group_jobs++;
1621
1622         if (td->o.group_reporting && prev_group_jobs > 1 &&
1623             verify_per_group_options(td, jobname))
1624                 goto err;
1625
1626         if (setup_rate(td))
1627                 goto err;
1628
1629         if (o->write_lat_log) {
1630                 struct log_params p = {
1631                         .td = td,
1632                         .avg_msec = o->log_avg_msec,
1633                         .hist_msec = o->log_hist_msec,
1634                         .hist_coarseness = o->log_hist_coarseness,
1635                         .log_type = IO_LOG_TYPE_LAT,
1636                         .log_offset = o->log_offset,
1637                         .log_prio = o->log_prio,
1638                         .log_issue_time = o->log_issue_time,
1639                         .log_gz = o->log_gz,
1640                         .log_gz_store = o->log_gz_store,
1641                 };
1642                 const char *pre = make_log_name(o->lat_log_file, o->name);
1643                 const char *suf;
1644
1645                 if (o->log_issue_time && !o->log_offset) {
1646                         log_err("fio: log_issue_time option requires write_lat_log and log_offset options\n");
1647                         goto err;
1648                 }
1649
1650                 if (p.log_gz_store)
1651                         suf = "log.fz";
1652                 else
1653                         suf = "log";
1654
1655                 if (!o->disable_lat) {
1656                         gen_log_name(logname, sizeof(logname), "lat", pre,
1657                                      td->thread_number, suf, o->per_job_logs);
1658                         setup_log(&td->lat_log, &p, logname);
1659                 }
1660
1661                 if (!o->disable_slat) {
1662                         gen_log_name(logname, sizeof(logname), "slat", pre,
1663                                      td->thread_number, suf, o->per_job_logs);
1664                         setup_log(&td->slat_log, &p, logname);
1665                 }
1666
1667                 if (!o->disable_clat) {
1668                         gen_log_name(logname, sizeof(logname), "clat", pre,
1669                                      td->thread_number, suf, o->per_job_logs);
1670                         setup_log(&td->clat_log, &p, logname);
1671                 }
1672
1673         } else if (o->log_issue_time) {
1674                 log_err("fio: log_issue_time option requires write_lat_log and log_offset options\n");
1675                 goto err;
1676         }
1677
1678         if (o->write_hist_log) {
1679                 struct log_params p = {
1680                         .td = td,
1681                         .avg_msec = o->log_avg_msec,
1682                         .hist_msec = o->log_hist_msec,
1683                         .hist_coarseness = o->log_hist_coarseness,
1684                         .log_type = IO_LOG_TYPE_HIST,
1685                         .log_offset = o->log_offset,
1686                         .log_prio = o->log_prio,
1687                         .log_issue_time = o->log_issue_time,
1688                         .log_gz = o->log_gz,
1689                         .log_gz_store = o->log_gz_store,
1690                 };
1691                 const char *pre = make_log_name(o->hist_log_file, o->name);
1692                 const char *suf;
1693
1694 #ifndef CONFIG_ZLIB
1695                 if (td->client_type) {
1696                         log_err("fio: --write_hist_log requires zlib in client/server mode\n");
1697                         goto err;
1698                 }
1699 #endif
1700
1701                 if (p.log_gz_store)
1702                         suf = "log.fz";
1703                 else
1704                         suf = "log";
1705
1706                 gen_log_name(logname, sizeof(logname), "clat_hist", pre,
1707                                 td->thread_number, suf, o->per_job_logs);
1708                 setup_log(&td->clat_hist_log, &p, logname);
1709         }
1710
1711         if (o->write_bw_log) {
1712                 struct log_params p = {
1713                         .td = td,
1714                         .avg_msec = o->log_avg_msec,
1715                         .hist_msec = o->log_hist_msec,
1716                         .hist_coarseness = o->log_hist_coarseness,
1717                         .log_type = IO_LOG_TYPE_BW,
1718                         .log_offset = o->log_offset,
1719                         .log_prio = o->log_prio,
1720                         .log_issue_time = o->log_issue_time,
1721                         .log_gz = o->log_gz,
1722                         .log_gz_store = o->log_gz_store,
1723                 };
1724                 const char *pre = make_log_name(o->bw_log_file, o->name);
1725                 const char *suf;
1726
1727                 if (fio_option_is_set(o, bw_avg_time))
1728                         p.avg_msec = min(o->log_avg_msec, o->bw_avg_time);
1729                 else
1730                         o->bw_avg_time = p.avg_msec;
1731
1732                 p.hist_msec = o->log_hist_msec;
1733                 p.hist_coarseness = o->log_hist_coarseness;
1734
1735                 if (p.log_gz_store)
1736                         suf = "log.fz";
1737                 else
1738                         suf = "log";
1739
1740                 gen_log_name(logname, sizeof(logname), "bw", pre,
1741                                 td->thread_number, suf, o->per_job_logs);
1742                 setup_log(&td->bw_log, &p, logname);
1743         }
1744         if (o->write_iops_log) {
1745                 struct log_params p = {
1746                         .td = td,
1747                         .avg_msec = o->log_avg_msec,
1748                         .hist_msec = o->log_hist_msec,
1749                         .hist_coarseness = o->log_hist_coarseness,
1750                         .log_type = IO_LOG_TYPE_IOPS,
1751                         .log_offset = o->log_offset,
1752                         .log_prio = o->log_prio,
1753                         .log_issue_time = o->log_issue_time,
1754                         .log_gz = o->log_gz,
1755                         .log_gz_store = o->log_gz_store,
1756                 };
1757                 const char *pre = make_log_name(o->iops_log_file, o->name);
1758                 const char *suf;
1759
1760                 if (fio_option_is_set(o, iops_avg_time))
1761                         p.avg_msec = min(o->log_avg_msec, o->iops_avg_time);
1762                 else
1763                         o->iops_avg_time = p.avg_msec;
1764
1765                 p.hist_msec = o->log_hist_msec;
1766                 p.hist_coarseness = o->log_hist_coarseness;
1767
1768                 if (p.log_gz_store)
1769                         suf = "log.fz";
1770                 else
1771                         suf = "log";
1772
1773                 gen_log_name(logname, sizeof(logname), "iops", pre,
1774                                 td->thread_number, suf, o->per_job_logs);
1775                 setup_log(&td->iops_log, &p, logname);
1776         }
1777
1778         if (!o->name)
1779                 o->name = strdup(jobname);
1780
1781         if (output_format & FIO_OUTPUT_NORMAL) {
1782                 if (!job_add_num) {
1783                         if (is_backend && !recursed)
1784                                 fio_server_send_add_job(td);
1785
1786                         if (!td_ioengine_flagged(td, FIO_NOIO)) {
1787                                 char *c1, *c2, *c3, *c4;
1788                                 char *c5 = NULL, *c6 = NULL;
1789                                 int i2p = is_power_of_2(o->kb_base);
1790                                 struct buf_output out;
1791
1792                                 c1 = num2str(o->min_bs[DDIR_READ], o->sig_figs, 1, i2p, N2S_BYTE);
1793                                 c2 = num2str(o->max_bs[DDIR_READ], o->sig_figs, 1, i2p, N2S_BYTE);
1794                                 c3 = num2str(o->min_bs[DDIR_WRITE], o->sig_figs, 1, i2p, N2S_BYTE);
1795                                 c4 = num2str(o->max_bs[DDIR_WRITE], o->sig_figs, 1, i2p, N2S_BYTE);
1796
1797                                 if (!o->bs_is_seq_rand) {
1798                                         c5 = num2str(o->min_bs[DDIR_TRIM], o->sig_figs, 1, i2p, N2S_BYTE);
1799                                         c6 = num2str(o->max_bs[DDIR_TRIM], o->sig_figs, 1, i2p, N2S_BYTE);
1800                                 }
1801
1802                                 buf_output_init(&out);
1803                                 __log_buf(&out, "%s: (g=%d): rw=%s, ", td->o.name,
1804                                                         td->groupid,
1805                                                         ddir_str(o->td_ddir));
1806
1807                                 if (o->bs_is_seq_rand)
1808                                         __log_buf(&out, "bs=(R) %s-%s, (W) %s-%s, bs_is_seq_rand, ",
1809                                                         c1, c2, c3, c4);
1810                                 else
1811                                         __log_buf(&out, "bs=(R) %s-%s, (W) %s-%s, (T) %s-%s, ",
1812                                                         c1, c2, c3, c4, c5, c6);
1813
1814                                 __log_buf(&out, "ioengine=%s, iodepth=%u\n",
1815                                                 td->io_ops->name, o->iodepth);
1816                                 log_info_buf(out.buf, out.buflen);
1817                                 buf_output_free(&out);
1818
1819                                 free(c1);
1820                                 free(c2);
1821                                 free(c3);
1822                                 free(c4);
1823                                 free(c5);
1824                                 free(c6);
1825                         }
1826                 } else if (job_add_num == 1)
1827                         log_info("...\n");
1828         }
1829
1830         if (td_steadystate_init(td))
1831                 goto err;
1832
1833         if (o->merge_blktrace_file && !merge_blktrace_iologs(td))
1834                 goto err;
1835
1836         if (merge_blktrace_only) {
1837                 put_job(td);
1838                 return 0;
1839         }
1840
1841         /*
1842          * recurse add identical jobs, clear numjobs and stonewall options
1843          * as they don't apply to sub-jobs
1844          */
1845         numjobs = o->numjobs;
1846         while (--numjobs) {
1847                 struct thread_data *td_new = get_new_job(false, td, true, jobname);
1848
1849                 if (!td_new)
1850                         goto err;
1851
1852                 td_new->o.numjobs = 1;
1853                 td_new->o.stonewall = 0;
1854                 td_new->o.new_group = 0;
1855                 td_new->subjob_number = numjobs;
1856                 td_new->o.ss_dur = o->ss_dur * 1000000l;
1857                 td_new->o.ss_limit = o->ss_limit;
1858
1859                 if (file_alloced) {
1860                         if (td_new->files) {
1861                                 struct fio_file *f;
1862                                 for_each_file(td_new, f, i)
1863                                         fio_file_free(f);
1864                                 free(td_new->files);
1865                                 td_new->files = NULL;
1866                         }
1867                         td_new->files_index = 0;
1868                         td_new->files_size = 0;
1869                         if (td_new->o.filename) {
1870                                 free(td_new->o.filename);
1871                                 td_new->o.filename = NULL;
1872                         }
1873                 }
1874
1875                 if (add_job(td_new, jobname, numjobs, 1, client_type))
1876                         goto err;
1877         }
1878
1879         return 0;
1880 err:
1881         put_job(td);
1882         return -1;
1883 }
1884
1885 /*
1886  * Parse as if 'o' was a command line
1887  */
1888 void add_job_opts(const char **o, int client_type)
1889 {
1890         struct thread_data *td, *td_parent;
1891         int i, in_global = 1;
1892         char jobname[32];
1893
1894         i = 0;
1895         td_parent = td = NULL;
1896         while (o[i]) {
1897                 if (!strncmp(o[i], "name", 4)) {
1898                         in_global = 0;
1899                         if (td)
1900                                 add_job(td, jobname, 0, 0, client_type);
1901                         td = NULL;
1902                         sprintf(jobname, "%s", o[i] + 5);
1903                 }
1904                 if (in_global && !td_parent)
1905                         td_parent = get_new_job(true, &def_thread, false, jobname);
1906                 else if (!in_global && !td) {
1907                         if (!td_parent)
1908                                 td_parent = &def_thread;
1909                         td = get_new_job(false, td_parent, false, jobname);
1910                 }
1911                 if (in_global)
1912                         fio_options_parse(td_parent, (char **) &o[i], 1);
1913                 else
1914                         fio_options_parse(td, (char **) &o[i], 1);
1915                 i++;
1916         }
1917
1918         if (td)
1919                 add_job(td, jobname, 0, 0, client_type);
1920 }
1921
1922 static int skip_this_section(const char *name)
1923 {
1924         int i;
1925
1926         if (!nr_job_sections)
1927                 return 0;
1928         if (!strncmp(name, "global", 6))
1929                 return 0;
1930
1931         for (i = 0; i < nr_job_sections; i++)
1932                 if (!strcmp(job_sections[i], name))
1933                         return 0;
1934
1935         return 1;
1936 }
1937
1938 static int is_empty_or_comment(char *line)
1939 {
1940         unsigned int i;
1941
1942         for (i = 0; i < strlen(line); i++) {
1943                 if (line[i] == ';')
1944                         return 1;
1945                 if (line[i] == '#')
1946                         return 1;
1947                 if (!isspace((int) line[i]) && !iscntrl((int) line[i]))
1948                         return 0;
1949         }
1950
1951         return 1;
1952 }
1953
1954 /*
1955  * This is our [ini] type file parser.
1956  */
1957 static int __parse_jobs_ini(struct thread_data *td,
1958                 char *file, int is_buf, int stonewall_flag, int type,
1959                 int nested, char *name, char ***popts, int *aopts, int *nopts)
1960 {
1961         bool global = false;
1962         bool stdin_occupied = false;
1963         char *string;
1964         FILE *f;
1965         char *p;
1966         int ret = 0, stonewall;
1967         int first_sect = 1;
1968         int skip_fgets = 0;
1969         int inside_skip = 0;
1970         char **opts;
1971         int i, alloc_opts, num_opts;
1972
1973         dprint(FD_PARSE, "Parsing ini file %s\n", file);
1974         assert(td || !nested);
1975
1976         if (is_buf)
1977                 f = NULL;
1978         else {
1979                 if (!strcmp(file, "-")) {
1980                         f = stdin;
1981                         stdin_occupied = true;
1982                 } else
1983                         f = fopen(file, "r");
1984
1985                 if (!f) {
1986                         int __err = errno;
1987
1988                         log_err("fio: unable to open '%s' job file\n", file);
1989                         if (td)
1990                                 td_verror(td, __err, "job file open");
1991                         return 1;
1992                 }
1993         }
1994
1995         string = malloc(OPT_LEN_MAX);
1996
1997         /*
1998          * it's really 256 + small bit, 280 should suffice
1999          */
2000         if (!nested) {
2001                 name = calloc(1, 280);
2002         }
2003
2004         opts = NULL;
2005         if (nested && popts) {
2006                 opts = *popts;
2007                 alloc_opts = *aopts;
2008                 num_opts = *nopts;
2009         }
2010
2011         if (!opts) {
2012                 alloc_opts = 8;
2013                 opts = malloc(sizeof(char *) * alloc_opts);
2014                 num_opts = 0;
2015         }
2016
2017         stonewall = stonewall_flag;
2018         do {
2019                 /*
2020                  * if skip_fgets is set, we already have loaded a line we
2021                  * haven't handled.
2022                  */
2023                 if (!skip_fgets) {
2024                         if (is_buf)
2025                                 p = strsep(&file, "\n");
2026                         else
2027                                 p = fgets(string, OPT_LEN_MAX, f);
2028                         if (!p)
2029                                 break;
2030                 }
2031
2032                 skip_fgets = 0;
2033                 strip_blank_front(&p);
2034                 strip_blank_end(p);
2035
2036                 dprint(FD_PARSE, "%s\n", p);
2037                 if (is_empty_or_comment(p))
2038                         continue;
2039
2040                 if (!nested) {
2041                         if (sscanf(p, "[%255[^\n]]", name) != 1) {
2042                                 if (inside_skip)
2043                                         continue;
2044
2045                                 log_err("fio: option <%s> outside of "
2046                                         "[] job section\n", p);
2047                                 ret = 1;
2048                                 break;
2049                         }
2050
2051                         name[strlen(name) - 1] = '\0';
2052
2053                         if (skip_this_section(name)) {
2054                                 inside_skip = 1;
2055                                 continue;
2056                         } else
2057                                 inside_skip = 0;
2058
2059                         dprint(FD_PARSE, "Parsing section [%s]\n", name);
2060
2061                         global = !strncmp(name, "global", 6);
2062
2063                         if (dump_cmdline) {
2064                                 if (first_sect)
2065                                         log_info("fio ");
2066                                 if (!global)
2067                                         log_info("--name=%s ", name);
2068                                 first_sect = 0;
2069                         }
2070
2071                         td = get_new_job(global, &def_thread, false, name);
2072                         if (!td) {
2073                                 ret = 1;
2074                                 break;
2075                         }
2076
2077                         /*
2078                          * Separate multiple job files by a stonewall
2079                          */
2080                         if (!global && stonewall) {
2081                                 td->o.stonewall = stonewall;
2082                                 stonewall = 0;
2083                         }
2084
2085                         num_opts = 0;
2086                         memset(opts, 0, alloc_opts * sizeof(char *));
2087                 }
2088                 else
2089                         skip_fgets = 1;
2090
2091                 while (1) {
2092                         if (!skip_fgets) {
2093                                 if (is_buf)
2094                                         p = strsep(&file, "\n");
2095                                 else
2096                                         p = fgets(string, OPT_LEN_MAX, f);
2097                                 if (!p)
2098                                         break;
2099                                 dprint(FD_PARSE, "%s", p);
2100                         }
2101                         else
2102                                 skip_fgets = 0;
2103
2104                         if (is_empty_or_comment(p))
2105                                 continue;
2106
2107                         strip_blank_front(&p);
2108
2109                         /*
2110                          * new section, break out and make sure we don't
2111                          * fgets() a new line at the top.
2112                          */
2113                         if (p[0] == '[') {
2114                                 if (nested) {
2115                                         log_err("No new sections in included files\n");
2116                                         ret = 1;
2117                                         goto out;
2118                                 }
2119
2120                                 skip_fgets = 1;
2121                                 break;
2122                         }
2123
2124                         strip_blank_end(p);
2125
2126                         if (!strncmp(p, "include", strlen("include"))) {
2127                                 char *filename = p + strlen("include") + 1,
2128                                         *ts, *full_fn = NULL;
2129
2130                                 /*
2131                                  * Allow for the include filename
2132                                  * specification to be relative.
2133                                  */
2134                                 if (access(filename, F_OK) &&
2135                                     (ts = strrchr(file, '/'))) {
2136                                         if (asprintf(&full_fn, "%.*s%s",
2137                                                  (int)(ts - file + 1), file,
2138                                                  filename) < 0) {
2139                                                 ret = ENOMEM;
2140                                                 break;
2141                                         }
2142                                         filename = full_fn;
2143                                 }
2144
2145                                 ret = __parse_jobs_ini(td, filename, is_buf,
2146                                                        stonewall_flag, type, 1,
2147                                                        name, &opts,
2148                                                        &alloc_opts, &num_opts);
2149
2150                                 if (ret) {
2151                                         log_err("Error %d while parsing "
2152                                                 "include file %s\n",
2153                                                 ret, filename);
2154                                 }
2155
2156                                 if (full_fn)
2157                                         free(full_fn);
2158
2159                                 if (ret)
2160                                         break;
2161
2162                                 continue;
2163                         }
2164
2165                         if (num_opts == alloc_opts) {
2166                                 alloc_opts <<= 1;
2167                                 opts = realloc(opts,
2168                                                 alloc_opts * sizeof(char *));
2169                         }
2170
2171                         opts[num_opts] = strdup(p);
2172                         num_opts++;
2173                 }
2174
2175                 if (nested) {
2176                         *popts = opts;
2177                         *aopts = alloc_opts;
2178                         *nopts = num_opts;
2179                         goto out;
2180                 }
2181
2182                 ret = fio_options_parse(td, opts, num_opts);
2183
2184                 if (!ret && td->o.read_iolog_file != NULL) {
2185                         char *fname = get_name_by_idx(td->o.read_iolog_file,
2186                                                       td->subjob_number);
2187                         if (!strcmp(fname, "-")) {
2188                                 if (stdin_occupied) {
2189                                         log_err("fio: only one user (read_iolog_file/job "
2190                                                 "file) of stdin is permitted at once but "
2191                                                 "more than one was found.\n");
2192                                         ret = 1;
2193                                 }
2194                                 stdin_occupied = true;
2195                         }
2196                 }
2197                 if (!ret) {
2198                         if (dump_cmdline)
2199                                 dump_opt_list(td);
2200
2201                         ret = add_job(td, name, 0, 0, type);
2202                 } else {
2203                         log_err("fio: job %s dropped\n", name);
2204                         put_job(td);
2205                 }
2206
2207                 for (i = 0; i < num_opts; i++)
2208                         free(opts[i]);
2209                 num_opts = 0;
2210         } while (!ret);
2211
2212         if (dump_cmdline)
2213                 log_info("\n");
2214
2215         i = 0;
2216         while (i < nr_job_sections) {
2217                 free(job_sections[i]);
2218                 i++;
2219         }
2220
2221         free(job_sections);
2222         job_sections = NULL;
2223         nr_job_sections = 0;
2224
2225         free(opts);
2226 out:
2227         free(string);
2228         if (!nested)
2229                 free(name);
2230         if (!is_buf && f != stdin)
2231                 fclose(f);
2232         return ret;
2233 }
2234
2235 int parse_jobs_ini(char *file, int is_buf, int stonewall_flag, int type)
2236 {
2237         return __parse_jobs_ini(NULL, file, is_buf, stonewall_flag, type,
2238                         0, NULL, NULL, NULL, NULL);
2239 }
2240
2241 static int fill_def_thread(void)
2242 {
2243         memset(&def_thread, 0, sizeof(def_thread));
2244         INIT_FLIST_HEAD(&def_thread.opt_list);
2245
2246         fio_getaffinity(getpid(), &def_thread.o.cpumask);
2247         def_thread.o.error_dump = 1;
2248
2249         /*
2250          * fill default options
2251          */
2252         fio_fill_default_options(&def_thread);
2253         return 0;
2254 }
2255
2256 static void show_debug_categories(void)
2257 {
2258 #ifdef FIO_INC_DEBUG
2259         const struct debug_level *dl = &debug_levels[0];
2260         int curlen, first = 1;
2261
2262         curlen = 0;
2263         while (dl->name) {
2264                 int has_next = (dl + 1)->name != NULL;
2265
2266                 if (first || curlen + strlen(dl->name) >= 80) {
2267                         if (!first) {
2268                                 printf("\n");
2269                                 curlen = 0;
2270                         }
2271                         curlen += printf("\t\t\t%s", dl->name);
2272                         curlen += 3 * (8 - 1);
2273                         if (has_next)
2274                                 curlen += printf(",");
2275                 } else {
2276                         curlen += printf("%s", dl->name);
2277                         if (has_next)
2278                                 curlen += printf(",");
2279                 }
2280                 dl++;
2281                 first = 0;
2282         }
2283         printf("\n");
2284 #endif
2285 }
2286
2287 /*
2288  * Following options aren't printed by usage().
2289  * --append-terse - Equivalent to --output-format=terse, see f6a7df53.
2290  * --latency-log - Deprecated option.
2291  */
2292 static void usage(const char *name)
2293 {
2294         printf("%s\n", fio_version_string);
2295         printf("%s [options] [job options] <job file(s)>\n", name);
2296         printf("  --debug=options\tEnable debug logging. May be one/more of:\n");
2297         show_debug_categories();
2298         printf("  --parse-only\t\tParse options only, don't start any IO\n");
2299         printf("  --merge-blktrace-only\tMerge blktraces only, don't start any IO\n");
2300         printf("  --output\t\tWrite output to file\n");
2301         printf("  --bandwidth-log\tGenerate aggregate bandwidth logs\n");
2302         printf("  --minimal\t\tMinimal (terse) output\n");
2303         printf("  --output-format=type\tOutput format (terse,json,json+,normal)\n");
2304         printf("  --terse-version=type\tSet terse version output format"
2305                 " (default 3, or 2 or 4 or 5)\n");
2306         printf("  --version\t\tPrint version info and exit\n");
2307         printf("  --help\t\tPrint this page\n");
2308         printf("  --cpuclock-test\tPerform test/validation of CPU clock\n");
2309         printf("  --crctest=[type]\tTest speed of checksum functions\n");
2310         printf("  --cmdhelp=cmd\t\tPrint command help, \"all\" for all of"
2311                 " them\n");
2312         printf("  --enghelp=engine\tPrint ioengine help, or list"
2313                 " available ioengines\n");
2314         printf("  --enghelp=engine,cmd\tPrint help for an ioengine"
2315                 " cmd\n");
2316         printf("  --showcmd\t\tTurn a job file into command line options\n");
2317         printf("  --eta=when\t\tWhen ETA estimate should be printed\n");
2318         printf("            \t\tMay be \"always\", \"never\" or \"auto\"\n");
2319         printf("  --eta-newline=t\tForce a new line for every 't'");
2320         printf(" period passed\n");
2321         printf("  --status-interval=t\tForce full status dump every");
2322         printf(" 't' period passed\n");
2323         printf("  --readonly\t\tTurn on safety read-only checks, preventing"
2324                 " writes\n");
2325         printf("  --section=name\tOnly run specified section in job file,"
2326                 " multiple sections can be specified\n");
2327         printf("  --alloc-size=kb\tSet smalloc pool to this size in kb"
2328                 " (def 16384)\n");
2329         printf("  --warnings-fatal\tFio parser warnings are fatal\n");
2330         printf("  --max-jobs=nr\t\tMaximum number of threads/processes to support\n");
2331         printf("  --server=args\t\tStart a backend fio server\n");
2332         printf("  --daemonize=pidfile\tBackground fio server, write pid to file\n");
2333         printf("  --client=hostname\tTalk to remote backend(s) fio server at hostname\n");
2334         printf("  --remote-config=file\tTell fio server to load this local job file\n");
2335         printf("  --idle-prof=option\tReport cpu idleness on a system or percpu basis\n"
2336                 "\t\t\t(option=system,percpu) or run unit work\n"
2337                 "\t\t\tcalibration only (option=calibrate)\n");
2338 #ifdef CONFIG_ZLIB
2339         printf("  --inflate-log=log\tInflate and output compressed log\n");
2340 #endif
2341         printf("  --trigger-file=file\tExecute trigger cmd when file exists\n");
2342         printf("  --trigger-timeout=t\tExecute trigger at this time\n");
2343         printf("  --trigger=cmd\t\tSet this command as local trigger\n");
2344         printf("  --trigger-remote=cmd\tSet this command as remote trigger\n");
2345         printf("  --aux-path=path\tUse this path for fio state generated files\n");
2346         printf("\nFio was written by Jens Axboe <axboe@kernel.dk>\n");
2347 }
2348
2349 #ifdef FIO_INC_DEBUG
2350 const struct debug_level debug_levels[] = {
2351         { .name = "process",
2352           .help = "Process creation/exit logging",
2353           .shift = FD_PROCESS,
2354         },
2355         { .name = "file",
2356           .help = "File related action logging",
2357           .shift = FD_FILE,
2358         },
2359         { .name = "io",
2360           .help = "IO and IO engine action logging (offsets, queue, completions, etc)",
2361           .shift = FD_IO,
2362         },
2363         { .name = "mem",
2364           .help = "Memory allocation/freeing logging",
2365           .shift = FD_MEM,
2366         },
2367         { .name = "blktrace",
2368           .help = "blktrace action logging",
2369           .shift = FD_BLKTRACE,
2370         },
2371         { .name = "verify",
2372           .help = "IO verification action logging",
2373           .shift = FD_VERIFY,
2374         },
2375         { .name = "random",
2376           .help = "Random generation logging",
2377           .shift = FD_RANDOM,
2378         },
2379         { .name = "parse",
2380           .help = "Parser logging",
2381           .shift = FD_PARSE,
2382         },
2383         { .name = "diskutil",
2384           .help = "Disk utility logging actions",
2385           .shift = FD_DISKUTIL,
2386         },
2387         { .name = "job",
2388           .help = "Logging related to creating/destroying jobs",
2389           .shift = FD_JOB,
2390         },
2391         { .name = "mutex",
2392           .help = "Mutex logging",
2393           .shift = FD_MUTEX
2394         },
2395         { .name = "profile",
2396           .help = "Logging related to profiles",
2397           .shift = FD_PROFILE,
2398         },
2399         { .name = "time",
2400           .help = "Logging related to time keeping functions",
2401           .shift = FD_TIME,
2402         },
2403         { .name = "net",
2404           .help = "Network logging",
2405           .shift = FD_NET,
2406         },
2407         { .name = "rate",
2408           .help = "Rate logging",
2409           .shift = FD_RATE,
2410         },
2411         { .name = "compress",
2412           .help = "Log compression logging",
2413           .shift = FD_COMPRESS,
2414         },
2415         { .name = "steadystate",
2416           .help = "Steady state detection logging",
2417           .shift = FD_STEADYSTATE,
2418         },
2419         { .name = "helperthread",
2420           .help = "Helper thread logging",
2421           .shift = FD_HELPERTHREAD,
2422         },
2423         { .name = "zbd",
2424           .help = "Zoned Block Device logging",
2425           .shift = FD_ZBD,
2426         },
2427         { .name = NULL, },
2428 };
2429
2430 static int set_debug(const char *string)
2431 {
2432         const struct debug_level *dl;
2433         char *p = (char *) string;
2434         char *opt;
2435         int i;
2436
2437         if (!string)
2438                 return 0;
2439
2440         if (!strcmp(string, "?") || !strcmp(string, "help")) {
2441                 log_info("fio: dumping debug options:");
2442                 for (i = 0; debug_levels[i].name; i++) {
2443                         dl = &debug_levels[i];
2444                         log_info("%s,", dl->name);
2445                 }
2446                 log_info("all\n");
2447                 return 1;
2448         }
2449
2450         while ((opt = strsep(&p, ",")) != NULL) {
2451                 int found = 0;
2452
2453                 if (!strncmp(opt, "all", 3)) {
2454                         log_info("fio: set all debug options\n");
2455                         fio_debug = ~0UL;
2456                         continue;
2457                 }
2458
2459                 for (i = 0; debug_levels[i].name; i++) {
2460                         dl = &debug_levels[i];
2461                         found = !strncmp(opt, dl->name, strlen(dl->name));
2462                         if (!found)
2463                                 continue;
2464
2465                         if (dl->shift == FD_JOB) {
2466                                 opt = strchr(opt, ':');
2467                                 if (!opt) {
2468                                         log_err("fio: missing job number\n");
2469                                         break;
2470                                 }
2471                                 opt++;
2472                                 fio_debug_jobno = atoi(opt);
2473                                 log_info("fio: set debug jobno %d\n",
2474                                                         fio_debug_jobno);
2475                         } else {
2476                                 log_info("fio: set debug option %s\n", opt);
2477                                 fio_debug |= (1UL << dl->shift);
2478                         }
2479                         break;
2480                 }
2481
2482                 if (!found)
2483                         log_err("fio: debug mask %s not found\n", opt);
2484         }
2485         return 0;
2486 }
2487 #else
2488 static int set_debug(const char *string)
2489 {
2490         log_err("fio: debug tracing not included in build\n");
2491         return 1;
2492 }
2493 #endif
2494
2495 static void fio_options_fill_optstring(void)
2496 {
2497         char *ostr = cmd_optstr;
2498         int i, c;
2499
2500         c = i = 0;
2501         while (l_opts[i].name) {
2502                 ostr[c++] = l_opts[i].val;
2503                 if (l_opts[i].has_arg == required_argument)
2504                         ostr[c++] = ':';
2505                 else if (l_opts[i].has_arg == optional_argument) {
2506                         ostr[c++] = ':';
2507                         ostr[c++] = ':';
2508                 }
2509                 i++;
2510         }
2511         ostr[c] = '\0';
2512 }
2513
2514 static int client_flag_set(char c)
2515 {
2516         int i;
2517
2518         i = 0;
2519         while (l_opts[i].name) {
2520                 int val = l_opts[i].val;
2521
2522                 if (c == (val & 0xff))
2523                         return (val & FIO_CLIENT_FLAG);
2524
2525                 i++;
2526         }
2527
2528         return 0;
2529 }
2530
2531 static void parse_cmd_client(void *client, char *opt)
2532 {
2533         fio_client_add_cmd_option(client, opt);
2534 }
2535
2536 static void show_closest_option(const char *name)
2537 {
2538         int best_option, best_distance;
2539         int i, distance;
2540
2541         while (*name == '-')
2542                 name++;
2543
2544         best_option = -1;
2545         best_distance = INT_MAX;
2546         i = 0;
2547         while (l_opts[i].name) {
2548                 distance = string_distance(name, l_opts[i].name);
2549                 if (distance < best_distance) {
2550                         best_distance = distance;
2551                         best_option = i;
2552                 }
2553                 i++;
2554         }
2555
2556         if (best_option != -1 && string_distance_ok(name, best_distance))
2557                 log_err("Did you mean %s?\n", l_opts[best_option].name);
2558 }
2559
2560 static int parse_output_format(const char *optarg)
2561 {
2562         char *p, *orig, *opt;
2563         int ret = 0;
2564
2565         p = orig = strdup(optarg);
2566
2567         output_format = 0;
2568
2569         while ((opt = strsep(&p, ",")) != NULL) {
2570                 if (!strcmp(opt, "minimal") ||
2571                     !strcmp(opt, "terse") ||
2572                     !strcmp(opt, "csv"))
2573                         output_format |= FIO_OUTPUT_TERSE;
2574                 else if (!strcmp(opt, "json"))
2575                         output_format |= FIO_OUTPUT_JSON;
2576                 else if (!strcmp(opt, "json+"))
2577                         output_format |= (FIO_OUTPUT_JSON | FIO_OUTPUT_JSON_PLUS);
2578                 else if (!strcmp(opt, "normal"))
2579                         output_format |= FIO_OUTPUT_NORMAL;
2580                 else {
2581                         log_err("fio: invalid output format %s\n", opt);
2582                         ret = 1;
2583                         break;
2584                 }
2585         }
2586
2587         free(orig);
2588         return ret;
2589 }
2590
2591 int parse_cmd_line(int argc, char *argv[], int client_type)
2592 {
2593         struct thread_data *td = NULL;
2594         int c, ini_idx = 0, lidx, ret = 0, do_exit = 0, exit_val = 0;
2595         char *ostr = cmd_optstr;
2596         char *pid_file = NULL;
2597         void *cur_client = NULL;
2598         bool backend = false;
2599
2600         /*
2601          * Reset optind handling, since we may call this multiple times
2602          * for the backend.
2603          */
2604         optind = 1;
2605
2606         while ((c = getopt_long_only(argc, argv, ostr, l_opts, &lidx)) != -1) {
2607                 if ((c & FIO_CLIENT_FLAG) || client_flag_set(c)) {
2608                         parse_cmd_client(cur_client, argv[optind - 1]);
2609                         c &= ~FIO_CLIENT_FLAG;
2610                 }
2611
2612                 switch (c) {
2613                 case 'a':
2614                         smalloc_pool_size = atoi(optarg);
2615                         smalloc_pool_size <<= 10;
2616                         sinit();
2617                         break;
2618                 case 'l':
2619                         log_err("fio: --latency-log is deprecated. Use per-job latency log options.\n");
2620                         do_exit++;
2621                         exit_val = 1;
2622                         break;
2623                 case 'b':
2624                         write_bw_log = true;
2625                         break;
2626                 case 'o': {
2627                         FILE *tmp;
2628
2629                         if (f_out && f_out != stdout)
2630                                 fclose(f_out);
2631
2632                         tmp = fopen(optarg, "w+");
2633                         if (!tmp) {
2634                                 log_err("fio: output file open error: %s\n", strerror(errno));
2635                                 exit_val = 1;
2636                                 do_exit++;
2637                                 break;
2638                         }
2639                         f_err = f_out = tmp;
2640                         break;
2641                         }
2642                 case 'm':
2643                         output_format = FIO_OUTPUT_TERSE;
2644                         break;
2645                 case 'F':
2646                         if (parse_output_format(optarg)) {
2647                                 log_err("fio: failed parsing output-format\n");
2648                                 exit_val = 1;
2649                                 do_exit++;
2650                                 break;
2651                         }
2652                         break;
2653                 case 'f':
2654                         output_format |= FIO_OUTPUT_TERSE;
2655                         break;
2656                 case 'h':
2657                         did_arg = true;
2658                         if (!cur_client) {
2659                                 usage(argv[0]);
2660                                 do_exit++;
2661                         }
2662                         break;
2663                 case 'c':
2664                         did_arg = true;
2665                         if (!cur_client) {
2666                                 fio_show_option_help(optarg);
2667                                 do_exit++;
2668                         }
2669                         break;
2670                 case 'i':
2671                         did_arg = true;
2672                         if (!cur_client) {
2673                                 exit_val = fio_show_ioengine_help(optarg);
2674                                 do_exit++;
2675                         }
2676                         break;
2677                 case 's':
2678                         did_arg = true;
2679                         dump_cmdline = true;
2680                         break;
2681                 case 'r':
2682                         read_only = 1;
2683                         break;
2684                 case 'v':
2685                         did_arg = true;
2686                         if (!cur_client) {
2687                                 log_info("%s\n", fio_version_string);
2688                                 do_exit++;
2689                         }
2690                         break;
2691                 case 'V':
2692                         terse_version = atoi(optarg);
2693                         if (!(terse_version >= 2 && terse_version <= 5)) {
2694                                 log_err("fio: bad terse version format\n");
2695                                 exit_val = 1;
2696                                 do_exit++;
2697                         }
2698                         break;
2699                 case 'e':
2700                         if (!strcmp("always", optarg))
2701                                 eta_print = FIO_ETA_ALWAYS;
2702                         else if (!strcmp("never", optarg))
2703                                 eta_print = FIO_ETA_NEVER;
2704                         break;
2705                 case 'E': {
2706                         long long t = 0;
2707
2708                         if (check_str_time(optarg, &t, 1)) {
2709                                 log_err("fio: failed parsing eta time %s\n", optarg);
2710                                 exit_val = 1;
2711                                 do_exit++;
2712                                 break;
2713                         }
2714                         eta_new_line = t / 1000;
2715                         if (!eta_new_line) {
2716                                 log_err("fio: eta new line time too short\n");
2717                                 exit_val = 1;
2718                                 do_exit++;
2719                         }
2720                         break;
2721                         }
2722                 case 'O': {
2723                         long long t = 0;
2724
2725                         if (check_str_time(optarg, &t, 1)) {
2726                                 log_err("fio: failed parsing eta interval %s\n", optarg);
2727                                 exit_val = 1;
2728                                 do_exit++;
2729                                 break;
2730                         }
2731                         eta_interval_msec = t / 1000;
2732                         if (eta_interval_msec < DISK_UTIL_MSEC) {
2733                                 log_err("fio: eta interval time too short (%umsec min)\n", DISK_UTIL_MSEC);
2734                                 exit_val = 1;
2735                                 do_exit++;
2736                         }
2737                         break;
2738                         }
2739                 case 'd':
2740                         if (set_debug(optarg))
2741                                 do_exit++;
2742                         break;
2743                 case 'P':
2744                         did_arg = true;
2745                         parse_only = true;
2746                         break;
2747                 case 'x': {
2748                         size_t new_size;
2749
2750                         if (!strcmp(optarg, "global")) {
2751                                 log_err("fio: can't use global as only "
2752                                         "section\n");
2753                                 do_exit++;
2754                                 exit_val = 1;
2755                                 break;
2756                         }
2757                         new_size = (nr_job_sections + 1) * sizeof(char *);
2758                         job_sections = realloc(job_sections, new_size);
2759                         job_sections[nr_job_sections] = strdup(optarg);
2760                         nr_job_sections++;
2761                         break;
2762                         }
2763 #ifdef CONFIG_ZLIB
2764                 case 'X':
2765                         exit_val = iolog_file_inflate(optarg);
2766                         did_arg = true;
2767                         do_exit++;
2768                         break;
2769 #endif
2770                 case 'p':
2771                         did_arg = true;
2772                         if (exec_profile)
2773                                 free(exec_profile);
2774                         exec_profile = strdup(optarg);
2775                         break;
2776                 case FIO_GETOPT_JOB: {
2777                         const char *opt = l_opts[lidx].name;
2778                         char *val = optarg;
2779
2780                         if (!strncmp(opt, "name", 4) && td) {
2781                                 ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type);
2782                                 if (ret)
2783                                         goto out_free;
2784                                 td = NULL;
2785                                 did_arg = true;
2786                         }
2787                         if (!td) {
2788                                 int is_section = !strncmp(opt, "name", 4);
2789                                 int global = 0;
2790
2791                                 if (!is_section || !strncmp(val, "global", 6))
2792                                         global = 1;
2793
2794                                 if (is_section && skip_this_section(val))
2795                                         continue;
2796
2797                                 td = get_new_job(global, &def_thread, true, NULL);
2798                                 if (!td || ioengine_load(td)) {
2799                                         if (td) {
2800                                                 put_job(td);
2801                                                 td = NULL;
2802                                         }
2803                                         do_exit++;
2804                                         exit_val = 1;
2805                                         break;
2806                                 }
2807                                 fio_options_set_ioengine_opts(l_opts, td);
2808                         }
2809
2810                         if ((!val || !strlen(val)) &&
2811                             l_opts[lidx].has_arg == required_argument) {
2812                                 log_err("fio: option %s requires an argument\n", opt);
2813                                 ret = 1;
2814                         } else
2815                                 ret = fio_cmd_option_parse(td, opt, val);
2816
2817                         if (ret) {
2818                                 if (td) {
2819                                         put_job(td);
2820                                         td = NULL;
2821                                 }
2822                                 do_exit++;
2823                                 exit_val = 1;
2824                         }
2825
2826                         if (!ret && !strcmp(opt, "ioengine")) {
2827                                 if (ioengine_load(td)) {
2828                                         put_job(td);
2829                                         td = NULL;
2830                                         do_exit++;
2831                                         exit_val = 1;
2832                                         break;
2833                                 }
2834                                 fio_options_set_ioengine_opts(l_opts, td);
2835                         }
2836                         break;
2837                 }
2838                 case FIO_GETOPT_IOENGINE: {
2839                         const char *opt = l_opts[lidx].name;
2840                         char *val = optarg;
2841
2842                         if (!td)
2843                                 break;
2844
2845                         ret = fio_cmd_ioengine_option_parse(td, opt, val);
2846
2847                         if (ret) {
2848                                 if (td) {
2849                                         put_job(td);
2850                                         td = NULL;
2851                                 }
2852                                 do_exit++;
2853                                 exit_val = 1;
2854                         }
2855                         break;
2856                 }
2857                 case 'w':
2858                         warnings_fatal = 1;
2859                         break;
2860                 case 'j':
2861                         /* we don't track/need this anymore, ignore it */
2862                         break;
2863                 case 'S':
2864                         did_arg = true;
2865 #ifndef CONFIG_NO_SHM
2866                         if (nr_clients) {
2867                                 log_err("fio: can't be both client and server\n");
2868                                 do_exit++;
2869                                 exit_val = 1;
2870                                 break;
2871                         }
2872                         if (optarg)
2873                                 fio_server_set_arg(optarg);
2874                         is_backend = true;
2875                         backend = true;
2876 #else
2877                         log_err("fio: client/server requires SHM support\n");
2878                         do_exit++;
2879                         exit_val = 1;
2880 #endif
2881                         break;
2882 #ifdef WIN32
2883                 case 'N':
2884                         did_arg = true;
2885                         fio_server_internal_set(optarg);
2886                         break;
2887 #endif
2888                 case 'D':
2889                         if (pid_file)
2890                                 free(pid_file);
2891                         pid_file = strdup(optarg);
2892                         break;
2893                 case 'I':
2894                         if ((ret = fio_idle_prof_parse_opt(optarg))) {
2895                                 /* exit on error and calibration only */
2896                                 did_arg = true;
2897                                 do_exit++;
2898                                 if (ret == -1)
2899                                         exit_val = 1;
2900                         }
2901                         break;
2902                 case 'C':
2903                         did_arg = true;
2904                         if (is_backend) {
2905                                 log_err("fio: can't be both client and server\n");
2906                                 do_exit++;
2907                                 exit_val = 1;
2908                                 break;
2909                         }
2910                         /* if --client parameter contains a pathname */
2911                         if (0 == access(optarg, R_OK)) {
2912                                 /* file contains a list of host addrs or names */
2913                                 char hostaddr[PATH_MAX] = {0};
2914                                 char formatstr[8];
2915                                 FILE * hostf = fopen(optarg, "r");
2916                                 if (!hostf) {
2917                                         log_err("fio: could not open client list file %s for read\n", optarg);
2918                                         do_exit++;
2919                                         exit_val = 1;
2920                                         break;
2921                                 }
2922                                 sprintf(formatstr, "%%%ds", PATH_MAX - 1);
2923                                 /*
2924                                  * read at most PATH_MAX-1 chars from each
2925                                  * record in this file
2926                                  */
2927                                 while (fscanf(hostf, formatstr, hostaddr) == 1) {
2928                                         /* expect EVERY host in file to be valid */
2929                                         if (fio_client_add(&fio_client_ops, hostaddr, &cur_client)) {
2930                                                 log_err("fio: failed adding client %s from file %s\n", hostaddr, optarg);
2931                                                 do_exit++;
2932                                                 exit_val = 1;
2933                                                 break;
2934                                         }
2935                                 }
2936                                 fclose(hostf);
2937                                 break; /* no possibility of job file for "this client only" */
2938                         }
2939                         if (fio_client_add(&fio_client_ops, optarg, &cur_client)) {
2940                                 log_err("fio: failed adding client %s\n", optarg);
2941                                 do_exit++;
2942                                 exit_val = 1;
2943                                 break;
2944                         }
2945                         /*
2946                          * If the next argument exists and isn't an option,
2947                          * assume it's a job file for this client only.
2948                          */
2949                         while (optind < argc) {
2950                                 if (!strncmp(argv[optind], "--", 2) ||
2951                                     !strncmp(argv[optind], "-", 1))
2952                                         break;
2953
2954                                 if (fio_client_add_ini_file(cur_client, argv[optind], false))
2955                                         break;
2956                                 optind++;
2957                         }
2958                         break;
2959                 case 'R':
2960                         did_arg = true;
2961                         if (fio_client_add_ini_file(cur_client, optarg, true)) {
2962                                 do_exit++;
2963                                 exit_val = 1;
2964                         }
2965                         break;
2966                 case 'T':
2967                         did_arg = true;
2968                         do_exit++;
2969                         exit_val = fio_monotonic_clocktest(1);
2970                         break;
2971                 case 'G':
2972                         did_arg = true;
2973                         do_exit++;
2974                         exit_val = fio_crctest(optarg);
2975                         break;
2976                 case 'M':
2977                         did_arg = true;
2978                         do_exit++;
2979                         exit_val = fio_memcpy_test(optarg);
2980                         break;
2981                 case 'L': {
2982                         long long val;
2983
2984                         if (check_str_time(optarg, &val, 1)) {
2985                                 log_err("fio: failed parsing time %s\n", optarg);
2986                                 do_exit++;
2987                                 exit_val = 1;
2988                                 break;
2989                         }
2990                         if (val < 1000) {
2991                                 log_err("fio: status interval too small\n");
2992                                 do_exit++;
2993                                 exit_val = 1;
2994                         }
2995                         status_interval = val / 1000;
2996                         break;
2997                         }
2998                 case 'W':
2999                         if (trigger_file)
3000                                 free(trigger_file);
3001                         trigger_file = strdup(optarg);
3002                         break;
3003                 case 'H':
3004                         if (trigger_cmd)
3005                                 free(trigger_cmd);
3006                         trigger_cmd = strdup(optarg);
3007                         break;
3008                 case 'J':
3009                         if (trigger_remote_cmd)
3010                                 free(trigger_remote_cmd);
3011                         trigger_remote_cmd = strdup(optarg);
3012                         break;
3013                 case 'K':
3014                         if (aux_path)
3015                                 free(aux_path);
3016                         aux_path = strdup(optarg);
3017                         break;
3018                 case 'B':
3019                         if (check_str_time(optarg, &trigger_timeout, 1)) {
3020                                 log_err("fio: failed parsing time %s\n", optarg);
3021                                 do_exit++;
3022                                 exit_val = 1;
3023                         }
3024                         trigger_timeout /= 1000000;
3025                         break;
3026
3027                 case 'A':
3028                         did_arg = true;
3029                         merge_blktrace_only = true;
3030                         break;
3031                 case '?':
3032                         log_err("%s: unrecognized option '%s'\n", argv[0],
3033                                                         argv[optind - 1]);
3034                         show_closest_option(argv[optind - 1]);
3035                         fio_fallthrough;
3036                 default:
3037                         do_exit++;
3038                         exit_val = 1;
3039                         break;
3040                 }
3041                 if (do_exit)
3042                         break;
3043         }
3044
3045         if (do_exit && !(is_backend || nr_clients))
3046                 exit(exit_val);
3047
3048         if (nr_clients && fio_clients_connect())
3049                 exit(1);
3050
3051         if (is_backend && backend)
3052                 return fio_start_server(pid_file);
3053         else if (pid_file)
3054                 free(pid_file);
3055
3056         if (td) {
3057                 if (!ret) {
3058                         ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type);
3059                         if (ret)
3060                                 exit(1);
3061                 }
3062         }
3063
3064         while (!ret && optind < argc) {
3065                 ini_idx++;
3066                 ini_file = realloc(ini_file, ini_idx * sizeof(char *));
3067                 ini_file[ini_idx - 1] = strdup(argv[optind]);
3068                 optind++;
3069         }
3070
3071 out_free:
3072         return ini_idx;
3073 }
3074
3075 int fio_init_options(void)
3076 {
3077         f_out = stdout;
3078         f_err = stderr;
3079
3080         fio_options_fill_optstring();
3081         fio_options_dup_and_init(l_opts);
3082
3083         atexit(free_shm);
3084
3085         if (fill_def_thread())
3086                 return 1;
3087
3088         return 0;
3089 }
3090
3091 extern int fio_check_options(struct thread_options *);
3092
3093 int parse_options(int argc, char *argv[])
3094 {
3095         const int type = FIO_CLIENT_TYPE_CLI;
3096         int job_files, i;
3097
3098         if (fio_init_options())
3099                 return 1;
3100         if (fio_test_cconv(&def_thread.o))
3101                 log_err("fio: failed internal cconv test\n");
3102
3103         job_files = parse_cmd_line(argc, argv, type);
3104
3105         if (job_files > 0) {
3106                 for (i = 0; i < job_files; i++) {
3107                         if (i && fill_def_thread())
3108                                 return 1;
3109                         if (nr_clients) {
3110                                 if (fio_clients_send_ini(ini_file[i]))
3111                                         return 1;
3112                                 free(ini_file[i]);
3113                         } else if (!is_backend) {
3114                                 if (parse_jobs_ini(ini_file[i], 0, i, type))
3115                                         return 1;
3116                                 free(ini_file[i]);
3117                         }
3118                 }
3119         } else if (nr_clients) {
3120                 if (fill_def_thread())
3121                         return 1;
3122                 if (fio_clients_send_ini(NULL))
3123                         return 1;
3124         }
3125
3126         free(ini_file);
3127         fio_options_free(&def_thread);
3128         filesetup_mem_free();
3129
3130         if (!thread_number) {
3131                 if (parse_dryrun())
3132                         return 0;
3133                 if (exec_profile)
3134                         return 0;
3135                 if (is_backend || nr_clients)
3136                         return 0;
3137                 if (did_arg)
3138                         return 0;
3139
3140                 log_err("No job(s) defined\n\n");
3141                 usage(argv[0]);
3142                 return 1;
3143         }
3144
3145         if (output_format & FIO_OUTPUT_NORMAL)
3146                 log_info("%s\n", fio_version_string);
3147
3148         return 0;
3149 }
3150
3151 void options_default_fill(struct thread_options *o)
3152 {
3153         memcpy(o, &def_thread.o, sizeof(*o));
3154 }
3155
3156 struct thread_data *get_global_options(void)
3157 {
3158         return &def_thread;
3159 }