fio: remove duplicate global definition of tsc_reliable
[fio.git] / init.c
diff --git a/init.c b/init.c
index c235b05e192584073f0792253a733fd16b59aabb..b5315334c6ba9f6edc8aad0d477c25f7eff4ceaa 100644 (file)
--- a/init.c
+++ b/init.c
@@ -30,7 +30,9 @@
 #include "idletime.h"
 #include "filelock.h"
 #include "steadystate.h"
+#include "blktrace.h"
 
+#include "oslib/asprintf.h"
 #include "oslib/getopt.h"
 #include "oslib/strcasestr.h"
 
@@ -44,15 +46,16 @@ const char fio_version_string[] = FIO_VERSION;
 
 static char **ini_file;
 static int max_jobs = FIO_MAX_JOBS;
-static int dump_cmdline;
-static int parse_only;
+static bool dump_cmdline;
+static bool parse_only;
+static bool merge_blktrace_only;
 
 static struct thread_data def_thread;
 struct thread_data *threads = NULL;
 static char **job_sections;
 static int nr_job_sections;
 
-int exitall_on_terminate = 0;
+bool exitall_on_terminate = false;
 int output_format = FIO_OUTPUT_NORMAL;
 int eta_print = FIO_ETA_AUTO;
 unsigned int eta_interval_msec = 1000;
@@ -62,13 +65,13 @@ FILE *f_err = NULL;
 char *exec_profile = NULL;
 int warnings_fatal = 0;
 int terse_version = 3;
-int is_backend = 0;
-int is_local_backend = 0;
+bool is_backend = false;
+bool is_local_backend = false;
 int nr_clients = 0;
-int log_syslog = 0;
+bool log_syslog = false;
 
-int write_bw_log = 0;
-int read_only = 0;
+bool write_bw_log = false;
+bool read_only = false;
 int status_interval = 0;
 
 char *trigger_file = NULL;
@@ -286,6 +289,11 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'K',
        },
+       {
+               .name           = (char *) "merge-blktrace-only",
+               .has_arg        = no_argument,
+               .val            = 'A' | FIO_CLIENT_FLAG,
+       },
        {
                .name           = NULL,
        },
@@ -737,19 +745,12 @@ static int fixup_options(struct thread_data *td)
        /*
         * There's no need to check for in-flight overlapping IOs if the job
         * isn't changing data or the maximum iodepth is guaranteed to be 1
+        * when we are not in offload mode
         */
        if (o->serialize_overlap && !(td->flags & TD_F_READ_IOLOG) &&
-           (!(td_write(td) || td_trim(td)) || o->iodepth == 1))
-               o->serialize_overlap = 0;
-       /*
-        * Currently can't check for overlaps in offload mode
-        */
-       if (o->serialize_overlap && o->io_submit_mode == IO_MODE_OFFLOAD) {
-               log_err("fio: checking for in-flight overlaps when the "
-                       "io_submit_mode is offload is not supported\n");
+           (!(td_write(td) || td_trim(td)) || o->iodepth == 1) &&
+           o->io_submit_mode != IO_MODE_OFFLOAD)
                o->serialize_overlap = 0;
-               ret |= warnings_fatal;
-       }
 
        if (o->nr_files > td->files_index)
                o->nr_files = td->files_index;
@@ -852,11 +853,6 @@ static int fixup_options(struct thread_data *td)
                        o->unit_base = N2S_BYTEPERSEC;
        }
 
