From: Jens Axboe Date: Thu, 4 Mar 2010 13:05:48 +0000 (+0100) Subject: Add initial support for profile specific options X-Git-Tag: fio-1.38~38 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=e2de69dac799a1eecac1b52085f908729591ef5a Add initial support for profile specific options Not complete yet, we need to split option parsing for profiles a bit. Signed-off-by: Jens Axboe --- diff --git a/options.c b/options.c index 03b24377..2f38b4ae 100644 --- a/options.c +++ b/options.c @@ -1959,7 +1959,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) @@ -2019,3 +2019,17 @@ void register_ext_option(struct ext_option *eopt) 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 index 29bb7a16..96c81a17 100644 --- a/options.h +++ b/options.h @@ -8,9 +8,11 @@ struct ext_option { struct flist_head list; + const char *prof_name; struct fio_option o; }; -void register_option(struct ext_option *); +void register_ext_option(struct ext_option *); +void prune_profile_options(const char *); #endif diff --git a/parse.c b/parse.c index 2cdac540..9c0965f0 100644 --- a/parse.c +++ b/parse.c @@ -852,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; @@ -905,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"); @@ -942,13 +957,14 @@ void option_init(struct fio_option *o) fprintf(stderr, "Option %s: string set option with" " default will always be true\n", o->name); } - if (!o->cb && !o->off1) { + 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)) { + 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); } diff --git a/parse.h b/parse.h index 95d99f56..5f602a37 100644 --- a/parse.h +++ b/parse.h @@ -59,7 +59,7 @@ typedef int (str_cb_fn)(void *, char *); 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 *, struct flist_head *, void *); -extern int show_cmd_help(struct fio_option *, const char *); +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 *); diff --git a/profile.c b/profile.c index e56ca29b..9f588a17 100644 --- a/profile.c +++ b/profile.c @@ -2,6 +2,7 @@ #include "profile.h" #include "debug.h" #include "flist.h" +#include "options.h" static FLIST_HEAD(profile_list); @@ -29,14 +30,34 @@ int load_profile(const char *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 index 6b196062..5268d4ae 100644 --- a/profile.h +++ b/profile.h @@ -12,6 +12,7 @@ struct profile_ops { int flags; const char **def_ops; + struct fio_option *options; }; void register_profile(struct profile_ops *); diff --git a/profiles/tiobench.c b/profiles/tiobench.c index d239468f..873be994 100644 --- a/profiles/tiobench.c +++ b/profiles/tiobench.c @@ -1,5 +1,11 @@ #include "../fio.h" #include "../profile.h" +#include "../parse.h" + +static unsigned long size; +static unsigned long loops; +static unsigned long bs; +static char *dir; static const char *tb_opts[] = { "buffered=0", "size=4*1024*$mb_memory", "bs=4k", "timeout=600", @@ -11,10 +17,42 @@ static const char *tb_opts[] = { "name=randread", "stonewall", "rw=randread", NULL, }; +static struct fio_option options[] = { + { + .name = "size", + .type = FIO_OPT_INT, + .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 = NULL, + }, +}; + static struct profile_ops tiobench_profile = { .name = "tiobench", .version = FIO_PROFILE_VERSION, .def_ops = tb_opts, + .options = options, }; static void fio_init tiobench_register(void)