Adds verify_only option
[fio.git] / options.c
index a700e4da71370838818e755840049f15e08a60f3..525d31840c5e7f55944f2acec3210973de581057 100644 (file)
--- a/options.c
+++ b/options.c
@@ -834,11 +834,12 @@ static int str_opendir_cb(void *data, const char fio_unused *str)
        return add_dir_files(td, td->o.opendir);
 }
 
-static int str_verify_pattern_cb(void *data, const char *input)
+static int pattern_cb(char *pattern, unsigned int max_size,
+                     const char *input, unsigned int *pattern_bytes)
 {
-       struct thread_data *td = data;
        long off;
-       int i = 0, j = 0, len, k, base = 10, pattern_length;
+       int i = 0, j = 0, len, k, base = 10;
+       uint32_t pattern_length;
        char *loc1, *loc2;
 
        loc1 = strstr(input, "0x");
@@ -848,7 +849,7 @@ static int str_verify_pattern_cb(void *data, const char *input)
        off = strtol(input, NULL, base);
        if (off != LONG_MAX || errno != ERANGE) {
                while (off) {
-                       td->o.verify_pattern[i] = off & 0xff;
+                       pattern[i] = off & 0xff;
                        off >>= 8;
                        i++;
                }
@@ -862,13 +863,13 @@ static int str_verify_pattern_cb(void *data, const char *input)
                                j = loc2 - input + 2;
                } else
                        return 1;
-               if (len - j < MAX_PATTERN_SIZE * 2) {
+               if (len - j < max_size * 2) {
                        while (k >= j) {
                                off = converthexchartoint(input[k--]);
                                if (k >= j)
                                        off += (converthexchartoint(input[k--])
                                                * 16);
-                               td->o.verify_pattern[i++] = (char) off;
+                               pattern[i++] = (char) off;
                        }
                }
        }
@@ -878,19 +879,19 @@ static int str_verify_pattern_cb(void *data, const char *input)
         * the number of memcpy's we have to do when verifying the IO.
         */
        pattern_length = i;
-       while (i > 1 && i * 2 <= MAX_PATTERN_SIZE) {
-               memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], i);
+       while (i > 1 && i * 2 <= max_size) {
+               memcpy(&pattern[i], &pattern[0], i);
                i *= 2;
        }
 
        /*
         * Fill remainder, if the pattern multiple ends up not being
-        * MAX_PATTERN_SIZE.
+        * max_size.
         */
-       while (i > 1 && i < MAX_PATTERN_SIZE) {
-               unsigned int b = min(pattern_length, MAX_PATTERN_SIZE - i);
+       while (i > 1 && i < max_size) {
+               unsigned int b = min(pattern_length, max_size - i);
 
-               memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], b);
+               memcpy(&pattern[i], &pattern[0], b);
                i += b;
        }
 
@@ -899,19 +900,45 @@ static int str_verify_pattern_cb(void *data, const char *input)
                 * The code in verify_io_u_pattern assumes a single byte pattern
                 * fills the whole verify pattern buffer.
                 */
-               memset(td->o.verify_pattern, td->o.verify_pattern[0],
-                      MAX_PATTERN_SIZE);
+               memset(pattern, pattern[0], max_size);
+       }
+
+       *pattern_bytes = i;
+       return 0;
+}
+
+static int str_buffer_pattern_cb(void *data, const char *input)
+{
+       struct thread_data *td = data;
+       int ret;
+
+       ret = pattern_cb(td->o.buffer_pattern, MAX_PATTERN_SIZE, input,
+                               &td->o.buffer_pattern_bytes);
+
+       if (!ret) {
+               td->o.refill_buffers = 0;
+               td->o.scramble_buffers = 0;
+               td->o.zero_buffers = 0;
        }
 
-       td->o.verify_pattern_bytes = i;
+       return ret;
+}
+
+static int str_verify_pattern_cb(void *data, const char *input)
+{
+       struct thread_data *td = data;
+       int ret;
+
+       ret = pattern_cb(td->o.verify_pattern, MAX_PATTERN_SIZE, input,
+                               &td->o.verify_pattern_bytes);
 
        /*
         * VERIFY_META could already be set
         */
-       if (td->o.verify == VERIFY_NONE)
+       if (!ret && td->o.verify == VERIFY_NONE)
                td->o.verify = VERIFY_PATTERN;
 
-       return 0;
+       return ret;
 }
 
 static int str_gtod_reduce_cb(void *data, int *il)
