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 <jens.axboe@oracle.com>
#include "verify.h"
#include "diskutil.h"
#include "cgroup.h"
#include "verify.h"
#include "diskutil.h"
#include "cgroup.h"
unsigned long page_mask;
unsigned long page_size;
unsigned long page_mask;
unsigned long page_size;
if (parse_options(argc, argv))
return 1;
if (parse_options(argc, argv))
return 1;
+ if (exec_profile && load_profile(exec_profile))
+ return 1;
+
if (!thread_number)
return 0;
if (!thread_number)
return 0;
#include "ioengine.h"
#include "iolog.h"
#include "helpers.h"
#include "ioengine.h"
#include "iolog.h"
#include "helpers.h"
#ifdef FIO_HAVE_GUASI
#include <guasi.h>
#ifdef FIO_HAVE_GUASI
#include <guasi.h>
extern void td_fill_rand_seeds(struct thread_data *);
extern void add_job_opts(const char **);
#define FIO_GETOPT_JOB 0x89988998
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)
FILE *f_out = NULL;
FILE *f_err = NULL;
char *job_section = NULL;
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;
int write_bw_log = 0;
int read_only = 0;
job_section = strdup(optarg);
break;
case 'p':
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;
break;
case FIO_GETOPT_JOB: {
const char *opt = l_opts[lidx].name;
if (!thread_number) {
if (dump_cmdline)
return 0;
if (!thread_number) {
if (dump_cmdline)
return 0;
+ if (exec_profile)
+ return 0;
log_err("No jobs defined(s)\n\n");
usage(argv[0]);
log_err("No jobs defined(s)\n\n");
usage(argv[0]);
#include "lib/fls.h"
#include "options.h"
#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.
*/
/*
* Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
*/
/*
* Map of job/command line options
*/
/*
* 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,
{
.name = "description",
.type = FIO_OPT_STR_STORE,
void fio_options_dup_and_init(struct option *long_options)
{
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);
unsigned int i;
options_init(options);
o++;
assert(i < FIO_NR_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);
- }
for (ret = 0, i = 0; i < num_opts; i++) {
opts[i] = fio_keyword_replace(opts[i]);
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);
int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val)
{
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)
}
void fio_fill_default_options(struct thread_data *td)
int fio_show_option_help(const char *opt)
{
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)
}
static void __options_mem(struct thread_data *td, int alloc)
-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;
- 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++;
#ifndef FIO_OPTION_H
#define FIO_OPTION_H
#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)
#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;
static void show_option_help(struct fio_option *o, FILE *out)
{
const char *typehelp[] = {
static void show_option_help(struct fio_option *o, FILE *out)
{
const char *typehelp[] = {
"string (opt=bla)",
"string with possible k/m/g postfix (opt=4k)",
"string with time postfix (opt=10s)",
"string (opt=bla)",
"string with possible k/m/g postfix (opt=4k)",
"string with time postfix (opt=10s)",
"integer value (opt=100)",
"boolean value (opt=1)",
"no argument (opt)",
"integer value (opt=100)",
"boolean value (opt=1)",
"no argument (opt)",
fprintf(out, "%20s: %s\n", "type", typehelp[o->type]);
fprintf(out, "%20s: %s\n", "default", o->def ? o->def : "no default");
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);
}
show_option_range(o, stdout);
show_option_values(o);
}
}
static struct fio_option *find_option(struct fio_option *options,
}
static struct fio_option *find_option(struct fio_option *options,
- struct flist_head *eops, const char *opt)
struct fio_option *o;
for (o = &options[0]; o->name; o++)
if (o_match(o, opt))
return o;
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;
- }
-
}
static struct fio_option *get_option(const char *opt,
}
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;
{
struct fio_option *o;
char *ret;
ret = (char *) opt;
(*post)++;
strip_blank_end(ret);
ret = (char *) opt;
(*post)++;
strip_blank_end(ret);
- o = find_option(options, eops, ret);
+ o = find_option(options, ret);
- o = find_option(options, eops, opt);
+ o = find_option(options, opt);
s1 = strdup(*((char **) p1));
s2 = strdup(*((char **) 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)
prio1 = prio2 = 0;
if (o1)
}
int parse_cmd_option(const char *opt, const char *val,
}
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)
- o = find_option(options, eops, opt);
+ o = find_option(options, opt);
if (!o) {
fprintf(stderr, "Bad option <%s>\n", opt);
return 1;
if (!o) {
fprintf(stderr, "Bad option <%s>\n", opt);
return 1;
-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;
{
struct fio_option *o;
char *post, *tmp;
- 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);
if (!o) {
fprintf(stderr, "Bad option <%s>\n", tmp);
free(tmp);
-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;
struct fio_option *o, *closest;
unsigned int best_dist;
int found = 0;
if (o->type == FIO_OPT_DEPRECATED)
continue;
if (o->type == FIO_OPT_DEPRECATED)
continue;
+ if (!exec_profile && o->prof_name)
+ continue;
if (name) {
if (!strcmp(name, o->name) ||
if (name) {
if (!strcmp(name, o->name) ||
if (show_all || match) {
found = 1;
if (match)
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);
if (show_all) {
if (!o->parent)
print_option(o);
- 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");
printf("No such command: %s", name);
if (closest) {
printf(" - showing closest match\n");
* Option types
*/
enum fio_opt_type {
* Option types
*/
enum fio_opt_type {
+ FIO_OPT_INVALID = 0,
+ FIO_OPT_STR,
FIO_OPT_STR_VAL,
FIO_OPT_STR_VAL_TIME,
FIO_OPT_STR_STORE,
FIO_OPT_STR_VAL,
FIO_OPT_STR_VAL_TIME,
FIO_OPT_STR_STORE,
const struct value_pair posval[PARSE_MAX_VP];/* possible values */
const char *parent; /* parent option */
int (*verify)(struct fio_option *, void *);
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 *);
};
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 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 *);
extern void fill_default_options(void *, struct fio_option *);
extern void option_init(struct fio_option *);
extern void options_init(struct fio_option *);
-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;
- 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++;
-void register_profile(struct profile_ops *ops)
+int register_profile(struct profile_ops *ops)
dprint(FD_PROFILE, "register profile '%s'\n", ops->name);
flist_add_tail(&ops->list, &profile_list);
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);
}
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);
-void register_profile(struct profile_ops *);
+int register_profile(struct profile_ops *);
void unregister_profile(struct profile_ops *);
int load_profile(const char *);
void unregister_profile(struct profile_ops *);
int load_profile(const char *);
static void fio_init tiobench_register(void)
{
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)
}
static void fio_exit tiobench_unregister(void)