Make fio include the git version in the version output
[fio.git] / init.c
diff --git a/init.c b/init.c
index 710e86730b7d82aa085eff13433dcc536df1f7f0..a04198f3e08c77a02a3d2286c350091106e9b086 100644 (file)
--- a/init.c
+++ b/init.c
 
 #include "fio_version.h"
 
-#if FIO_PATCH > 0
-const char fio_version_string[] =      __fio_stringify(FIO_MAJOR) "."  \
-                                       __fio_stringify(FIO_MINOR) "."  \
-                                       __fio_stringify(FIO_PATCH);
-#else
-const char fio_version_string[] =      __fio_stringify(FIO_MAJOR) "."  \
-                                       __fio_stringify(FIO_MINOR);
-#endif
+const char fio_version_string[] = FIO_VERSION;
 
 #define FIO_RANDSEED           (0xb1899bedUL)
 
@@ -74,21 +67,23 @@ static char cmd_optstr[256];
 static int did_arg;
 
 const fio_fp64_t def_percentile_list[FIO_IO_U_LIST_MAX_LEN] = {
-       { .u.f  =  1.0 },
-       { .u.f  =  5.0 },
-       { .u.f  = 10.0 },
-       { .u.f  = 20.0 },
-       { .u.f  = 30.0 },
-       { .u.f  = 40.0 },
-       { .u.f  = 50.0 },
-       { .u.f  = 60.0 },
-       { .u.f  = 70.0 },
-       { .u.f  = 80.0 },
-       { .u.f  = 90.0 },
-       { .u.f  = 95.0 },
-       { .u.f  = 99.0 },
-       { .u.f  = 99.5 },
-       { .u.f  = 99.9 },
+       { .u.f  =  1.00 },
+       { .u.f  =  5.00 },
+       { .u.f  = 10.00 },
+       { .u.f  = 20.00 },
+       { .u.f  = 30.00 },
+       { .u.f  = 40.00 },
+       { .u.f  = 50.00 },
+       { .u.f  = 60.00 },
+       { .u.f  = 70.00 },
+       { .u.f  = 80.00 },
+       { .u.f  = 90.00 },
+       { .u.f  = 95.00 },
+       { .u.f  = 99.00 },
+       { .u.f  = 99.50 },
+       { .u.f  = 99.90 },
+       { .u.f  = 99.95 },
+       { .u.f  = 99.99 },
 };
 
 #define FIO_CLIENT_FLAG                (1 << 16)
@@ -568,13 +563,22 @@ static int fixup_options(struct thread_data *td)
        }
 #endif
 
+       /*
+        * For fully compressible data, just zero them at init time.
+        * It's faster than repeatedly filling it.
+        */
+       if (td->o.compress_percentage == 100) {
+               td->o.zero_buffers = 1;
+               td->o.compress_percentage = 0;
+       }
+
        return ret;
 }
 
 /*
  * This function leaks the buffer
  */
-static char *to_kmg(unsigned int val)
+char *fio_uint_to_kmg(unsigned int val)
 {
        char *buf = malloc(32);
        char post[] = { 0, 'K', 'M', 'G', 'P', 'E', 0 };
@@ -735,10 +739,9 @@ int ioengine_load(struct thread_data *td)
  * to make sure we don't have conflicts, and initializes various
  * members of td.
  */
-static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
+static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
+                  int recursed, int client_type)
 {
-       const char *ddir_str[] = { NULL, "read", "write", "rw", NULL,
-                                  "randread", "randwrite", "randrw" };
        unsigned int i;
        char fname[PATH_MAX];
        int numjobs, file_alloced;
@@ -757,17 +760,14 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
                return 0;
        }
 
+       td->client_type = client_type;
+
        if (profile_td_init(td))
                goto err;
 
        if (ioengine_load(td))
                goto err;
 
