Recent changes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following changes since commit 4ceb30d4b44957e252a75f7ee4170f36109934c3:

  Use log_info() more consistently (2010-02-24 09:19:14 +0100)

are available in the git repository at:
  git://git.kernel.dk/fio.git master

Jens Axboe (9):
      Add check for OPT_LEN_MAX being too small
      Quote profile name
      Add support for registrering external options
      Merge branch 'master' of ssh://router/data/git/fio
      Add support for loadable profiles
      Add parser support for out-of-td option storage
      Add initial support for profile specific options
      More progress on per-profile options support
      Make sure profile options get added to long_options[]

Zhang, Yanmin (1):
      Increase OPT_LEN_MAX

 Makefile            |    4 +-
 debug.h             |    1 +
 fio.h               |    6 +-
 flist.h             |    2 +
 init.c              |  110 +++++++++----------------
 options.c           |   64 +++++++++++----
 options.h           |   18 ++++
 parse.c             |  220 +++++++++++++++++++++++++++++++++++++--------------
 parse.h             |   12 ++-
 profile.c           |   64 +++++++++++++++
 profile.h           |   31 +++++++
 profiles.h          |   10 ---
 profiles/tiobench.c |  101 +++++++++++++++++++++++
 13 files changed, 476 insertions(+), 167 deletions(-)
 create mode 100644 options.h
 create mode 100644 profile.c
 create mode 100644 profile.h
 delete mode 100644 profiles.h
 create mode 100644 profiles/tiobench.c

---

Diff of recent changes:

