Allow reset of offset_increment counter
[fio.git] / init.c
diff --git a/init.c b/init.c
index 6b29aa702407a69799f54ff15a60011a105be5d8..62c7dc2472c9f67625a6b3a97d37d8847a185931 100644 (file)
--- a/init.c
+++ b/init.c
@@ -64,8 +64,6 @@ int write_bw_log = 0;
 int read_only = 0;
 int status_interval = 0;
 
-static int write_lat_log;
-
 static int prev_group_jobs;
 
 unsigned long fio_debug = 0;
@@ -172,6 +170,13 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'x' | FIO_CLIENT_FLAG,
        },
+#ifdef CONFIG_ZLIB
+       {
+               .name           = (char *) "inflate-log",
+               .has_arg        = required_argument,
+               .val            = 'X' | FIO_CLIENT_FLAG,
+       },
+#endif
        {
                .name           = (char *) "alloc-size",
                .has_arg        = required_argument,
@@ -375,6 +380,7 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent,
        profile_add_hooks(td);
 
        td->thread_number = thread_number;
+       td->subjob_number = 0;
 
        if (jobname)
                td->o.name = strdup(jobname);
@@ -630,6 +636,15 @@ static int fixup_options(struct thread_data *td)
                if (o->max_bs[DDIR_WRITE] != o->min_bs[DDIR_WRITE] &&
                    !o->verify_interval)
                        o->verify_interval = o->min_bs[DDIR_WRITE];
+
+               /*
+                * Verify interval must be smaller or equal to the
+                * write size.
+                */
+               if (o->verify_interval > o->min_bs[DDIR_WRITE])
+                       o->verify_interval = o->min_bs[DDIR_WRITE];
+               else if (td_read(td) && o->verify_interval > o->min_bs[DDIR_READ])
+                       o->verify_interval = o->min_bs[DDIR_READ];
        }
 
        if (o->pre_read) {
@@ -1056,6 +1071,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
        char fname[PATH_MAX];
        int numjobs, file_alloced;
        struct thread_options *o = &td->o;
+       char logname[PATH_MAX + 32];
 
        /*
         * the def_thread is just for options, it's not a real job
@@ -1145,15 +1161,72 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
        if (setup_rate(td))
                goto err;
 
-       if (o->lat_log_file || write_lat_log) {
-               setup_log(&td->lat_log, o->log_avg_msec, IO_LOG_TYPE_LAT);
-               setup_log(&td->slat_log, o->log_avg_msec, IO_LOG_TYPE_SLAT);
-               setup_log(&td->clat_log, o->log_avg_msec, IO_LOG_TYPE_CLAT);
+       if (o->lat_log_file) {
+               struct log_params p = {
+                       .td = td,
+                       .avg_msec = o->log_avg_msec,
+                       .log_type = IO_LOG_TYPE_LAT,
+                       .log_offset = o->log_offset,
+                       .log_gz = o->log_gz,
+                       .log_gz_store = o->log_gz_store,
+               };
+               const char *suf;
+
+               if (p.log_gz_store)
+                       suf = "log.fz";
+               else
+                       suf = "log";
+
+               snprintf(logname, sizeof(logname), "%s_lat.%d.%s",
+                               o->lat_log_file, td->thread_number, suf);
+               setup_log(&td->lat_log, &p, logname);
+               snprintf(logname, sizeof(logname), "%s_slat.%d.%s",
+                               o->lat_log_file, td->thread_number, suf);
+               setup_log(&td->slat_log, &p, logname);
+               snprintf(logname, sizeof(logname), "%s_clat.%d.%s",
+                               o->lat_log_file, td->thread_number, suf);
+               setup_log(&td->clat_log, &p, logname);
+       }
+       if (o->bw_log_file) {
+               struct log_params p = {
+                       .td = td,
+                       .avg_msec = o->log_avg_msec,
+                       .log_type = IO_LOG_TYPE_BW,
+                       .log_offset = o->log_offset,
+                       .log_gz = o->log_gz,
+                       .log_gz_store = o->log_gz_store,
+               };
+               const char *suf;
+
+               if (p.log_gz_store)
+                       suf = "log.fz";
+               else
+                       suf = "log";
+
+               snprintf(logname, sizeof(logname), "%s_bw.%d.%s",
+                               o->bw_log_file, td->thread_number, suf);
+               setup_log(&td->bw_log, &p, logname);
+       }
+       if (o->iops_log_file) {
+               struct log_params p = {
+                       .td = td,
+                       .avg_msec = o->log_avg_msec,
+                       .log_type = IO_LOG_TYPE_IOPS,
+                       .log_offset = o->log_offset,
+                       .log_gz = o->log_gz,
+                       .log_gz_store = o->log_gz_store,
+               };
+               const char *suf;
+
+               if (p.log_gz_store)
+                       suf = "log.fz";
+               else
+                       suf = "log";
+
+               snprintf(logname, sizeof(logname), "%s_iops.%d.%s",
+                               o->iops_log_file, td->thread_number, suf);
+               setup_log(&td->iops_log, &p, logname);
        }
-       if (o->bw_log_file || write_bw_log)
-               setup_log(&td->bw_log, o->log_avg_msec, IO_LOG_TYPE_BW);
-       if (o->iops_log_file)
-               setup_log(&td->iops_log, o->log_avg_msec, IO_LOG_TYPE_IOPS);
 
        if (!o->name)
                o->name = strdup(jobname);
@@ -1216,6 +1289,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                td_new->o.numjobs = 1;
                td_new->o.stonewall = 0;
                td_new->o.new_group = 0;
+               td_new->subjob_number = numjobs;
 
                if (file_alloced) {
                        if (td_new->files) {
@@ -1506,11 +1580,10 @@ static void usage(const char *name)
        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"
-               "\t\t\tdiskutil,job,mutex,profile,time,net,rate\n");
+               "\t\t\tdiskutil,job,mutex,profile,time,net,rate,compress\n");
        printf("  --parse-only\t\tParse options only, don't start any IO\n");
        printf("  --output\t\tWrite output to file\n");
        printf("  --runtime\t\tRuntime in seconds\n");
-       printf("  --latency-log\t\tGenerate per-job latency logs\n");
        printf("  --bandwidth-log\tGenerate per-job bandwidth logs\n");
        printf("  --minimal\t\tMinimal (terse) output\n");
        printf("  --output-format=x\tOutput format (terse,json,normal)\n");
@@ -1545,6 +1618,9 @@ static void usage(const char *name)
        printf("  --idle-prof=option\tReport cpu idleness on a system or percpu basis\n"
                "\t\t\t(option=system,percpu) or run unit work\n"
                "\t\t\tcalibration only (option=calibrate)\n");
+#ifdef CONFIG_ZLIB
+       printf("  --inflate-log=log\tInflate and output compressed log\n");
+#endif
        printf("\nFio was written by Jens Axboe <jens.axboe@oracle.com>");
        printf("\n                   Jens Axboe <jaxboe@fusionio.com>");
        printf("\n                   Jens Axboe <axboe@fb.com>\n");
@@ -1612,6 +1688,10 @@ struct debug_level debug_levels[] = {
          .help = "Rate logging",
          .shift = FD_RATE,
        },
+       { .name = "compress",
+         .help = "Log compression logging",
+         .shift = FD_COMPRESS,
+       },
        { .name = NULL, },
 };
 
@@ -1751,7 +1831,9 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        }
                        break;
                case 'l':
-                       write_lat_log = 1;
+                       log_err("fio: --latency-log is deprecated. Use per-job latency log options.\n");
+                       do_exit++;
+                       exit_val = 1;
                        break;
                case 'b':
                        write_bw_log = 1;
@@ -1874,6 +1956,13 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        nr_job_sections++;
                        break;
                        }
+#ifdef CONFIG_ZLIB
+               case 'X':
+                       exit_val = iolog_file_inflate(optarg);
+                       did_arg++;
+                       do_exit++;
+                       break;
+#endif
                case 'p':
                        did_arg = 1;
                        if (exec_profile)
@@ -1931,10 +2020,8 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        if (!ret && !strcmp(opt, "ioengine")) {
                                free_ioengine(td);
                                if (ioengine_load(td)) {
-                                       if (td) {
-                                               put_job(td);
-                                               td = NULL;
-                                       }
+                                       put_job(td);
+                                       td = NULL;
                                        do_exit++;
                                        break;
                                }