-       if (td->o.use_thread)
-               nr_thread++;
-       else
-               nr_process++;
-
        if (td->o.odirect)
                td->io_ops->flags |= FIO_RAWIO;
 
@@ -836,37 +836,35 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
                goto err;
 
        if (td->o.write_lat_log) {
-               setup_log(&td->lat_log, td->o.log_avg_msec);
-               setup_log(&td->slat_log, td->o.log_avg_msec);
-               setup_log(&td->clat_log, td->o.log_avg_msec);
+               setup_log(&td->lat_log, td->o.log_avg_msec, IO_LOG_TYPE_LAT);
+               setup_log(&td->slat_log, td->o.log_avg_msec, IO_LOG_TYPE_SLAT);
+               setup_log(&td->clat_log, td->o.log_avg_msec, IO_LOG_TYPE_CLAT);
        }
        if (td->o.write_bw_log)
-               setup_log(&td->bw_log, td->o.log_avg_msec);
+               setup_log(&td->bw_log, td->o.log_avg_msec, IO_LOG_TYPE_BW);
        if (td->o.write_iops_log)
-               setup_log(&td->iops_log, td->o.log_avg_msec);
+               setup_log(&td->iops_log, td->o.log_avg_msec, IO_LOG_TYPE_IOPS);
 
        if (!td->o.name)
                td->o.name = strdup(jobname);
 
        if (!terse_output) {
                if (!job_add_num) {
-                       if (!strcmp(td->io_ops->name, "cpuio")) {
-                               log_info("%s: ioengine=cpu, cpuload=%u,"
-                                        " cpucycle=%u\n", td->o.name,
-                                                       td->o.cpuload,
-                                                       td->o.cpucycle);
-                       } else {
+                       if (is_backend && !recursed)
+                               fio_server_send_add_job(td);
+
+                       if (!(td->io_ops->flags & FIO_NOIO)) {
                                char *c1, *c2, *c3, *c4;
 
-                               c1 = to_kmg(td->o.min_bs[DDIR_READ]);
-                               c2 = to_kmg(td->o.max_bs[DDIR_READ]);
-                               c3 = to_kmg(td->o.min_bs[DDIR_WRITE]);
-                               c4 = to_kmg(td->o.max_bs[DDIR_WRITE]);
+                               c1 = fio_uint_to_kmg(td->o.min_bs[DDIR_READ]);
+                               c2 = fio_uint_to_kmg(td->o.max_bs[DDIR_READ]);
+                               c3 = fio_uint_to_kmg(td->o.min_bs[DDIR_WRITE]);
+                               c4 = fio_uint_to_kmg(td->o.max_bs[DDIR_WRITE]);
 
                                log_info("%s: (g=%d): rw=%s, bs=%s-%s/%s-%s,"
                                         " ioengine=%s, iodepth=%u\n",
                                                td->o.name, td->groupid,
-                                               ddir_str[td->o.td_ddir],
+                                               ddir_str(td->o.td_ddir),
                                                c1, c2, c3, c4,
                                                td->io_ops->name,
                                                td->o.iodepth);
@@ -904,7 +902,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
 
                job_add_num = numjobs - 1;
 
-               if (add_job(td_new, jobname, job_add_num))
+               if (add_job(td_new, jobname, job_add_num, 1, client_type))
                        goto err;
        }
 
@@ -917,7 +915,7 @@ err:
 /*
  * Parse as if 'o' was a command line
  */
-void add_job_opts(const char **o)
+void add_job_opts(const char **o, int client_type)
 {
        struct thread_data *td, *td_parent;
        int i, in_global = 1;
@@ -929,7 +927,7 @@ void add_job_opts(const char **o)
                if (!strncmp(o[i], "name", 4)) {
                        in_global = 0;
                        if (td)
-                               add_job(td, jobname, 0);
+                               add_job(td, jobname, 0, 0, client_type);
                        td = NULL;
                        sprintf(jobname, "%s", o[i] + 5);
                }
@@ -948,7 +946,7 @@ void add_job_opts(const char **o)
        }
 
        if (td)
-               add_job(td, jobname, 0);
+               add_job(td, jobname, 0, 0, client_type);
 }
 
 static int skip_this_section(const char *name)
@@ -986,7 +984,7 @@ static int is_empty_or_comment(char *line)
 /*
  * This is our [ini] type file parser.
  */
-int parse_jobs_ini(char *file, int is_buf, int stonewall_flag)
+int parse_jobs_ini(char *file, int is_buf, int stonewall_flag, int type)
 {
        unsigned int global;
        struct thread_data *td;
@@ -1130,7 +1128,7 @@ int parse_jobs_ini(char *file, int is_buf, int stonewall_flag)
                                for (i = 0; i < num_opts; i++)
                                        log_info("--%s ", opts[i]);
 
-                       ret = add_job(td, name, 0);
+                       ret = add_job(td, name, 0, 0, type);
                } else {
                        log_err("fio: job %s dropped\n", name);
                        put_job(td);
@@ -1177,7 +1175,7 @@ static int fill_def_thread(void)
 
 static void usage(const char *name)
 {
-       printf("fio %s\n", fio_version_string);
+       printf("%s\n", fio_version_string);
        printf("%s [options] [job options] <job file(s)>\n", name);
        printf("  --debug=options\tEnable debug logging. May be one/more of:\n"
                "\t\t\tprocess,file,io,mem,blktrace,verify,random,parse,\n"
@@ -1215,20 +1213,62 @@ static void usage(const char *name)
 
 #ifdef FIO_INC_DEBUG
 struct debug_level debug_levels[] = {
-       { .name = "process",    .shift = FD_PROCESS, },
-       { .name = "file",       .shift = FD_FILE, },
-       { .name = "io",         .shift = FD_IO, },
-       { .name = "mem",        .shift = FD_MEM, },
-       { .name = "blktrace",   .shift = FD_BLKTRACE },
-       { .name = "verify",     .shift = FD_VERIFY },
-       { .name = "random",     .shift = FD_RANDOM },
-       { .name = "parse",      .shift = FD_PARSE },
-       { .name = "diskutil",   .shift = FD_DISKUTIL },
-       { .name = "job",        .shift = FD_JOB },
-       { .name = "mutex",      .shift = FD_MUTEX },
-       { .name = "profile",    .shift = FD_PROFILE },
-       { .name = "time",       .shift = FD_TIME },
-       { .name = "net",        .shift = FD_NET },
+       { .name = "process",
+         .help = "Process creation/exit logging",
+         .shift = FD_PROCESS,
+       },
+       { .name = "file",
+         .help = "File related action logging",
+         .shift = FD_FILE,
+       },
+       { .name = "io",
+         .help = "IO and IO engine action logging (offsets, queue, completions, etc)",
+         .shift = FD_IO,
+       },
+       { .name = "mem",
+         .help = "Memory allocation/freeing logging",
+         .shift = FD_MEM,
+       },
+       { .name = "blktrace",
+         .help = "blktrace action logging",
+         .shift = FD_BLKTRACE,
+       },
+       { .name = "verify",
+         .help = "IO verification action logging",
+         .shift = FD_VERIFY,
+       },
+       { .name = "random",
+         .help = "Random generation logging",
+         .shift = FD_RANDOM,
+       },
+       { .name = "parse",
+         .help = "Parser logging",
+         .shift = FD_PARSE,
+       },
+       { .name = "diskutil",
+         .help = "Disk utility logging actions",
+         .shift = FD_DISKUTIL,
+       },
+       { .name = "job",
+         .help = "Logging related to creating/destroying jobs",
+         .shift = FD_JOB,
+       },
+       { .name = "mutex",
+         .help = "Mutex logging",
+         .shift = FD_MUTEX
+       },
+       { .name = "profile",
+         .help = "Logging related to profiles",
+         .shift = FD_PROFILE,
+       },
+       { .name = "time",
+         .help = "Logging related to time keeping functions",
+         .shift = FD_TIME,
+       },
+       { .name = "net",
+         .help = "Network logging",
+         .shift = FD_NET,
+       },
        { .name = NULL, },
 };
 
@@ -1335,7 +1375,7 @@ void parse_cmd_client(void *client, char *opt)
        fio_client_add_cmd_option(client, opt);
 }
 
-int parse_cmd_line(int argc, char *argv[])
+int parse_cmd_line(int argc, char *argv[], int client_type)
 {
        struct thread_data *td = NULL;
        int c, ini_idx = 0, lidx, ret = 0, do_exit = 0, exit_val = 0;
@@ -1408,7 +1448,7 @@ int parse_cmd_line(int argc, char *argv[])
                        break;
                case 'v':
                        if (!cur_client) {
-                               log_info("fio %s\n", fio_version_string);
+                               log_info("%s\n", fio_version_string);
                                do_exit++;
                        }
                        break;
@@ -1454,7 +1494,7 @@ int parse_cmd_line(int argc, char *argv[])
                        char *val = optarg;
 
                        if (!strncmp(opt, "name", 4) && td) {
-                               ret = add_job(td, td->o.name ?: "fio", 0);
+                               ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type);
                                if (ret)
                                        return 0;
                                td = NULL;
@@ -1526,7 +1566,7 @@ int parse_cmd_line(int argc, char *argv[])
                                exit_val = 1;
                                break;
                        }
-                       if (fio_client_add(optarg, &cur_client)) {
+                       if (fio_client_add(&fio_client_ops, optarg, &cur_client)) {
                                log_err("fio: failed adding client %s\n", optarg);
                                do_exit++;
                                exit_val = 1;
@@ -1558,7 +1598,7 @@ int parse_cmd_line(int argc, char *argv[])
 
        if (td) {
                if (!ret)
-                       ret = add_job(td, td->o.name ?: "fio", 0);
+                       ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type);
        }
 
        while (!ret && optind < argc) {
@@ -1571,10 +1611,8 @@ int parse_cmd_line(int argc, char *argv[])
        return ini_idx;
 }
 
-int parse_options(int argc, char *argv[])
+int fio_init_options(void)
 {
-       int job_files, i;
-
        f_out = stdout;
        f_err = stderr;
 
@@ -1586,7 +1624,22 @@ int parse_options(int argc, char *argv[])
        if (fill_def_thread())
                return 1;
 
-       job_files = parse_cmd_line(argc, argv);
+       return 0;
+}
+
+extern int fio_check_options(struct thread_options *);
+
+int parse_options(int argc, char *argv[])
+{
+       const int type = FIO_CLIENT_TYPE_CLI;
+       int job_files, i;
+
+       if (fio_init_options())
+               return 1;
+       if (fio_test_cconv(&def_thread.o))
+               log_err("fio: failed internal cconv test\n");
+
+       job_files = parse_cmd_line(argc, argv, type);
 
        if (job_files > 0) {
                for (i = 0; i < job_files; i++) {
@@ -1597,7 +1650,7 @@ int parse_options(int argc, char *argv[])
                                        return 1;
                                free(ini_file[i]);
                        } else if (!is_backend) {
-                               if (parse_jobs_ini(ini_file[i], 0, i))
+                               if (parse_jobs_ini(ini_file[i], 0, i, type))
                                        return 1;
                                free(ini_file[i]);
                        }
@@ -1634,7 +1687,12 @@ int parse_options(int argc, char *argv[])
        }
 
        if (!terse_output)
-               log_info("fio %s\n", fio_version_string);
+               log_info("%s\n", fio_version_string);
 
        return 0;
 }
+
+void options_default_fill(struct thread_options *o)
+{
+       memcpy(o, &def_thread.o, sizeof(*o));
+}