[PATCH] Add default option values
authorJens Axboe <jens.axboe@oracle.com>
Wed, 10 Jan 2007 10:23:16 +0000 (11:23 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 10 Jan 2007 10:23:16 +0000 (11:23 +0100)
It's handy for the help text, and it also cleans up init.c by removing
a bunch of default option defines.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
init.c
parse.c
parse.h

diff --git a/HOWTO b/HOWTO
index 1b34c28..1c8dd4e 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -211,6 +211,9 @@ rw=str              Type of io pattern. Accepted values are:
                For certain types of io the result may still be skewed a bit,
                since the speed may be different.
 
+randrepeat=bool        For random IO workloads, seed the generator in a predictable
+               way so that results are repeatable across repetitions.
+
 size=siint     The total size of file io for this job. This may describe
                the size of the single file the job uses, or it may be
                divided between the number of files in the job. If the
diff --git a/init.c b/init.c
index aca607d..4add942 100644 (file)
--- a/init.c
+++ b/init.c
 #include "fio.h"
 #include "parse.h"
 
-/*
- * The default options
- */
-#define DEF_BS                 (4096)
-#define DEF_TIMEOUT            (0)
-#define DEF_RATE_CYCLE         (1000)
-#define DEF_ODIRECT            (1)
-#define DEF_IO_ENGINE          (FIO_SYNCIO)
-#define DEF_IO_ENGINE_NAME     "sync"
-#define DEF_SEQUENTIAL         (1)
-#define DEF_RAND_REPEAT                (1)
-#define DEF_OVERWRITE          (0)
-#define DEF_INVALIDATE         (1)
-#define DEF_SYNCIO             (0)
-#define DEF_RANDSEED           (0xb1899bedUL)
-#define DEF_BWAVGTIME          (500)
-#define DEF_CREATE_SER         (1)
-#define DEF_CREATE_FSYNC       (1)
-#define DEF_LOOPS              (1)
-#define DEF_VERIFY             (0)
-#define DEF_STONEWALL          (0)
-#define DEF_NUMJOBS            (1)
-#define DEF_USE_THREAD         (0)
-#define DEF_FILE_SIZE          (1024 * 1024 * 1024UL)
-#define DEF_ZONE_SIZE          (0)
-#define DEF_ZONE_SKIP          (0)
-#define DEF_RWMIX_CYCLE                (500)
-#define DEF_RWMIX_READ         (50)
-#define DEF_NICE               (0)
-#define DEF_NR_FILES           (1)
-#define DEF_UNLINK             (1)
-#define DEF_WRITE_BW_LOG       (0)
-#define DEF_WRITE_LAT_LOG      (0)
-#define DEF_NO_RAND_MAP                (0)
-#define DEF_HUGEPAGE_SIZE      FIO_HUGE_PAGE
-#define DEF_THINKTIME_BLOCKS   (1)
+#define FIO_RANDSEED           (0xb1899bedUL)
 
 #define td_var_offset(var)     ((size_t) &((struct thread_data *)0)->var)
 
@@ -69,6 +34,9 @@ static int str_prioclass_cb(void *, unsigned int *);
 static int str_exitall_cb(void);
 static int str_cpumask_cb(void *, unsigned int *);
 
+#define __stringify_1(x)       #x
+#define __stringify(x)         __stringify_1(x)
+
 /*
  * Map of job/command line options
  */
@@ -96,24 +64,28 @@ static struct fio_option options[] = {
                .type   = FIO_OPT_STR,
                .cb     = str_rw_cb,
                .help   = "IO direction (read, write, rw, etc)",
+               .def    = "read",
        },
        {
                .name   = "ioengine",
                .type   = FIO_OPT_STR,
                .cb     = str_ioengine_cb,
                .help   = "IO engine to use (sync, aio, etc)",
+               .def    = "sync",
        },
        {
                .name   = "mem",
                .type   = FIO_OPT_STR,
                .cb     = str_mem_cb,
                .help   = "Backing type for IO buffers (malloc, shm, etc)",
+               .def    = "malloc",
        },
        {
                .name   = "verify",
                .type   = FIO_OPT_STR,
                .cb     = str_verify_cb,
                .help   = "Verify sum function (md5 or crc32)",
+               .def    = "0",
        },
        {
                .name   = "write_iolog",
@@ -159,30 +131,35 @@ static struct fio_option options[] = {
                .off1   = td_var_offset(bs[DDIR_READ]),
                .off2   = td_var_offset(bs[DDIR_WRITE]),
                .help   = "Block size unit",
+               .def    = "4k",
        },
        {
                .name   = "offset",
                .type   = FIO_OPT_STR_VAL,
                .off1   = td_var_offset(start_offset),
                .help   = "Start IO from this offset",
+               .def    = "0",
        },
        {
                .name   = "zonesize",
                .type   = FIO_OPT_STR_VAL,
                .off1   = td_var_offset(zone_size),
                .help   = "Give size of an IO zone",
+               .def    = "0",
        },
        {
                .name   = "zoneskip",
                .type   = FIO_OPT_STR_VAL,
                .off1   = td_var_offset(zone_skip),
                .help   = "Space between IO zones",
+               .def    = "0",
        },
        {
                .name   = "lockmem",
                .type   = FIO_OPT_STR_VAL,
                .cb     = str_lockmem_cb,
                .help   = "Lock down this amount of memory",
+               .def    = "0",
        },
        {
                .name   = "bsrange",
@@ -193,49 +170,64 @@ static struct fio_option options[] = {
                .off4   = td_var_offset(max_bs[DDIR_WRITE]),
                .help   = "Set block size range",
        },
+       {
+               .name   = "randrepeat",
+               .type   = FIO_OPT_INT,
+               .off1   = td_var_offset(rand_repeatable),
+               .help   = "Use repeatable random IO pattern",
+               .def    = "1",
+       },
        {
                .name   = "nrfiles",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(nr_files),
                .help   = "Split job workload between this number of files",
+               .def    = "1",
        },
        {
                .name   = "iodepth",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(iodepth),
                .help   = "Amount of IO buffers to keep in flight",
+               .def    = "1",
        },
        {
                .name   = "fsync",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(fsync_blocks),
                .help   = "Issue fsync for writes every given number of blocks",
+               .def    = "0",
        },
        {
                .name   = "rwmixcycle",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(rwmixcycle),
-               .help   = "Cycle period for mixed read/write workloads",
+               .help   = "Cycle period for mixed read/write workloads (msec)",
+               .def    = "500",
        },
        {
                .name   = "rwmixread",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(rwmixread),
-               .max_val= 100,
+               .maxval = 100,
                .help   = "Percentage of mixed workload that is reads",
+               .def    = "50",
        },
        {
                .name   = "rwmixwrite",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(rwmixwrite),
-               .max_val= 100,
+               .maxval = 100,
                .help   = "Percentage of mixed workload that is writes",
+               .def    = "50",
        },
        {
                .name   = "nice",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(nice),
                .help   = "Set job CPU nice value",
+               .maxval = 20,
+               .def    = "0",
        },
 #ifdef FIO_HAVE_IOPRIO
        {
@@ -256,12 +248,14 @@ static struct fio_option options[] = {
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(thinktime),
                .help   = "Idle time between IO buffers",
+               .def    = "0",
        },
        {
                .name   = "thinktime_blocks",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(thinktime_blocks),
                .help   = "IO buffer period between 'thinktime'",
+               .def    = "1",
        },
        {
                .name   = "rate",
@@ -279,61 +273,71 @@ static struct fio_option options[] = {
                .name   = "ratecycle",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(ratecycle),
-               .name   = "Window average for rate limits",
+               .name   = "Window average for rate limits (msec)",
+               .def    = "1000",
        },
        {
                .name   = "startdelay",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(start_delay),
                .help   = "Only start job when this period has passed",
+               .def    = "0",
        },
        {
                .name   = "timeout",
                .type   = FIO_OPT_STR_VAL_TIME,
                .off1   = td_var_offset(timeout),
                .help   = "Stop workload when this amount of time has passed",
+               .def    = "0",
        },
        {
                .name   = "invalidate",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(invalidate_cache),
                .help   = "Invalidate buffer/page cache prior to running job",
+               .def    = "1",
        },
        {
                .name   = "sync",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(sync_io),
                .help   = "Use O_SYNC for buffered writes",
+               .def    = "0",
        },
        {
                .name   = "bwavgtime",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(bw_avg_time),
-               .help   = "Time window over which to calculate bandwidth",
+               .help   = "Time window over which to calculate bandwidth (msec)",
+               .def    = "500",
        },
        {
                .name   = "create_serialize",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(create_serialize),
                .help   = "Serialize creating of job files",
+               .def    = "1",
        },
        {
                .name   = "create_fsync",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(create_fsync),
                .help   = "Fsync file after creation",
+               .def    = "1",
        },
        {
                .name   = "loops",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(loops),
                .help   = "Number of times to run the job",
+               .def    = "1",
        },
        {
                .name   = "numjobs",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(numjobs),
                .help   = "Duplicate this job this many times",
+               .def    = "1",
        },
        {
                .name   = "cpuload",
@@ -352,12 +356,14 @@ static struct fio_option options[] = {
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(odirect),
                .help   = "Use O_DIRECT IO",
+               .def    = "1",
        },
        {
                .name   = "overwrite",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(overwrite),
                .help   = "When writing, set whether to overwrite current data",
+               .def    = "0",
        },
 #ifdef FIO_HAVE_CPU_AFFINITY
        {
@@ -372,12 +378,14 @@ static struct fio_option options[] = {
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(end_fsync),
                .help   = "Include fsync at the end of job",
+               .def    = "0",
        },
        {
                .name   = "unlink",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(unlink),
-               .help   = "Unlink files after job has completed",
+               .help   = "Unlink created files after job has completed",
+               .def    = "1",
        },
        {
                .name   = "exitall",
@@ -426,6 +434,7 @@ static struct fio_option options[] = {
                .type   = FIO_OPT_STR_VAL,
                .off1   = td_var_offset(hugepage_size),
                .help   = "When using hugepages, specify size of each page",
+               .def    = __stringify(FIO_HUGE_PAGE),
        },
        {
                .name = NULL,
@@ -486,7 +495,7 @@ static struct option long_options[FIO_JOB_OPTS + FIO_CMD_OPTS] = {
        },
 };
 
-static int def_timeout = DEF_TIMEOUT;
+static int def_timeout = 0;
 
 static char fio_version_string[] = "fio 1.11";
 
@@ -502,8 +511,8 @@ unsigned long long mlock_size = 0;
 FILE *f_out = NULL;
 FILE *f_err = NULL;
 
-static int write_lat_log = DEF_WRITE_LAT_LOG;
-static int write_bw_log = DEF_WRITE_BW_LOG;
+static int write_lat_log = 0;
+static int write_bw_log = 0;
 
 /*
  * Return a free job structure.
@@ -635,16 +644,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        if (td == &def_thread)
                return 0;
 
-       /*
-        * Set default io engine, if none set
-        */
-       if (!td->io_ops) {
-               td->io_ops = load_ioengine(td, DEF_IO_ENGINE_NAME);
-               if (!td->io_ops) {
-                       log_err("default engine %s not there?\n", DEF_IO_ENGINE_NAME);
-                       return 1;
-               }
-       }
+       assert(td->io_ops);
 
        if (td->odirect)
                td->io_ops->flags |= FIO_RAWIO;
@@ -806,7 +806,7 @@ int init_random_state(struct thread_data *td)
                return 0;
 
        if (td->rand_repeatable)
-               seeds[3] = DEF_RANDSEED;
+               seeds[3] = FIO_RANDSEED;
 
        if (!td->norandommap) {
                for_each_file(td, f, i) {
@@ -1119,41 +1119,14 @@ static int fill_def_thread(void)
        }
 
        /*
-        * fill globals
+        * fill default options
         */
-       def_thread.ddir = DDIR_READ;
-       def_thread.iomix = 0;
-       def_thread.bs[DDIR_READ] = DEF_BS;
-       def_thread.bs[DDIR_WRITE] = DEF_BS;
-       def_thread.min_bs[DDIR_READ] = def_thread.min_bs[DDIR_WRITE] = 0;
-       def_thread.max_bs[DDIR_READ] = def_thread.max_bs[DDIR_WRITE] = 0;
-       def_thread.odirect = DEF_ODIRECT;
-       def_thread.ratecycle = DEF_RATE_CYCLE;
-       def_thread.sequential = DEF_SEQUENTIAL;
+       fill_default_options(&def_thread, options);
+
        def_thread.timeout = def_timeout;
-       def_thread.overwrite = DEF_OVERWRITE;
-       def_thread.invalidate_cache = DEF_INVALIDATE;
-       def_thread.sync_io = DEF_SYNCIO;
-       def_thread.mem_type = MEM_MALLOC;
-       def_thread.bw_avg_time = DEF_BWAVGTIME;
-       def_thread.create_serialize = DEF_CREATE_SER;
-       def_thread.create_fsync = DEF_CREATE_FSYNC;
-       def_thread.loops = DEF_LOOPS;
-       def_thread.verify = DEF_VERIFY;
-       def_thread.stonewall = DEF_STONEWALL;
-       def_thread.numjobs = DEF_NUMJOBS;
-       def_thread.use_thread = DEF_USE_THREAD;
-       def_thread.rwmixcycle = DEF_RWMIX_CYCLE;
-       def_thread.rwmixread = DEF_RWMIX_READ;
-       def_thread.nice = DEF_NICE;
-       def_thread.rand_repeatable = DEF_RAND_REPEAT;
-       def_thread.nr_files = DEF_NR_FILES;
-       def_thread.unlink = DEF_UNLINK;
        def_thread.write_bw_log = write_bw_log;
        def_thread.write_lat_log = write_lat_log;
-       def_thread.norandommap = DEF_NO_RAND_MAP;
-       def_thread.hugepage_size = DEF_HUGEPAGE_SIZE;
-       def_thread.thinktime_blocks = DEF_THINKTIME_BLOCKS;
+
 #ifdef FIO_HAVE_DISK_UTIL
        def_thread.do_disk_util = 1;
 #endif
diff --git a/parse.c b/parse.c
index ad09691..102e607 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -180,8 +180,10 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                if (ret)
                        break;
 
-               if (o->max_val && ull > o->max_val)
-                       ull = o->max_val;
+               if (o->maxval && ull > o->maxval)
+                       ull = o->maxval;
+               if (o->minval && ull < o->minval)
+                       ull = o->minval;
 
                if (fn)
                        ret = fn(data, &ull);
@@ -249,8 +251,10 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                if (ret)
                        break;
 
-               if (o->max_val && il > o->max_val)
-                       il = o->max_val;
+               if (o->maxval && il > o->maxval)
+                       il = o->maxval;
+               if (o->minval && il < o->minval)
+                       il = o->minval;
 
                if (fn)
                        ret = fn(data, &il);
@@ -384,8 +388,13 @@ int show_cmd_help(struct fio_option *options, const char *name)
                if (show_all || match) {
                        found = 1;
                        printf("%s: %s\n", o->name, o->help);
-                       if (match)
+                       if (match) {
                                printf("type: %s\n", typehelp[o->type]);
+                               if (o->def)
+                                       printf("default: %s\n", o->def);
+                               else
+                                       printf("defaults: no default\n");
+                       }
                }
 
                o++;
@@ -397,3 +406,14 @@ int show_cmd_help(struct fio_option *options, const char *name)
        printf("No such command: %s\n", name);
        return 1;
 }
+
+void fill_default_options(void *data, struct fio_option *options)
+{
+       struct fio_option *o = &options[0];
+
+       while (o->name) {
+               if (o->def)
+                       handle_option(o, o->def, data);
+               o++;
+       }
+}
diff --git a/parse.h b/parse.h
index 9cfd68d..dc875bd 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -19,15 +19,18 @@ enum fio_opt_type {
  * Option define
  */
 struct fio_option {
-       const char *name;
-       enum fio_opt_type type;
-       unsigned int off1;
+       const char *name;               /* option name */
+       enum fio_opt_type type;         /* option type */
+       unsigned int off1;              /* potential parameters */
        unsigned int off2;
        unsigned int off3;
        unsigned int off4;
-       unsigned int max_val;
-       void *cb;
-       const char *help;
+       unsigned int maxval;            /* max and min value */
+       unsigned int minval;
+       void *cb;                       /* callback */
+       const char *help;               /* help text for option */
+       const char *def;                /* default setting */
+       char opt_set;                   /* option was set */
 };
 
 typedef int (str_cb_fn)(void *, char *);
@@ -35,6 +38,7 @@ typedef int (str_cb_fn)(void *, char *);
 extern int parse_option(const char *, struct fio_option *, void *);
 extern int parse_cmd_option(const char *t, const char *l, struct fio_option *, void *);
 extern int show_cmd_help(struct fio_option *, const char *);
+extern void fill_default_options(void *, struct fio_option *);
 
 extern void strip_blank_front(char **);
 extern void strip_blank_end(char *);