@@ -1042,6 +1069,10 @@ struct opt_group *opt_group_from_mask(unsigned int *mask)
 }
 
 static struct opt_group fio_opt_cat_groups[] = {
+       {
+               .name   = "Latency profiling",
+               .mask   = FIO_OPT_G_LATPROF,
+       },
        {
                .name   = "Rate",
                .mask   = FIO_OPT_G_RATE,
@@ -1622,6 +1653,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_RANDOM,
        },
+       {
+               .name   = "randseed",
+               .lname  = "The random generator seed",
+               .type   = FIO_OPT_INT,
+               .off1   = td_var_offset(rand_seed),
+               .help   = "Set the random generator seed value",
+               .parent = "rw",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_RANDOM,
+       },
        {
                .name   = "use_os_rand",
                .lname  = "Use OS random",
@@ -1976,6 +2017,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_GENERAL,
                .group  = FIO_OPT_G_RUNTIME,
        },
+       {
+               .name   = "verify_only",
+               .lname  = "Verify only",
+               .type   = FIO_OPT_STR_SET,
+               .off1   = td_var_offset(verify_only),
+               .help   = "Verifies previously written data is still valid",
+               .category = FIO_OPT_C_GENERAL,
+               .group  = FIO_OPT_G_RUNTIME,
+       },
        {
                .name   = "ramp_time",
                .lname  = "Ramp time",
@@ -2623,7 +2673,38 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .off1   = td_var_offset(max_latency),
                .help   = "Maximum tolerated IO latency (usec)",
                .category = FIO_OPT_C_IO,
-               .group = FIO_OPT_G_RATE,
+               .group = FIO_OPT_G_LATPROF,
+       },
+       {
+               .name   = "latency_target",
+               .lname  = "Latency Target (usec)",
+               .type   = FIO_OPT_STR_VAL_TIME,
+               .off1   = td_var_offset(latency_target),
+               .help   = "Ramp to max queue depth supporting this latency",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_LATPROF,
+       },
+       {
+               .name   = "latency_window",
+               .lname  = "Latency Window (usec)",
+               .type   = FIO_OPT_STR_VAL_TIME,
+               .off1   = td_var_offset(latency_window),
+               .help   = "Time to sustain latency_target",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_LATPROF,
+       },
+       {
+               .name   = "latency_percentile",
+               .lname  = "Latency Percentile",
+               .type   = FIO_OPT_FLOAT_LIST,
+               .off1   = td_var_offset(latency_percentile),
+               .help   = "Percentile of IOs must be below latency_target",
+               .def    = "100",
+               .maxlen = 1,
+               .minfp  = 0.0,
+               .maxfp  = 100.0,
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_LATPROF,
        },
        {
                .name   = "invalidate",
@@ -2901,6 +2982,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IO_BUF,
        },
+       {
+               .name   = "buffer_pattern",
+               .lname  = "Buffer pattern",
+               .type   = FIO_OPT_STR,
+               .cb     = str_buffer_pattern_cb,
+               .help   = "Fill pattern for IO buffers",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IO_BUF,
+       },
        {
                .name   = "buffer_compress_percentage",
                .lname  = "Buffer compression percentage",
@@ -3550,7 +3640,8 @@ static char **dup_and_sub_options(char **opts, int num_opts)
        return opts_copy;
 }
 
-int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
+int fio_options_parse(struct thread_data *td, char **opts, int num_opts,
+                       int dump_cmdline)
 {
        int i, ret, unknown;
        char **opts_copy;
@@ -3561,7 +3652,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
        for (ret = 0, i = 0, unknown = 0; i < num_opts; i++) {
                struct fio_option *o;
                int newret = parse_option(opts_copy[i], opts[i], fio_options,
-                                               &o, td);
+                                               &o, td, dump_cmdline);
 
                if (opts_copy[i]) {
                        if (newret && !o) {
@@ -3590,7 +3681,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
                        if (td->eo)
                                newret = parse_option(opts_copy[i], opts[i],
                                                      td->io_ops->options, &o,
-                                                     td->eo);
+                                                     td->eo, dump_cmdline);
 
                        ret |= newret;
                        if (!o)