Add support for loadable profiles
authorJens Axboe <jens.axboe@oracle.com>
Thu, 4 Mar 2010 11:43:20 +0000 (12:43 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 4 Mar 2010 11:43:20 +0000 (12:43 +0100)
Split the only existing profile, tiobench, into this setup.

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

index ce63cfc896d5e4dab3e027d8058879fb16d06a2a..ce2374b62c9ad89777f983ecc30166be0f16181f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ SCRIPTS = fio_generate_plots
 OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \
        eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
        rbtree.o diskutil.o fifo.o blktrace.o smalloc.o filehash.o helpers.o \
-       cgroup.o
+       cgroup.o profile.o
 
 OBJS += crc/crc7.o
 OBJS += crc/crc16.o
@@ -32,6 +32,8 @@ OBJS += engines/net.o
 OBJS += engines/syslet-rw.o
 OBJS += engines/guasi.o
 
+OBJS += profiles/tiobench.o
+
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
        QUIET_CC        = @echo '   ' CC $@;
diff --git a/debug.h b/debug.h
index 1a2b79ab6d24b4a385ed1720f718dc29a345cf3b..71b346d8d41bc716dfd59b3d1e1887cdcbebe89a 100644 (file)
--- a/debug.h
+++ b/debug.h
@@ -16,6 +16,7 @@ enum {
        FD_DISKUTIL,
        FD_JOB,
        FD_MUTEX,
+       FD_PROFILE,
        FD_DEBUG_MAX,
 };
 
diff --git a/fio.h b/fio.h
index bdc1708123e89f73f704fecdd34301f76f1ca37e..7eb02ad42dbbb9b66f7569ff6f82f34a6f2cf17d 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -28,7 +28,6 @@
 #include "io_ddir.h"
 #include "ioengine.h"
 #include "iolog.h"
-#include "profiles.h"
 #include "helpers.h"
 
 #ifdef FIO_HAVE_GUASI
@@ -271,7 +270,7 @@ struct thread_options {
        /*
         * Benchmark profile type
         */
-       unsigned int profile;
+       char *profile;
 
        /*
         * blkio cgroup support
@@ -538,6 +537,7 @@ extern void fio_options_dup_and_init(struct option *);
 extern void options_mem_dupe(struct thread_data *);
 extern void options_mem_free(struct thread_data *);
 extern void td_fill_rand_seeds(struct thread_data *);
+extern void add_job_opts(const char **);
 #define FIO_GETOPT_JOB         0x89988998
 #define FIO_NR_OPTIONS         128
 
diff --git a/flist.h b/flist.h
index 95023c75aa1799732ea8f2ea99e64c3df4027644..7aca9730b2e9621349cfb27b427c3ff19f91829f 100644 (file)
--- a/flist.h
+++ b/flist.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_FLIST_H
 #define _LINUX_FLIST_H
 
+#include <stdlib.h>
+
 #undef offsetof
 #ifdef __compiler_offsetof
 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
diff --git a/init.c b/init.c
index 7785e9e42649f9c509e1358c5c159edba43bad2f..c0ce4312088aae2abcce9b1b8d385d84b9e8c161 100644 (file)
--- a/init.c
+++ b/init.c
@@ -19,6 +19,7 @@
 #include "smalloc.h"
 #include "filehash.h"
 #include "verify.h"
+#include "profile.h"
 
 static char fio_version_string[] = "fio 1.37";
 
@@ -136,26 +137,6 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
        },
 };
 
-static const char *tiobench_opts[] = {
-       "buffered=0", "size=4*1024*$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;
@@ -655,6 +636,43 @@ err:
        return -1;
 }
 
+/*
+ * Parse as if 'o' was a command line
+ */
+void add_job_opts(const char **o)
+{
+       struct thread_data *td, *td_parent;
+       int i, in_global = 1;
+       char jobname[32];
+
+       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);
+}
+
 static int skip_this_section(const char *name)
 {
        if (!job_section)
@@ -961,6 +979,7 @@ struct debug_level debug_levels[] = {
        { .name = "diskutil",   .shift = FD_DISKUTIL },
        { .name = "job",        .shift = FD_JOB },
        { .name = "mutex",      .shift = FD_MUTEX },
+       { .name = "profile",    .shift = FD_PROFILE },
        { .name = NULL, },
 };
 
@@ -1028,57 +1047,6 @@ 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;
index 0e57e52b4abfd42eda0bb1b70e4788c05723b291..03b24377babde979427c4255cc451acd88b85343 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1726,14 +1726,8 @@ static struct fio_option options[] = {
        },
        {
                .name   = "profile",
-               .type   = FIO_OPT_STR,
+               .type   = FIO_OPT_STR_STORE,
                .off1   = td_var_offset(profile),
-               .posval = {
-                         { .ival = "tiobench",
-                           .oval = PROFILE_TIOBENCH,
-                           .help = "Perform tiobench like test",
-                         },
-               },
                .help   = "Select a specific builtin performance test",
        },
        {
diff --git a/profile.c b/profile.c
new file mode 100644 (file)
index 0000000..e56ca29
--- /dev/null
+++ b/profile.c
@@ -0,0 +1,42 @@
+#include "fio.h"
+#include "profile.h"
+#include "debug.h"
+#include "flist.h"
+
+static FLIST_HEAD(profile_list);
+
+int load_profile(const char *profile)
+{
+       struct profile_ops *ops;
+       struct flist_head *n;
+
+       dprint(FD_PROFILE, "loading profile '%s'\n", profile);
+
+       flist_for_each(n, &profile_list) {
+               ops = flist_entry(n, struct profile_ops, list);
+               if (!strcmp(profile, ops->name))
+                       break;
+
+               ops = NULL;
+       }
+
+       if (ops) {
+               add_job_opts(ops->def_ops);
+               return 0;
+       }
+
+       log_err("fio: profile '%s' not found\n", profile);
+       return 1;
+}
+
+void register_profile(struct profile_ops *ops)
+{
+       dprint(FD_PROFILE, "register profile '%s'\n", ops->name);
+       flist_add_tail(&ops->list, &profile_list);
+}
+
+void unregister_profile(struct profile_ops *ops)
+{
+       dprint(FD_PROFILE, "unregister profile '%s'\n", ops->name);
+       flist_del(&ops->list);
+}
diff --git a/profile.h b/profile.h
new file mode 100644 (file)
index 0000000..6b19606
--- /dev/null
+++ b/profile.h
@@ -0,0 +1,21 @@
+#ifndef FIO_PROFILE_H
+#define FIO_PROFILE_H
+
+#include "flist.h"
+
+#define FIO_PROFILE_VERSION    1
+
+struct profile_ops {
+       struct flist_head list;
+       char name[32];
+       int version;
+       int flags;
+
+       const char **def_ops;
+};
+
+void register_profile(struct profile_ops *);
+void unregister_profile(struct profile_ops *);
+int load_profile(const char *);
+
+#endif
diff --git a/profiles.h b/profiles.h
deleted file mode 100644 (file)
index 8203a46..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef FIO_PROFILE_H
-#define FIO_PROFILE_H
-
-enum {
-       PROFILE_NONE            = 0,
-       PROFILE_TIOBENCH        = 1,
-       PROFILE_END             = 2,
-};
-
-#endif
diff --git a/profiles/tiobench.c b/profiles/tiobench.c
new file mode 100644 (file)
index 0000000..d239468
--- /dev/null
@@ -0,0 +1,28 @@
+#include "../fio.h"
+#include "../profile.h"
+
+static const char *tb_opts[] = {
+       "buffered=0", "size=4*1024*$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 struct profile_ops tiobench_profile = {
+       .name           = "tiobench",
+       .version        = FIO_PROFILE_VERSION,
+       .def_ops        = tb_opts,
+};
+
+static void fio_init tiobench_register(void)
+{
+       register_profile(&tiobench_profile);
+}
+
+static void fio_exit tiobench_unregister(void)
+{
+       unregister_profile(&tiobench_profile);
+}