-#ifndef FIO_HAVE_ANY_FALLOCATE
-       /* Platform doesn't support any fallocate so force it to none */
-       o->fallocate_mode = FIO_FALLOCATE_NONE;
-#endif
-
 #ifndef CONFIG_FDATASYNC
        if (o->fdatasync_blocks) {
                log_info("fio: this platform does not support fdatasync()"
@@ -948,24 +944,12 @@ static int fixup_options(struct thread_data *td)
                ret |= 1;
        }
 
-       if (fio_option_is_set(o, clat_percentiles) &&
-           !fio_option_is_set(o, lat_percentiles)) {
-               o->lat_percentiles = !o->clat_percentiles;
-       } else if (fio_option_is_set(o, lat_percentiles) &&
-                  !fio_option_is_set(o, clat_percentiles)) {
-               o->clat_percentiles = !o->lat_percentiles;
-       } else if (fio_option_is_set(o, lat_percentiles) &&
-                  fio_option_is_set(o, clat_percentiles) &&
-                  o->lat_percentiles && o->clat_percentiles) {
-               log_err("fio: lat_percentiles and clat_percentiles are "
-                       "mutually exclusive\n");
-               ret |= 1;
-       }
-
        if (o->disable_lat)
                o->lat_percentiles = 0;
        if (o->disable_clat)
                o->clat_percentiles = 0;
+       if (o->disable_slat)
+               o->slat_percentiles = 0;
 
        /*
         * Fix these up to be nsec internally
@@ -1046,6 +1030,7 @@ static void td_fill_rand_seeds_internal(struct thread_data *td, bool use64)
        init_rand_seed(&td->poisson_state[2], td->rand_seeds[FIO_RAND_POISSON3_OFF], 0);
        init_rand_seed(&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF], false);
        init_rand_seed(&td->zone_state, td->rand_seeds[FIO_RAND_ZONE_OFF], false);
+       init_rand_seed(&td->prio_state, td->rand_seeds[FIO_RAND_PRIO_CMDS], false);
 
        if (!td_random(td))
                return;
@@ -1217,7 +1202,7 @@ static void init_flags(struct thread_data *td)
 
 static int setup_random_seeds(struct thread_data *td)
 {
-       unsigned long seed;
+       uint64_t seed;
        unsigned int i;
 
        if (!td->o.rand_repeatable && !fio_option_is_set(&td->o, rand_seed)) {
@@ -1273,8 +1258,7 @@ static char *make_filename(char *buf, size_t buf_size,struct thread_options *o,
        for (f = &fpre_keywords[0]; f->keyword; f++)
                f->strlen = strlen(f->keyword);
 
-       buf[buf_size - 1] = '\0';
-       strncpy(buf, o->filename_format, buf_size - 1);
+       snprintf(buf, buf_size, "%s", o->filename_format);
 
        memset(copy, 0, sizeof(copy));
        for (f = &fpre_keywords[0]; f->keyword; f++) {
@@ -1353,7 +1337,7 @@ static char *make_filename(char *buf, size_t buf_size,struct thread_options *o,
                        if (post_start)
                                strncpy(dst, buf + post_start, dst_left);
 
-                       strncpy(buf, copy, buf_size - 1);
+                       snprintf(buf, buf_size, "%s", copy);
                } while (1);
        }
 
@@ -1438,7 +1422,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                   int recursed, int client_type)
 {
        unsigned int i;
-       char fname[PATH_MAX];
+       char fname[PATH_MAX + 1];
        int numjobs, file_alloced;
        struct thread_options *o = &td->o;
        char logname[PATH_MAX + 32];
@@ -1513,6 +1497,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
 
        td->ts.clat_percentiles = o->clat_percentiles;
        td->ts.lat_percentiles = o->lat_percentiles;
+       td->ts.slat_percentiles = o->slat_percentiles;
        td->ts.percentile_precision = o->percentile_precision;
        memcpy(td->ts.percentile_list, o->percentile_list, sizeof(o->percentile_list));
        td->ts.sig_figs = o->sig_figs;
@@ -1523,6 +1508,8 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                td->ts.lat_stat[i].min_val = ULONG_MAX;
                td->ts.bw_stat[i].min_val = ULONG_MAX;
                td->ts.iops_stat[i].min_val = ULONG_MAX;
+               td->ts.clat_high_prio_stat[i].min_val = ULONG_MAX;
+               td->ts.clat_low_prio_stat[i].min_val = ULONG_MAX;
        }
        td->ts.sync_stat.min_val = ULONG_MAX;
        td->ddir_seq_nr = o->ddir_seq_nr;
@@ -1724,6 +1711,14 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
        if (td_steadystate_init(td))
                goto err;
 
+       if (o->merge_blktrace_file && !merge_blktrace_iologs(td))
+               goto err;
+
+       if (merge_blktrace_only) {
+               put_job(td);
+               return 0;
+       }
+
        /*
         * recurse add identical jobs, clear numjobs and stonewall options
         * as they don't apply to sub-jobs
@@ -1879,7 +1874,7 @@ static int __parse_jobs_ini(struct thread_data *td,
                }
        }
 
-       string = malloc(4096);
+       string = malloc(OPT_LEN_MAX);
 
        /*
         * it's really 256 + small bit, 280 should suffice
@@ -1912,7 +1907,7 @@ static int __parse_jobs_ini(struct thread_data *td,
                        if (is_buf)
                                p = strsep(&file, "\n");
                        else
-                               p = fgets(string, 4096, f);
+                               p = fgets(string, OPT_LEN_MAX, f);
                        if (!p)
                                break;
                }
@@ -1981,7 +1976,7 @@ static int __parse_jobs_ini(struct thread_data *td,
                                if (is_buf)
                                        p = strsep(&file, "\n");
                                else
-                                       p = fgets(string, 4096, f);
+                                       p = fgets(string, OPT_LEN_MAX, f);
                                if (!p)
                                        break;
                                dprint(FD_PARSE, "%s", p);
@@ -2021,19 +2016,12 @@ static int __parse_jobs_ini(struct thread_data *td,
                                 */
                                if (access(filename, F_OK) &&
                                    (ts = strrchr(file, '/'))) {
-                                       int len = ts - file +
-                                               strlen(filename) + 2;
-
-                                       if (!(full_fn = calloc(1, len))) {
+                                       if (asprintf(&full_fn, "%.*s%s",
+                                                (int)(ts - file + 1), file,
+                                                filename) < 0) {
                                                ret = ENOMEM;
                                                break;
                                        }
-
-                                       strncpy(full_fn,
-                                               file, (ts - file) + 1);
-                                       strncpy(full_fn + (ts - file) + 1,
-                                               filename, strlen(filename));
-                                       full_fn[len - 1] = 0;
                                        filename = full_fn;
                                }
 
@@ -2173,6 +2161,7 @@ static void usage(const char *name)
        printf("  --debug=options\tEnable debug logging. May be one/more of:\n");
        show_debug_categories();
        printf("  --parse-only\t\tParse options only, don't start any IO\n");
+       printf("  --merge-blktrace-only\tMerge blktraces only, don't start any IO\n");
        printf("  --output\t\tWrite output to file\n");
        printf("  --bandwidth-log\tGenerate aggregate bandwidth logs\n");
        printf("  --minimal\t\tMinimal (terse) output\n");
@@ -2471,7 +2460,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
        char *ostr = cmd_optstr;
        char *pid_file = NULL;
        void *cur_client = NULL;
-       int backend = 0;
+       bool backend = false;
 
        /*
         * Reset optind handling, since we may call this multiple times
@@ -2497,7 +2486,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        exit_val = 1;
                        break;
                case 'b':
-                       write_bw_log = 1;
+                       write_bw_log = true;
                        break;
                case 'o': {
                        FILE *tmp;
@@ -2552,7 +2541,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        break;
                case 's':
                        did_arg = true;
-                       dump_cmdline = 1;
+                       dump_cmdline = true;
                        break;
                case 'r':
                        read_only = 1;
@@ -2618,7 +2607,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        break;
                case 'P':
                        did_arg = true;
-                       parse_only = 1;
+                       parse_only = true;
                        break;
                case 'x': {
                        size_t new_size;
@@ -2743,8 +2732,8 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        }
                        if (optarg)
                                fio_server_set_arg(optarg);
-                       is_backend = 1;
-                       backend = 1;
+                       is_backend = true;
+                       backend = true;
 #else
                        log_err("fio: client/server requires SHM support\n");
                        do_exit++;
@@ -2889,10 +2878,16 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        }
                        trigger_timeout /= 1000000;
                        break;
+
+               case 'A':
+                       did_arg = true;
+                       merge_blktrace_only = true;
+                       break;
                case '?':
                        log_err("%s: unrecognized option '%s'\n", argv[0],
                                                        argv[optind - 1]);
                        show_closest_option(argv[optind - 1]);
+                       /* fall through */
                default:
                        do_exit++;
                        exit_val = 1;