diff --git a/Makefile b/Makefile
index ce63cfc..ce2374b 100644
--- 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 1a2b79a..71b346d 100644
--- 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 bdc1708..91a28b4 100644
--- 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,8 +537,9 @@ 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
+#define FIO_NR_OPTIONS		512
 
 /*
  * ETA/status stuff
diff --git a/flist.h b/flist.h
index 95023c7..7aca973 100644
--- 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 19c6340..c0ce431 100644
--- 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;
diff --git a/options.c b/options.c
index 1c07982..6cfd80d 100644
--- a/options.c
+++ b/options.c
@@ -14,8 +14,9 @@
 #include "verify.h"
 #include "parse.h"
 #include "lib/fls.h"
+#include "options.h"
 
-#define td_var_offset(var)	((size_t) &((struct thread_options *)0)->var)
+static FLIST_HEAD(ext_opt_list);
 
 /*
  * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
@@ -1725,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",
 	},
 	{
@@ -1766,9 +1761,21 @@ static struct fio_option options[] = {
 	},
 };
 
+static void add_to_lopt(struct option *lopt, struct fio_option *o)
+{
+	lopt->name = (char *) o->name;
+	lopt->val = FIO_GETOPT_JOB;
+	if (o->type == FIO_OPT_STR_SET)
+		lopt->has_arg = no_argument;
+	else
+		lopt->has_arg = required_argument;
+}
+
 void fio_options_dup_and_init(struct option *long_options)
 {
 	struct fio_option *o;
+	struct ext_option *eo;
+	struct flist_head *n;
 	unsigned int i;
 
 	options_init(options);
@@ -1779,17 +1786,19 @@ void fio_options_dup_and_init(struct option *long_options)
 
 	o = &options[0];
 	while (o->name) {
-		long_options[i].name = (char *) o->name;
-		long_options[i].val = FIO_GETOPT_JOB;
-		if (o->type == FIO_OPT_STR_SET)
-			long_options[i].has_arg = no_argument;
-		else
-			long_options[i].has_arg = required_argument;
+		add_to_lopt(&long_options[i], o);
 
 		i++;
 		o++;
 		assert(i < FIO_NR_OPTIONS);
 	}
+
+	flist_for_each(n, &ext_opt_list) {
+		eo = flist_entry(n, struct ext_option, list);
+		add_to_lopt(&long_options[i], &eo->o);
+		i++;
+		assert(i < FIO_NR_OPTIONS);
+	}
 }
 
 struct fio_keyword {
@@ -1946,7 +1955,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
 
 	for (ret = 0, i = 0; i < num_opts; i++) {
 		opts[i] = fio_keyword_replace(opts[i]);
-		ret |= parse_option(opts[i], options, td);
+		ret |= parse_option(opts[i], options, &ext_opt_list, td);
 	}
 
 	return ret;
@@ -1954,7 +1963,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
 
 int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val)
 {
-	return parse_cmd_option(opt, val, options, td);
+	return parse_cmd_option(opt, val, options, &ext_opt_list, td);
 }
 
 void fio_fill_default_options(struct thread_data *td)
@@ -1964,7 +1973,7 @@ void fio_fill_default_options(struct thread_data *td)
 
 int fio_show_option_help(const char *opt)
 {
-	return show_cmd_help(options, opt);
+	return show_cmd_help(options, &ext_opt_list, opt);
 }
 
 static void __options_mem(struct thread_data *td, int alloc)
@@ -2017,3 +2026,24 @@ unsigned int fio_get_kb_base(void *data)
 
 	return kb_base;
 }
+
+void register_ext_option(struct ext_option *eopt)
+{
+	dprint(FD_PARSE, "register option '%s'\n", eopt->o.name);
+	option_init(&eopt->o);
+	flist_add_tail(&eopt->list, &ext_opt_list);
+}
+
+void prune_profile_options(const char *prof_name)
+{
+	struct ext_option *eo;
+	struct flist_head *n, *tmp;
+
+	flist_for_each_safe(n, tmp, &ext_opt_list) {
+		eo = flist_entry(n, struct ext_option, list);
+		if (strcmp(eo->prof_name, prof_name))
+			continue;
+		flist_del(&eo->list);
+		free(eo);
+	}
+}
diff --git a/options.h b/options.h
new file mode 100644
index 0000000..96c81a1
--- /dev/null
+++ b/options.h
@@ -0,0 +1,18 @@
+#ifndef FIO_OPTION_H
+#define FIO_OPTION_H
+
+#include "parse.h"
+#include "flist.h"
+
+#define td_var_offset(var)	((size_t) &((struct thread_options *)0)->var)
+
+struct ext_option {
+	struct flist_head list;
+	const char *prof_name;
+	struct fio_option o;
+};
+
+void register_ext_option(struct ext_option *);
+void prune_profile_options(const char *);
+
+#endif
diff --git a/parse.c b/parse.c
index a55e52b..9c0965f 100644
--- a/parse.c
+++ b/parse.c
@@ -12,6 +12,7 @@
 
 #include "parse.h"
 #include "debug.h"
+#include "options.h"
 
 static struct fio_option *fio_options;
 extern unsigned int fio_get_kb_base(void *);
@@ -253,16 +254,35 @@ static int check_int(const char *p, int *val)
 	return 1;
 }
 
+static inline int o_match(struct fio_option *o, const char *opt)
+{
+	if (!strcmp(o->name, opt))
+		return 1;
+	else if (o->alias && !strcmp(o->alias, opt))
+		return 1;
+
+	return 0;
+}
+
 static struct fio_option *find_option(struct fio_option *options,
-				      const char *opt)
+				      struct flist_head *eops, const char *opt)
 {
+	struct flist_head *n;
 	struct fio_option *o;
 
-	for (o = &options[0]; o->name; o++) {
-		if (!strcmp(o->name, opt))
-			return o;
-		else if (o->alias && !strcmp(o->alias, opt))
+	for (o = &options[0]; o->name; o++)
+		if (o_match(o, opt))
 			return o;
+
+	if (!eops)
+		return NULL;
+
+	flist_for_each(n, eops) {
+		struct ext_option *eopt;
+
+		eopt = flist_entry(n, struct ext_option, list);
+		if (o_match(&eopt->o, opt))
+			return &eopt->o;
 	}
 
 	return NULL;
@@ -307,9 +327,13 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 			ret = 1;
 			if (!strncmp(vp->ival, ptr, strlen(vp->ival))) {
 				ret = 0;
-				if (!o->off1)
-					break;
-				val_store(ilp, vp->oval, o->off1, data);
+				if (o->roff1)
+					*(unsigned int *) o->roff1 = vp->oval;
+				else {
+					if (!o->off1)
+						break;
+					val_store(ilp, vp->oval, o->off1, data);
+				}
 				break;
 			}
 		}
@@ -349,15 +373,31 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 			ret = fn(data, &ull);
 		else {
 			if (o->type == FIO_OPT_INT) {
-				if (first)
-					val_store(ilp, ull, o->off1, data);
-				if (!more && o->off2)
-					val_store(ilp, ull, o->off2, data);
+				if (first) {
+					if (o->roff1)
+						*(unsigned long long *) o->roff1 = ull;
+					else
+						val_store(ilp, ull, o->off1, data);
+				}
+				if (!more) {
+					if (o->roff2)
+						*(unsigned long long *) o->roff2 = ull;
+					else if (o->off2)
+						val_store(ilp, ull, o->off2, data);
+				}
 			} else {
-				if (first)
-					val_store(ullp, ull, o->off1, data);
-				if (!more && o->off2)
-					val_store(ullp, ull, o->off2, data);
+				if (first) {
+					if (o->roff1)
+						*(unsigned long long *) o->roff1 = ull;
+					else
+						val_store(ullp, ull, o->off1, data);
+				}
+				if (!more) {
+					if (o->roff2)
+						*(unsigned long long *) o->roff2 =  ull;
+					else if (o->off2)
+						val_store(ullp, ull, o->off2, data);
+				}
 			}
 		}
 		break;
@@ -365,7 +405,11 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 	case FIO_OPT_STR_STORE: {
 		fio_opt_str_fn *fn = o->cb;
 
-		cp = td_var(data, o->off1);
+		if (o->roff1)
+			cp = (char **) o->roff1;
+		else
+			cp = td_var(data, o->off1);
+
 		*cp = strdup(ptr);
 		if (fn) {
 			ret = fn(data, ptr);
@@ -407,10 +451,19 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 			}
 
 			if (first) {
-				val_store(ilp, ul1, o->off1, data);
-				val_store(ilp, ul2, o->off2, data);
+				if (o->roff1)
+					*(unsigned long *) o->roff1 = ul1;
+				else
+					val_store(ilp, ul1, o->off1, data);
+				if (o->roff2)
+					*(unsigned long *) o->roff2 = ul2;
+				else
+					val_store(ilp, ul2, o->off2, data);
 			}
-			if (o->off3 && o->off4) {
+			if (o->roff3 && o->roff4) {
+				*(unsigned long *) o->roff3 = ul1;
+				*(unsigned long *) o->roff4 = ul2;
+			} else if (o->off3 && o->off4) {
 				val_store(ilp, ul1, o->off3, data);
 				val_store(ilp, ul2, o->off4, data);
 			}
@@ -442,10 +495,18 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 		if (fn)
 			ret = fn(data, &il);
 		else {
-			if (first)
-				val_store(ilp, il, o->off1, data);
-			if (!more && o->off2)
-				val_store(ilp, il, o->off2, data);
+			if (first) {
+				if (o->roff1)
+					*(unsigned int *)o->roff1 = il;
+				else
+					val_store(ilp, il, o->off1, data);
+			}
+			if (!more) {
+				if (o->roff2)
+					*(unsigned int *) o->roff2 = il;
+				else if (o->off2)
+					val_store(ilp, il, o->off2, data);
+			}
 		}
 		break;
 	}
@@ -455,10 +516,18 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 		if (fn)
 			ret = fn(data);
 		else {
-			if (first)
-				val_store(ilp, 1, o->off1, data);
-			if (!more && o->off2)
-				val_store(ilp, 1, o->off2, data);
+			if (first) {
+				if (o->roff1)
+					*(unsigned int *) o->roff1 = 1;
+				else
+					val_store(ilp, 1, o->off1, data);
+			}
+			if (!more) {
+				if (o->roff2)
+					*(unsigned int *) o->roff2 = 1;
+				else if (o->off2)
+					val_store(ilp, 1, o->off2, data);
+			}
 		}
 		break;
 	}
@@ -535,7 +604,8 @@ static int handle_option(struct fio_option *o, const char *__ptr, void *data)
 }
 
 static struct fio_option *get_option(const char *opt,
-				     struct fio_option *options, char **post)
+				     struct fio_option *options,
+				     struct flist_head *eops, char **post)
 {
 	struct fio_option *o;
 	char *ret;
@@ -547,9 +617,9 @@ static struct fio_option *get_option(const char *opt,
 		ret = (char *) opt;
 		(*post)++;
 		strip_blank_end(ret);
-		o = find_option(options, ret);
+		o = find_option(options, eops, ret);
 	} else {
-		o = find_option(options, opt);
+		o = find_option(options, eops, opt);
 		*post = NULL;
 	}
 
@@ -565,8 +635,8 @@ static int opt_cmp(const void *p1, const void *p2)
 	s1 = strdup(*((char **) p1));
 	s2 = strdup(*((char **) p2));
 
-	o1 = get_option(s1, fio_options, &foo);
-	o2 = get_option(s2, fio_options, &foo);
+	o1 = get_option(s1, fio_options, NULL, &foo);
+	o2 = get_option(s2, fio_options, NULL, &foo);
 
 	prio1 = prio2 = 0;
 	if (o1)
@@ -587,11 +657,12 @@ void sort_options(char **opts, struct fio_option *options, int num_opts)
 }
 
 int parse_cmd_option(const char *opt, const char *val,
-		     struct fio_option *options, void *data)
+		     struct fio_option *options, struct flist_head *eops,
+		     void *data)
 {
 	struct fio_option *o;
 
-	o = find_option(options, opt);
+	o = find_option(options, eops, opt);
 	if (!o) {
 		fprintf(stderr, "Bad option <%s>\n", opt);
 		return 1;
@@ -620,6 +691,11 @@ static char *option_dup_subs(const char *opt)
 	ssize_t nchr = OPT_LEN_MAX;
 	size_t envlen;
 
+	if (strlen(in) + 1 > OPT_LEN_MAX) {
+		fprintf(stderr, "OPT_LEN_MAX (%d) is too small\n", OPT_LEN_MAX);
+		return NULL;
+	}
+
 	in[OPT_LEN_MAX] = '\0';
 	strncpy(in, opt, OPT_LEN_MAX);
 
@@ -653,14 +729,17 @@ static char *option_dup_subs(const char *opt)
 	return strdup(out);
 }
 
-int parse_option(const char *opt, struct fio_option *options, void *data)
+int parse_option(const char *opt, struct fio_option *options,
+		 struct flist_head *ext_opt_list, void *data)
 {
 	struct fio_option *o;
 	char *post, *tmp;
 
 	tmp = option_dup_subs(opt);
+	if (!tmp)
+		return 1;
 
-	o = get_option(tmp, options, &post);
+	o = get_option(tmp, options, ext_opt_list, &post);
 	if (!o) {
 		fprintf(stderr, "Bad option <%s>\n", tmp);
 		free(tmp);
@@ -773,8 +852,11 @@ static void print_option(struct fio_option *o)
 	} while (printed);
 }
 
-int show_cmd_help(struct fio_option *options, const char *name)
+int show_cmd_help(struct fio_option *options, struct flist_head *ext_opts,
+		  const char *name)
 {
+	struct flist_head *n;
+	struct ext_option *eo;
 	struct fio_option *o, *closest;
 	unsigned int best_dist;
 	int found = 0;
@@ -826,6 +908,18 @@ int show_cmd_help(struct fio_option *options, const char *name)
 	if (found)
 		return 0;
 
+	flist_for_each(n, ext_opts) {
+		eo = flist_entry(n, struct ext_option, list);
+		o = &eo->o;
+		if (!strcmp(name, o->name) ||
+		    (o->alias && !strcmp(name, o->alias))) {
+			printf("%20s: %s\n", o->name, o->help);
+			show_option_help(o, stdout);
+			printf("%20s: External, valid for '%s'\n", "Restriction", eo->prof_name);
+			return 0;
+		}
+	}
+
 	printf("No such command: %s", name);
 	if (closest) {
 		printf(" - showing closest match\n");
@@ -851,6 +945,31 @@ void fill_default_options(void *data, struct fio_option *options)
 			handle_option(o, o->def, data);
 }
 
+void option_init(struct fio_option *o)
+{
+	if (o->type == FIO_OPT_DEPRECATED)
+		return;
+	if (o->type == FIO_OPT_BOOL) {
+		o->minval = 0;
+		o->maxval = 1;
+	}
+	if (o->type == FIO_OPT_STR_SET && o->def) {
+		fprintf(stderr, "Option %s: string set option with"
+				" default will always be true\n", o->name);
+	}
+	if (!o->cb && (!o->off1 && !o->roff1)) {
+		fprintf(stderr, "Option %s: neither cb nor offset given\n",
+							o->name);
+	}
+	if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE)
+		return;
+	if (o->cb && ((o->off1 || o->off2 || o->off3 || o->off4) ||
+		      (o->roff1 || o->roff2 || o->roff3 || o->roff4))) {
+		fprintf(stderr, "Option %s: both cb and offset given\n",
+							 o->name);
+	}
+}
+
 /*
  * Sanitize the options structure. For now it just sets min/max for bool
  * values and whether both callback and offsets are given.
@@ -861,27 +980,6 @@ void options_init(struct fio_option *options)
 
 	dprint(FD_PARSE, "init options\n");
 
-	for (o = &options[0]; o->name; o++) {
-		if (o->type == FIO_OPT_DEPRECATED)
-			continue;
-		if (o->type == FIO_OPT_BOOL) {
-			o->minval = 0;
-			o->maxval = 1;
-		}
-		if (o->type == FIO_OPT_STR_SET && o->def) {
-			fprintf(stderr, "Option %s: string set option with"
-					" default will always be true\n",
-						o->name);
-		}
-		if (!o->cb && !o->off1) {
-			fprintf(stderr, "Option %s: neither cb nor offset"
-					" given\n", o->name);
-		}
-		if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE)
-			continue;
-		if (o->cb && (o->off1 || o->off2 || o->off3 || o->off4)) {
-			fprintf(stderr, "Option %s: both cb and offset given\n",
-								 o->name);
-		}
-	}
+	for (o = &options[0]; o->name; o++)
+		option_init(o);
 }
diff --git a/parse.h b/parse.h
index 5b1a53d..5f602a3 100644
--- a/parse.h
+++ b/parse.h
@@ -1,6 +1,8 @@
 #ifndef FIO_PARSE_H
 #define FIO_PARSE_H
 
+#include "flist.h"
+
 /*
  * Option types
  */
