Add support for simple profile benchmarks
authorJens Axboe <jens.axboe@oracle.com>
Fri, 13 Nov 2009 20:23:07 +0000 (21:23 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 13 Nov 2009 20:23:07 +0000 (21:23 +0100)
One of the reasons that tiobench gets used a lot, is that you
simply have to run it. For "real" benchmarks, you usually
have to configure them first. This adds support for easy testing
by adding some predefined and included workloads. This commit
includes tiobench, to run a tiobench like workload you would
simply do:

$ fio --profile=tiobench

and that would be it.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fio.h
init.c
options.c
profiles.h [new file with mode: 0644]

diff --git a/fio.h b/fio.h
index e4ed76fbde2bf0304f477349a67db1ad488db298..1723067eb325adb33112b9239ae29869067c19ca 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -28,6 +28,7 @@
 #include "io_ddir.h"
 #include "ioengine.h"
 #include "iolog.h"
+#include "profiles.h"
 
 #ifdef FIO_HAVE_GUASI
 #include <guasi.h>
@@ -264,6 +265,11 @@ struct thread_options {
         * I/O Error handling
         */
        unsigned int continue_on_error;
+
+       /*
+        * Benchmark profile type
+        */
+       unsigned int profile;
 };
 
 #define FIO_VERROR_SIZE        128
diff --git a/init.c b/init.c
index cc0f3ba8a45b53ca0c4d7f17c5644146300dd82d..26c7d1def0e4891a06e3ac8630d20a348255d56f 100644 (file)
--- a/init.c
+++ b/init.c
@@ -126,11 +126,36 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'a',
        },
+       {
+               .name           = "profile",
+               .has_arg        = required_argument,
+               .val            = 'p',
+       },
        {
                .name           = NULL,
        },
 };
 
+static const char *tiobench_opts[] = {
+       "buffered=0", "size=256*$mb_memory", "bs=4k", "timeout=600",
+       "numjobs=4", "group_reporting", "thread", "overwrite=1",
+       "filename=.fio.tio.1:.fio.tio.2:.fio.tio.3:.fio.tio.4",
+       "name=seqwrite", "rw=write", "end_fsync=1",
+       "name=randwrite", "stonewall", "rw=randwrite", "end_fsync=1",
+       "name=seqread", "stonewall", "rw=read",
+       "name=randread", "stonewall", "rw=randread", NULL,
+};
+
+static const char **fio_prof_strings[PROFILE_END] = {
+       NULL,
+       tiobench_opts,
+};
+
+static const char *profiles[PROFILE_END] = {
+       "none",
+       "tiobench",
+};
+
 FILE *get_f_out()
 {
        return f_out;
@@ -992,6 +1017,57 @@ static int set_debug(const char *string)
 }
 #endif
 
+static int load_profile(const char *profile)
+{
+       struct thread_data *td, *td_parent;
+       const char **o;
+       int i, in_global = 1;
+       char jobname[32];
+
+       dprint(FD_PARSE, "loading profile %s\n", profile);
+
+       for (i = 0; i < PROFILE_END; i++) {
+               if (!strcmp(profile, profiles[i]))
+                       break;
+       }
+
+       if (i == PROFILE_END) {
+               log_err("fio: unknown profile %s\n", profile);
+               return 1;
+       }
+
+       o = fio_prof_strings[i];
+       if (!o)
+               return 0;
+
+       i = 0;
+       td_parent = td = NULL;
+       while (o[i]) {
+               if (!strncmp(o[i], "name", 4)) {
+                       in_global = 0;
+                       if (td)
+                               add_job(td, jobname, 0);
+                       td = NULL;
+                       sprintf(jobname, "%s", o[i] + 5);
+               }
+               if (in_global && !td_parent)
+                       td_parent = get_new_job(1, &def_thread);
+               else if (!in_global && !td) {
+                       if (!td_parent)
+                               td_parent = &def_thread;
+                       td = get_new_job(0, td_parent);
+               }
+               if (in_global)
+                       fio_options_parse(td_parent, (char **) &o[i], 1);
+               else
+                       fio_options_parse(td, (char **) &o[i], 1);
+               i++;
+       }
+       if (td)
+               add_job(td, jobname, 0);
+       return 0;
+}
+
 static int parse_cmd_line(int argc, char *argv[])
 {
        struct thread_data *td = NULL;
@@ -1058,6 +1134,10 @@ static int parse_cmd_line(int argc, char *argv[])
                                free(job_section);
                        job_section = strdup(optarg);
                        break;
+               case 'p':
+                       if (load_profile(optarg))
+                               do_exit++;
+                       break;
                case FIO_GETOPT_JOB: {
                        const char *opt = l_opts[lidx].name;
                        char *val = optarg;
index 4544378eb16e6a0aa187eb7f303c1f63457f4ec7..ff277657ea0264f2394984578ab52a629170c940 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1714,6 +1714,18 @@ static struct fio_option options[] = {
                .help   = "Continue on non-fatal errors during I/O",
                .def    = "0",
        },
+       {
+               .name   = "profile",
+               .type   = FIO_OPT_STR,
+               .off1   = td_var_offset(profile),
+               .posval = {
+                         { .ival = "tiobench",
+                           .oval = PROFILE_TIOBENCH,
+                           .help = "Perform tiobench like test",
+                         },
+               },
+               .help   = "Select a specific builtin performance test",
+       },
        {
                .name = NULL,
        },
@@ -1811,6 +1823,7 @@ static char *bc_calc(char *str)
                return str;
 
        tmp++;
+       memset(opt, 0, sizeof(opt));
        strncpy(opt, str, tmp - str);
 
        buf = malloc(128);
@@ -1879,7 +1892,7 @@ static char *fio_keyword_replace(char *opt)
                         * replace opt and free the old opt
                         */
                        opt = new;
-                       free(o_org);
+                       //free(o_org);
 
                        /*
                         * Check for potential math and invoke bc, if possible
diff --git a/profiles.h b/profiles.h
new file mode 100644 (file)
index 0000000..8203a46
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef FIO_PROFILE_H
+#define FIO_PROFILE_H
+
+enum {
+       PROFILE_NONE            = 0,
+       PROFILE_TIOBENCH        = 1,
+       PROFILE_END             = 2,
+};
+
+#endif