From: Jens Axboe Date: Fri, 5 Mar 2010 08:48:44 +0000 (+0100) Subject: Cleanup profile support X-Git-Tag: fio-1.38~35 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=07b3232de97ac32a873f0b5d17c8f49c18ed3ae7 Cleanup profile support This is closer to where it needs to end up. No ext_options, just include profile options in the general option table (and mark them private for that profile). Profile options are only available after loading a specific profile, so there should be less confusion. Signed-off-by: Jens Axboe --- diff --git a/fio.c b/fio.c index 778749d6..c33f7868 100644 --- a/fio.c +++ b/fio.c @@ -40,6 +40,7 @@ #include "verify.h" #include "diskutil.h" #include "cgroup.h" +#include "profile.h" unsigned long page_mask; unsigned long page_size; @@ -1653,6 +1654,9 @@ int main(int argc, char *argv[]) if (parse_options(argc, argv)) return 1; + if (exec_profile && load_profile(exec_profile)) + return 1; + if (!thread_number) return 0; diff --git a/fio.h b/fio.h index 91a28b4b..23e007b8 100644 --- a/fio.h +++ b/fio.h @@ -29,6 +29,7 @@ #include "ioengine.h" #include "iolog.h" #include "helpers.h" +#include "options.h" #ifdef FIO_HAVE_GUASI #include @@ -539,7 +540,7 @@ 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 512 +#define FIO_NR_OPTIONS (FIO_MAX_OPTS + 128) /* * ETA/status stuff diff --git a/init.c b/init.c index c0ce4312..acebb7d1 100644 --- a/init.c +++ b/init.c @@ -39,6 +39,7 @@ unsigned long long mlock_size = 0; FILE *f_out = NULL; FILE *f_err = NULL; char *job_section = NULL; +char *exec_profile = NULL; int write_bw_log = 0; int read_only = 0; @@ -1114,8 +1115,7 @@ static int parse_cmd_line(int argc, char *argv[]) job_section = strdup(optarg); break; case 'p': - if (load_profile(optarg)) - do_exit++; + exec_profile = strdup(optarg); break; case FIO_GETOPT_JOB: { const char *opt = l_opts[lidx].name; @@ -1204,6 +1204,8 @@ int parse_options(int argc, char *argv[]) if (!thread_number) { if (dump_cmdline) return 0; + if (exec_profile) + return 0; log_err("No jobs defined(s)\n\n"); usage(argv[0]); diff --git a/options.c b/options.c index 6cfd80d1..da9d0be4 100644 --- a/options.c +++ b/options.c @@ -16,8 +16,6 @@ #include "lib/fls.h" #include "options.h" -static FLIST_HEAD(ext_opt_list); - /* * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that. */ @@ -736,7 +734,7 @@ static int kb_base_verify(struct fio_option *o, void *data) /* * Map of job/command line options */ -static struct fio_option options[] = { +static struct fio_option options[FIO_MAX_OPTS] = { { .name = "description", .type = FIO_OPT_STR_STORE, @@ -1774,8 +1772,6 @@ static void add_to_lopt(struct option *lopt, struct fio_option *o) 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); @@ -1792,13 +1788,6 @@ void fio_options_dup_and_init(struct option *long_options) 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 { @@ -1955,7 +1944,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, &ext_opt_list, td); + ret |= parse_option(opts[i], options, td); } return ret; @@ -1963,7 +1952,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, &ext_opt_list, td); + return parse_cmd_option(opt, val, options, td); } void fio_fill_default_options(struct thread_data *td) @@ -1973,7 +1962,7 @@ void fio_fill_default_options(struct thread_data *td) int fio_show_option_help(const char *opt) { - return show_cmd_help(options, &ext_opt_list, opt); + return show_cmd_help(options, opt); } static void __options_mem(struct thread_data *td, int alloc) @@ -2027,23 +2016,31 @@ unsigned int fio_get_kb_base(void *data) return kb_base; } -void register_ext_option(struct ext_option *eopt) +int add_option(struct fio_option *o) { - dprint(FD_PARSE, "register option '%s'\n", eopt->o.name); - option_init(&eopt->o); - flist_add_tail(&eopt->list, &ext_opt_list); + struct fio_option *__o; + int opt_index = 0; + + __o = options; + while (__o->name) { + opt_index++; + __o++; + } + + memcpy(&options[opt_index], o, sizeof(*o)); + return 0; } -void prune_profile_options(const char *prof_name) +void invalidate_profile_options(const char *prof_name) { - struct ext_option *eo; - struct flist_head *n, *tmp; + struct fio_option *o; - 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); + o = options; + while (o->name) { + if (o->prof_name && !strcmp(o->prof_name, prof_name)) { + o->type = FIO_OPT_INVALID; + o->prof_name = NULL; + } + o++; } } diff --git a/options.h b/options.h index 96c81a17..cf823fc6 100644 --- a/options.h +++ b/options.h @@ -1,18 +1,15 @@ #ifndef FIO_OPTION_H #define FIO_OPTION_H +#define FIO_MAX_OPTS 512 + #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 *); +int add_option(struct fio_option *); +void invalidate_profile_options(const char *); +extern char *exec_profile; #endif diff --git a/parse.c b/parse.c index 9c0965f0..98e623a0 100644 --- a/parse.c +++ b/parse.c @@ -78,6 +78,7 @@ static void show_option_values(struct fio_option *o) static void show_option_help(struct fio_option *o, FILE *out) { const char *typehelp[] = { + "invalid", "string (opt=bla)", "string with possible k/m/g postfix (opt=4k)", "string with time postfix (opt=10s)", @@ -86,6 +87,7 @@ static void show_option_help(struct fio_option *o, FILE *out) "integer value (opt=100)", "boolean value (opt=1)", "no argument (opt)", + "deprecated", }; if (o->alias) @@ -93,6 +95,8 @@ static void show_option_help(struct fio_option *o, FILE *out) fprintf(out, "%20s: %s\n", "type", typehelp[o->type]); fprintf(out, "%20s: %s\n", "default", o->def ? o->def : "no default"); + if (o->prof_name) + fprintf(out, "%20s: only for profile '%s'\n", "valid", o->prof_name); show_option_range(o, stdout); show_option_values(o); } @@ -265,26 +269,14 @@ static inline int o_match(struct fio_option *o, const char *opt) } static struct fio_option *find_option(struct fio_option *options, - struct flist_head *eops, const char *opt) + const char *opt) { - struct flist_head *n; struct fio_option *o; 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; } @@ -604,8 +596,7 @@ 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, - struct flist_head *eops, char **post) + struct fio_option *options, char **post) { struct fio_option *o; char *ret; @@ -617,9 +608,9 @@ static struct fio_option *get_option(const char *opt, ret = (char *) opt; (*post)++; strip_blank_end(ret); - o = find_option(options, eops, ret); + o = find_option(options, ret); } else { - o = find_option(options, eops, opt); + o = find_option(options, opt); *post = NULL; } @@ -635,8 +626,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, NULL, &foo); - o2 = get_option(s2, fio_options, NULL, &foo); + o1 = get_option(s1, fio_options, &foo); + o2 = get_option(s2, fio_options, &foo); prio1 = prio2 = 0; if (o1) @@ -657,12 +648,11 @@ 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, struct flist_head *eops, - void *data) + struct fio_option *options, void *data) { struct fio_option *o; - o = find_option(options, eops, opt); + o = find_option(options, opt); if (!o) { fprintf(stderr, "Bad option <%s>\n", opt); return 1; @@ -729,8 +719,7 @@ static char *option_dup_subs(const char *opt) return strdup(out); } -int parse_option(const char *opt, struct fio_option *options, - struct flist_head *ext_opt_list, void *data) +int parse_option(const char *opt, struct fio_option *options, void *data) { struct fio_option *o; char *post, *tmp; @@ -739,7 +728,7 @@ int parse_option(const char *opt, struct fio_option *options, if (!tmp) return 1; - o = get_option(tmp, options, ext_opt_list, &post); + o = get_option(tmp, options, &post); if (!o) { fprintf(stderr, "Bad option <%s>\n", tmp); free(tmp); @@ -852,11 +841,8 @@ static void print_option(struct fio_option *o) } while (printed); } -int show_cmd_help(struct fio_option *options, struct flist_head *ext_opts, - const char *name) +int show_cmd_help(struct fio_option *options, const char *name) { - struct flist_head *n; - struct ext_option *eo; struct fio_option *o, *closest; unsigned int best_dist; int found = 0; @@ -872,6 +858,8 @@ int show_cmd_help(struct fio_option *options, struct flist_head *ext_opts, if (o->type == FIO_OPT_DEPRECATED) continue; + if (!exec_profile && o->prof_name) + continue; if (name) { if (!strcmp(name, o->name) || @@ -891,7 +879,7 @@ int show_cmd_help(struct fio_option *options, struct flist_head *ext_opts, if (show_all || match) { found = 1; if (match) - printf("%24s: %s\n", o->name, o->help); + printf("%20s: %s\n", o->name, o->help); if (show_all) { if (!o->parent) print_option(o); @@ -908,18 +896,6 @@ int show_cmd_help(struct fio_option *options, struct flist_head *ext_opts, 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"); diff --git a/parse.h b/parse.h index 5f602a37..8f7982ad 100644 --- a/parse.h +++ b/parse.h @@ -7,7 +7,8 @@ * Option types */ enum fio_opt_type { - FIO_OPT_STR = 0, + FIO_OPT_INVALID = 0, + FIO_OPT_STR, FIO_OPT_STR_VAL, FIO_OPT_STR_VAL_TIME, FIO_OPT_STR_STORE, @@ -52,14 +53,15 @@ struct fio_option { const struct value_pair posval[PARSE_MAX_VP];/* possible values */ const char *parent; /* parent option */ int (*verify)(struct fio_option *, void *); + const char *prof_name; /* only valid for specific profile */ }; typedef int (str_cb_fn)(void *, char *); -extern int parse_option(const char *, struct fio_option *, struct flist_head *, void *); +extern int parse_option(const char *, struct fio_option *, void *); extern void sort_options(char **, struct fio_option *, int); -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 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 option_init(struct fio_option *); extern void options_init(struct fio_option *); diff --git a/profile.c b/profile.c index 44e62699..354b06d3 100644 --- a/profile.c +++ b/profile.c @@ -31,34 +31,40 @@ int load_profile(const char *profile) return 1; } -static void add_profile_options(struct profile_ops *ops) +static int add_profile_options(struct profile_ops *ops) { - struct fio_option *fo; - struct ext_option *eo; + struct fio_option *o; if (!ops->options) - return; + return 0; - 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++; + o = ops->options; + while (o->name) { + o->prof_name = ops->name; + if (add_option(o)) + return 1; + o++; } + + return 0; } -void register_profile(struct profile_ops *ops) +int register_profile(struct profile_ops *ops) { + int ret; + dprint(FD_PROFILE, "register profile '%s'\n", ops->name); flist_add_tail(&ops->list, &profile_list); - add_profile_options(ops); + ret = add_profile_options(ops); + if (ret) + invalidate_profile_options(ops->name); + + return ret; } 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); + invalidate_profile_options(ops->name); } diff --git a/profile.h b/profile.h index 8ea77d9b..dbfb9c2e 100644 --- a/profile.h +++ b/profile.h @@ -24,7 +24,7 @@ struct profile_ops { const char **cmdline; }; -void register_profile(struct profile_ops *); +int register_profile(struct profile_ops *); void unregister_profile(struct profile_ops *); int load_profile(const char *); diff --git a/profiles/tiobench.c b/profiles/tiobench.c index 4bdcfa24..aba0785c 100644 --- a/profiles/tiobench.c +++ b/profiles/tiobench.c @@ -92,7 +92,8 @@ static struct profile_ops tiobench_profile = { static void fio_init tiobench_register(void) { - register_profile(&tiobench_profile); + if (register_profile(&tiobench_profile)) + log_err("fio: failed to register profile 'tiobench'\n"); } static void fio_exit tiobench_unregister(void)