@@ -25,7 +27,7 @@ struct value_pair {
 	const char *help;		/* help text for sub option */
 };
 
-#define OPT_LEN_MAX 	1024
+#define OPT_LEN_MAX 	4096
 #define PARSE_MAX_VP	16
 
 /*
@@ -39,6 +41,7 @@ struct fio_option {
 	unsigned int off2;
 	unsigned int off3;
 	unsigned int off4;
+	void *roff1, *roff2, *roff3, *roff4;
 	unsigned int maxval;		/* max and min value */
 	int minval;
 	int neg;			/* negate value stored */
@@ -53,11 +56,12 @@ struct fio_option {
 
 typedef int (str_cb_fn)(void *, char *);
 
-extern int parse_option(const char *, struct fio_option *, void *);
+extern int parse_option(const char *, struct fio_option *, struct flist_head *, void *);
 extern void sort_options(char **, struct fio_option *, int);
-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 int parse_cmd_option(const char *t, const char *l, struct fio_option *, struct flist_head *, void *);
+extern int show_cmd_help(struct fio_option *, struct flist_head *, const char *);
 extern void fill_default_options(void *, struct fio_option *);
+extern void option_init(struct fio_option *);
 extern void options_init(struct fio_option *);
 
 extern void strip_blank_front(char **);
diff --git a/profile.c b/profile.c
new file mode 100644
index 0000000..44e6269
--- /dev/null
+++ b/profile.c
@@ -0,0 +1,64 @@
+#include "fio.h"
+#include "profile.h"
+#include "debug.h"
+#include "flist.h"
+#include "options.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) {
+		ops->prep_cmd();
+		add_job_opts(ops->cmdline);
+		return 0;
+	}
+
+	log_err("fio: profile '%s' not found\n", profile);
+	return 1;
+}
+
+static void add_profile_options(struct profile_ops *ops)
+{
+	struct fio_option *fo;
+	struct ext_option *eo;
+	
+	if (!ops->options)
+		return;
+
+	fo = ops->options;
+	while (fo->name) {
+		eo = malloc(sizeof(*eo));
+		eo->prof_name = ops->name;
+		memcpy(&eo->o, fo, sizeof(*fo));
+		register_ext_option(eo);
+		fo++;
+	}
+}
+
+void register_profile(struct profile_ops *ops)
+{
+	dprint(FD_PROFILE, "register profile '%s'\n", ops->name);
+	flist_add_tail(&ops->list, &profile_list);
+	add_profile_options(ops);
+}
+
+void unregister_profile(struct profile_ops *ops)
+{
+	dprint(FD_PROFILE, "unregister profile '%s'\n", ops->name);
+	flist_del(&ops->list);
+	prune_profile_options(ops->name);
+}
diff --git a/profile.h b/profile.h
new file mode 100644
index 0000000..8ea77d9
--- /dev/null
+++ b/profile.h
@@ -0,0 +1,31 @@
+#ifndef FIO_PROFILE_H
+#define FIO_PROFILE_H
+
+#include "flist.h"
+
+struct profile_ops {
+	struct flist_head list;
+	char name[32];
+	int flags;
+
+	/*
+	 * Profile specific options
+	 */
+	struct fio_option *options;
+
+	/*
+	 * Called after parsing options, to prepare 'cmdline'
+	 */
+	void (*prep_cmd)(void);
+
+	/*
+	 * The complete command line
+	 */
+	const char **cmdline;
+};
+
+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
index 8203a46..0000000
--- a/profiles.h
+++ /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
index 0000000..4bdcfa2
--- /dev/null
+++ b/profiles/tiobench.c
@@ -0,0 +1,101 @@
+#include "../fio.h"
+#include "../profile.h"
+#include "../parse.h"
+
+static unsigned long long size;
+static unsigned int loops = 1;
+static unsigned int bs = 4096;
+static unsigned int nthreads = 1;
+static char *dir;
+
+char sz_idx[80], bs_idx[80], loop_idx[80], dir_idx[80], t_idx[80];
+
+static const char *tb_opts[] = {
+	"buffered=0", sz_idx, bs_idx, loop_idx, dir_idx, t_idx,
+	"timeout=600", "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 fio_option options[] = {
+	{
+		.name	= "size",
+		.type	= FIO_OPT_STR_VAL,
+		.roff1	= &size,
+		.help	= "Size in MB",
+	},
+	{
+		.name	= "block",
+		.type	= FIO_OPT_INT,
+		.roff1	= &bs,
+		.help	= "Block size in bytes",
+		.def	= "4k",
+	},
+	{
+		.name	= "numruns",
+		.type	= FIO_OPT_INT,
+		.roff1	= &loops,
+		.help	= "Number of runs",
+	},
+	{
+		.name	= "dir",
+		.type	= FIO_OPT_STR_STORE,
+		.roff1	= &dir,
+		.help	= "Test directory",
+	},
+	{
+		.name	= "threads",
+		.type	= FIO_OPT_INT,
+		.roff1	= &nthreads,
+		.help	= "Number of Threads",
+	},
+	{
+		.name	= NULL,
+	},
+};
+
+/*
+ * Fill our private options into the command line
+ */
+static void tb_prep_cmdline(void)
+{
+
+	/*
+	 * tiobench uses size as MB, so multiply up
+	 */
+	size *= 1024 * 1024ULL;
+	if (size)
+		sprintf(sz_idx, "size=%llu", size);
+	else
+		strcpy(sz_idx, "size=4*1024*$mb_memory");
+
+	sprintf(bs_idx, "bs=%u", bs);
+	sprintf(loop_idx, "loops=%u", loops);
+
+	if (dir)
+		sprintf(dir_idx, "directory=%s", dir);
+	else
+		sprintf(dir_idx, "directory=./");
+
+	sprintf(t_idx, "numjobs=%u", nthreads);
+}
+
+static struct profile_ops tiobench_profile = {
+	.name		= "tiobench",
+	.options	= options,
+	.prep_cmd	= tb_prep_cmdline,
+	.cmdline	= tb_opts,
+};
+
+static void fio_init tiobench_register(void)
+{
+	register_profile(&tiobench_profile);
+}
+
+static void fio_exit tiobench_unregister(void)
+{
+	unregister_profile(&tiobench_profile);
+}
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux