From 9f988e2ebb3bff7087cc9681a54bd7f0d0e42140 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 4 Mar 2010 10:42:38 +0100 Subject: [PATCH 1/1] Add support for registrering external options Start of support for real profiles. Signed-off-by: Jens Axboe --- options.c | 14 ++++++-- options.h | 16 +++++++++ parse.c | 100 ++++++++++++++++++++++++++++++++++-------------------- parse.h | 7 ++-- 4 files changed, 95 insertions(+), 42 deletions(-) create mode 100644 options.h diff --git a/options.c b/options.c index 1c07982d..0e57e52b 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. @@ -1946,7 +1947,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 +1955,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) @@ -2017,3 +2018,10 @@ 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); +} diff --git a/options.h b/options.h new file mode 100644 index 00000000..29bb7a16 --- /dev/null +++ b/options.h @@ -0,0 +1,16 @@ +#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; + struct fio_option o; +}; + +void register_option(struct ext_option *); + +#endif diff --git a/parse.c b/parse.c index d44d1308..13a27cc8 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; @@ -535,7 +555,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 +568,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 +586,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 +608,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; @@ -658,7 +680,8 @@ 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; @@ -667,7 +690,7 @@ int parse_option(const char *opt, struct fio_option *options, void *data) 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); @@ -858,6 +881,30 @@ 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) { + 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)) { + 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. @@ -868,27 +915,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 ae6bdead..085de1a5 100644 --- a/parse.h +++ b/parse.h @@ -1,6 +1,8 @@ #ifndef FIO_PARSE_H #define FIO_PARSE_H +#include "flist.h" + /* * Option types */ @@ -53,11 +55,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 parse_cmd_option(const char *t, const char *l, struct fio_option *, struct flist_head *, void *); extern int show_cmd_help(struct fio_option *, 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 **); -- 2.25.1