From 9af4a24408ea7d4cea084a4fe214b81145cc36ac Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 16 Mar 2012 10:13:49 +0100 Subject: [PATCH] gfio: start of options view and edit This is pretty crap right now, but it's exposing all the options. Now we just need them to reflect the current job, and be able to update a remote job with a new set of options. Signed-off-by: Jens Axboe --- Makefile | 5 +- gfio.c | 10 +- goptions.c | 311 +++++++++++++++++++++++++++++++++++++++++++++++++++++ goptions.h | 6 ++ options.c | 129 +++++++++++++++++++--- options.h | 49 +++++++++ parse.c | 12 +-- parse.h | 21 +--- 8 files changed, 497 insertions(+), 46 deletions(-) create mode 100644 goptions.c create mode 100644 goptions.h diff --git a/Makefile b/Makefile index a114a2e8..4b87ca67 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ endif OBJS = $(SOURCE:.c=.o) FIO_OBJS = $(OBJS) fio.o -GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o +GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o goptions.o T_SMALLOC_OBJS = t/stest.o T_SMALLOC_OBJS += mutex.o smalloc.o t/log.o @@ -104,6 +104,9 @@ all: .depend $(PROGS) $(SCRIPTS) .c.o: .depend $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $< +goptions.o: goptions.c goptions.h + $(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c goptions.c + ghelpers.o: ghelpers.c ghelpers.h $(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c ghelpers.c diff --git a/gfio.c b/gfio.c index 56a38874..675a8775 100644 --- a/gfio.c +++ b/gfio.c @@ -32,6 +32,7 @@ #include "fio.h" #include "gfio.h" #include "ghelpers.h" +#include "goptions.h" #include "graph.h" static int gfio_server_running; @@ -291,21 +292,21 @@ static void update_button_states(struct gui *ui, struct gui_entry *ge) case GE_STATE_NEW: connect_state = 1; - edit_state = 0; + edit_state = 1; connect_str = "Connect"; send_state = 0; start_state = 0; break; case GE_STATE_CONNECTED: connect_state = 1; - edit_state = 0; + edit_state = 1; connect_str = "Disconnect"; send_state = 1; start_state = 0; break; case GE_STATE_JOB_SENT: connect_state = 1; - edit_state = 0; + edit_state = 1; connect_str = "Disconnect"; send_state = 0; start_state = 1; @@ -2507,6 +2508,9 @@ static void send_job_entry(GtkWidget *w, gpointer data) static void edit_job_entry(GtkWidget *w, gpointer data) { + struct gui *ui = (struct gui *) data; + + gopt_get_options_window(ui->window); } static void start_job_entry(GtkWidget *w, gpointer data) diff --git a/goptions.c b/goptions.c new file mode 100644 index 00000000..36477f08 --- /dev/null +++ b/goptions.c @@ -0,0 +1,311 @@ +#include +#include +#include + +#include +#include +#include + +#include "fio.h" +#include "gfio.h" +#include "ghelpers.h" +#include "parse.h" + +struct gopt { + GtkWidget *box; + unsigned int opt_index; + unsigned int opt_type; +}; + +struct gopt_combo { + struct gopt gopt; + GtkWidget *combo; +}; + +struct gopt_int { + struct gopt gopt; + GtkWidget *spin; +}; + +struct gopt_bool { + struct gopt gopt; + GtkWidget *check; +}; + +struct gopt_str { + struct gopt gopt; + GtkWidget *entry; +}; + +struct gopt_range { + struct gopt gopt; + GtkWidget *spins[4]; +}; + +static struct gopt *gopt_new_str_store(struct fio_option *o) +{ + struct gopt_str *s; + GtkWidget *label; + + s = malloc(sizeof(*s)); + + s->gopt.box = gtk_hbox_new(FALSE, 3); + label = gtk_label_new(o->name); + gtk_box_pack_start(GTK_BOX(s->gopt.box), label, FALSE, FALSE, 0); + + s->entry = gtk_entry_new(); + gtk_entry_set_editable(GTK_ENTRY(s->entry), 1); + + if (o->def) + gtk_entry_set_text(GTK_ENTRY(s->entry), o->def); + + gtk_box_pack_start(GTK_BOX(s->gopt.box), s->entry, FALSE, FALSE, 0); + return &s->gopt; +} + +static struct gopt *gopt_new_combo(struct fio_option *o) +{ + struct gopt_combo *combo; + struct value_pair *vp; + GtkWidget *label; + int i, active = 0; + + combo = malloc(sizeof(*combo)); + + combo->gopt.box = gtk_hbox_new(FALSE, 3); + label = gtk_label_new(o->name); + gtk_box_pack_start(GTK_BOX(combo->gopt.box), label, FALSE, FALSE, 0); + + combo->combo = gtk_combo_box_new_text(); + gtk_box_pack_start(GTK_BOX(combo->gopt.box), combo->combo, FALSE, FALSE, 0); + + i = 0; + vp = &o->posval[0]; + while (vp->ival) { + gtk_combo_box_append_text(GTK_COMBO_BOX(combo->combo), vp->ival); + if (o->def && !strcmp(vp->ival, o->def)) + active = i; + vp++; + i++; + } + + gtk_combo_box_set_active(GTK_COMBO_BOX(combo->combo), active); + return &combo->gopt; +} + +static struct gopt *gopt_new_int(struct fio_option *o) +{ + struct gopt_int *i; + gint maxval, defval; + GtkWidget *label; + + i = malloc(sizeof(*i)); + i->gopt.box = gtk_hbox_new(FALSE, 3); + label = gtk_label_new(o->name); + gtk_box_pack_start(GTK_BOX(i->gopt.box), label, FALSE, FALSE, 0); + + maxval = o->maxval; + if (!maxval) + maxval = INT_MAX; + + defval = 0; + if (o->def) { + long long val; + + check_str_bytes(o->def, &val, NULL); + defval = val; + } + + i->spin = gtk_spin_button_new_with_range(o->minval, maxval, 1.0); + gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(i->spin), GTK_UPDATE_IF_VALID); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(i->spin), defval); + + gtk_box_pack_start(GTK_BOX(i->gopt.box), i->spin, FALSE, FALSE, 0); + return &i->gopt; +} + +static struct gopt *gopt_new_bool(struct fio_option *o) +{ + struct gopt_bool *b; + GtkWidget *label; + int defstate = 0; + + b = malloc(sizeof(*b)); + b->gopt.box = gtk_hbox_new(FALSE, 3); + label = gtk_label_new(o->name); + gtk_box_pack_start(GTK_BOX(b->gopt.box), label, FALSE, FALSE, 0); + + b->check = gtk_check_button_new(); + if (o->def && !strcmp(o->def, "1")) + defstate = 1; + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b->check), defstate); + + gtk_box_pack_start(GTK_BOX(b->gopt.box), b->check, FALSE, FALSE, 0); + return &b->gopt; +} + +static struct gopt *gopt_new_int_range(struct fio_option *o) +{ + struct gopt_range *r; + gint maxval, defval; + GtkWidget *label; + int i; + + r = malloc(sizeof(*r)); + r->gopt.box = gtk_hbox_new(FALSE, 3); + label = gtk_label_new(o->name); + gtk_box_pack_start(GTK_BOX(r->gopt.box), label, FALSE, FALSE, 0); + + maxval = o->maxval; + if (!maxval) + maxval = INT_MAX; + + defval = 0; + if (o->def) { + long long val; + + check_str_bytes(o->def, &val, NULL); + defval = val; + } + + for (i = 0; i < 4; i++) { + r->spins[i] = gtk_spin_button_new_with_range(o->minval, maxval, 1.0); + gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(r->spins[i]), GTK_UPDATE_IF_VALID); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(r->spins[i]), defval); + + gtk_box_pack_start(GTK_BOX(r->gopt.box), r->spins[i], FALSE, FALSE, 0); + } + + return &r->gopt; +} + +static void gopt_add_option(GtkWidget *hbox, struct fio_option *o, + unsigned int opt_index) +{ + struct gopt *go = NULL; + + switch (o->type) { + case FIO_OPT_STR_STORE: + go = gopt_new_str_store(o); + break; + case FIO_OPT_STR_VAL: + case FIO_OPT_STR_VAL_TIME: + case FIO_OPT_INT: + go = gopt_new_int(o); + break; + case FIO_OPT_STR_SET: + case FIO_OPT_BOOL: + go = gopt_new_bool(o); + break; + case FIO_OPT_STR: + if (!o->posval[0].ival) { + go = gopt_new_str_store(o); + break; + } + case FIO_OPT_STR_MULTI: + go = gopt_new_combo(o); + break; + case FIO_OPT_RANGE: + go = gopt_new_int_range(o); + break; + /* still need to handle this one */ + case FIO_OPT_FLOAT_LIST: + break; + case FIO_OPT_DEPRECATED: + break; + default: + printf("ignore type %u\n", o->type); + break; + } + + if (go) { + if (o->help) + gtk_widget_set_tooltip_text(go->box, o->help); + + gtk_box_pack_start(GTK_BOX(hbox), go->box, FALSE, FALSE, 5); + go->opt_index = opt_index; + go->opt_type = o->type; + } +} + +static void gopt_add_options(GtkWidget **vboxes) +{ + GtkWidget *hbox = NULL; + int i; + + for (i = 0; fio_options[i].name; i++) { + struct fio_option *o = &fio_options[i]; + unsigned int mask = o->category; + struct opt_group *og; + + while ((og = opt_group_from_mask(&mask)) != NULL) { + GtkWidget *vbox = vboxes[ffz(~og->mask)]; + + hbox = gtk_hbox_new(FALSE, 3); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); + gopt_add_option(hbox, &fio_options[i], i); + } + } +} + +static GtkWidget *gopt_add_group_tab(GtkWidget *notebook, struct opt_group *og) +{ + GtkWidget *box, *vbox, *scroll; + + scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_container_set_border_width(GTK_CONTAINER(scroll), 5); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + vbox = gtk_vbox_new(FALSE, 3); + box = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 5); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), vbox); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, gtk_label_new(og->name)); + + return vbox; +} + +static void gopt_add_group_tabs(GtkWidget *notebook, GtkWidget **vbox) +{ + struct opt_group *og; + unsigned int i = 0; + + do { + unsigned int mask = (1U << i); + + og = opt_group_from_mask(&mask); + if (!og) + break; + vbox[i] = gopt_add_group_tab(notebook, og); + i++; + } while (1); +} + +void gopt_get_options_window(GtkWidget *window) +{ + GtkWidget *dialog, *notebook; + GtkWidget *vboxes[__FIO_OPT_G_NR]; + + dialog = gtk_dialog_new_with_buttons("Fio options", + GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); + + gtk_widget_set_size_request(GTK_WIDGET(dialog), 1024, 768); + + notebook = gtk_notebook_new(); + gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), 1); + gtk_notebook_popup_enable(GTK_NOTEBOOK(notebook)); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), notebook, TRUE, TRUE, 5); + + gopt_add_group_tabs(notebook, vboxes); + + gopt_add_options(vboxes); + + gtk_widget_show_all(dialog); + + gtk_dialog_run(GTK_DIALOG(dialog)); + + gtk_widget_destroy(dialog); +} diff --git a/goptions.h b/goptions.h new file mode 100644 index 00000000..14e54f78 --- /dev/null +++ b/goptions.h @@ -0,0 +1,6 @@ +#ifndef GFIO_OPTIONS_H +#define GFIO_OPTIONS_H + +void gopt_get_options_window(GtkWidget *window); + +#endif diff --git a/options.c b/options.c index 714741a0..91bec0e8 100644 --- a/options.c +++ b/options.c @@ -842,10 +842,107 @@ static int kb_base_verify(struct fio_option *o, void *data) return 0; } +/* + * Option grouping + */ +static struct opt_group fio_opt_groups[] = { + { + .name = "Description", + .mask = FIO_OPT_G_DESC, + }, + { + .name = "File", + .mask = FIO_OPT_G_FILE, + }, + { + .name = "Misc", + .mask = FIO_OPT_G_MISC, + }, + { + .name = "IO (main)", + .mask = FIO_OPT_G_IO, + }, + { + .name = "IO direction", + .mask = FIO_OPT_G_IO_DDIR, + }, + { + .name = "IO buffer", + .mask = FIO_OPT_G_IO_BUF, + }, + { + .name = "Random", + .mask = FIO_OPT_G_RAND, + }, + { + .name = "OS", + .mask = FIO_OPT_G_OS, + }, + { + .name = "Memory", + .mask = FIO_OPT_G_MEM, + }, + { + .name = "Verify", + .mask = FIO_OPT_G_VERIFY, + }, + { + .name = "CPU", + .mask = FIO_OPT_G_CPU, + }, + { + .name = "Log", + .mask = FIO_OPT_G_LOG, + }, + { + .name = "Zone", + .mask = FIO_OPT_G_ZONE, + }, + { + .name = "Cache", + .mask = FIO_OPT_G_CACHE, + }, + { + .name = "Stat", + .mask = FIO_OPT_G_STAT, + }, + { + .name = "Error", + .mask = FIO_OPT_G_ERR, + }, + { + .name = "Job", + .mask = FIO_OPT_G_JOB, + }, + { + .name = NULL, + }, +}; + +struct opt_group *opt_group_from_mask(unsigned int *mask) +{ + struct opt_group *og; + int i; + + if (*mask == FIO_OPT_G_INVALID) + return NULL; + + for (i = 0; fio_opt_groups[i].name; i++) { + og = &fio_opt_groups[i]; + + if (*mask & og->mask) { + *mask &= ~(og->mask); + return og; + } + } + + return NULL; +} + /* * Map of job/command line options */ -static struct fio_option options[FIO_MAX_OPTS] = { +struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "description", .type = FIO_OPT_STR_STORE, @@ -2413,13 +2510,13 @@ void fio_options_dup_and_init(struct option *long_options) { unsigned int i; - options_init(options); + options_init(fio_options); i = 0; while (long_options[i].name) i++; - options_to_lopts(options, long_options, i, FIO_GETOPT_JOB); + options_to_lopts(fio_options, long_options, i, FIO_GETOPT_JOB); } struct fio_keyword { @@ -2642,13 +2739,13 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts) int i, ret, unknown; char **opts_copy; - sort_options(opts, options, num_opts); + sort_options(opts, fio_options, num_opts); opts_copy = dup_and_sub_options(opts, num_opts); for (ret = 0, i = 0, unknown = 0; i < num_opts; i++) { struct fio_option *o; - int newret = parse_option(opts_copy[i], opts[i], options, &o, - td); + int newret = parse_option(opts_copy[i], opts[i], fio_options, + &o, td); if (opts_copy[i]) { if (newret && !o) { @@ -2694,7 +2791,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, fio_options, td); } int fio_cmd_ioengine_option_parse(struct thread_data *td, const char *opt, @@ -2705,12 +2802,12 @@ int fio_cmd_ioengine_option_parse(struct thread_data *td, const char *opt, void fio_fill_default_options(struct thread_data *td) { - fill_default_options(td, options); + fill_default_options(td, fio_options); } int fio_show_option_help(const char *opt) { - return show_cmd_help(options, opt); + return show_cmd_help(fio_options, opt); } void options_mem_dupe(void *data, struct fio_option *options) @@ -2733,7 +2830,7 @@ void options_mem_dupe(void *data, struct fio_option *options) */ void fio_options_mem_dupe(struct thread_data *td) { - options_mem_dupe(&td->o, options); + options_mem_dupe(&td->o, fio_options); if (td->eo && td->io_ops) { void *oldeo = td->eo; @@ -2762,13 +2859,13 @@ int add_option(struct fio_option *o) struct fio_option *__o; int opt_index = 0; - __o = options; + __o = fio_options; while (__o->name) { opt_index++; __o++; } - memcpy(&options[opt_index], o, sizeof(*o)); + memcpy(&fio_options[opt_index], o, sizeof(*o)); return 0; } @@ -2776,7 +2873,7 @@ void invalidate_profile_options(const char *prof_name) { struct fio_option *o; - o = options; + o = fio_options; while (o->name) { if (o->prof_name && !strcmp(o->prof_name, prof_name)) { o->type = FIO_OPT_INVALID; @@ -2791,7 +2888,7 @@ void add_opt_posval(const char *optname, const char *ival, const char *help) struct fio_option *o; unsigned int i; - o = find_option(options, optname); + o = find_option(fio_options, optname); if (!o) return; @@ -2810,7 +2907,7 @@ void del_opt_posval(const char *optname, const char *ival) struct fio_option *o; unsigned int i; - o = find_option(options, optname); + o = find_option(fio_options, optname); if (!o) return; @@ -2827,7 +2924,7 @@ void del_opt_posval(const char *optname, const char *ival) void fio_options_free(struct thread_data *td) { - options_free(options, td); + options_free(fio_options, td); if (td->eo && td->io_ops && td->io_ops->options) { options_free(td->io_ops->options, td->eo); free(td->eo); diff --git a/options.h b/options.h index ed6b9c2d..0b93c05a 100644 --- a/options.h +++ b/options.h @@ -18,6 +18,8 @@ void del_opt_posval(const char *, const char *); struct thread_data; void fio_options_free(struct thread_data *); +extern struct fio_option fio_options[FIO_MAX_OPTS]; + static inline int o_match(struct fio_option *o, const char *opt) { if (!strcmp(o->name, opt)) @@ -40,4 +42,51 @@ static inline struct fio_option *find_option(struct fio_option *options, return NULL; } +struct opt_group { + const char *name; + unsigned int mask; +}; + +enum opt_category { + __FIO_OPT_G_DESC = 0, + __FIO_OPT_G_FILE = 1, + __FIO_OPT_G_MISC = 2, + __FIO_OPT_G_IO = 3, + __FIO_OPT_G_IO_DDIR = 4, + __FIO_OPT_G_IO_BUF = 5, + __FIO_OPT_G_RAND = 6, + __FIO_OPT_G_OS = 7, + __FIO_OPT_G_MEM = 8, + __FIO_OPT_G_VERIFY = 9, + __FIO_OPT_G_CPU = 10, + __FIO_OPT_G_LOG = 11, + __FIO_OPT_G_ZONE = 12, + __FIO_OPT_G_CACHE = 13, + __FIO_OPT_G_STAT = 14, + __FIO_OPT_G_ERR = 15, + __FIO_OPT_G_JOB = 16, + __FIO_OPT_G_NR = 17, + + FIO_OPT_G_DESC = (1U << __FIO_OPT_G_DESC), + FIO_OPT_G_FILE = (1U << __FIO_OPT_G_FILE), + FIO_OPT_G_MISC = (1U << __FIO_OPT_G_MISC), + FIO_OPT_G_IO = (1U << __FIO_OPT_G_IO), + FIO_OPT_G_IO_DDIR = (1U << __FIO_OPT_G_IO_DDIR), + FIO_OPT_G_IO_BUF = (1U << __FIO_OPT_G_IO_BUF), + FIO_OPT_G_RAND = (1U << __FIO_OPT_G_RAND), + FIO_OPT_G_OS = (1U << __FIO_OPT_G_OS), + FIO_OPT_G_MEM = (1U << __FIO_OPT_G_MEM), + FIO_OPT_G_VERIFY = (1U << __FIO_OPT_G_VERIFY), + FIO_OPT_G_CPU = (1U << __FIO_OPT_G_CPU), + FIO_OPT_G_LOG = (1U << __FIO_OPT_G_LOG), + FIO_OPT_G_ZONE = (1U << __FIO_OPT_G_ZONE), + FIO_OPT_G_CACHE = (1U << __FIO_OPT_G_CACHE), + FIO_OPT_G_STAT = (1U << __FIO_OPT_G_STAT), + FIO_OPT_G_ERR = (1U << __FIO_OPT_G_ERR), + FIO_OPT_G_JOB = (1U << __FIO_OPT_G_JOB), + FIO_OPT_G_INVALID = (1U << __FIO_OPT_G_NR), +}; + +extern struct opt_group *opt_group_from_mask(unsigned int *mask); + #endif diff --git a/parse.c b/parse.c index cdd9ac7e..9891974d 100644 --- a/parse.c +++ b/parse.c @@ -15,7 +15,7 @@ #include "debug.h" #include "options.h" -static struct fio_option *fio_options; +static struct fio_option *__fio_options; extern unsigned int fio_get_kb_base(void *); static int vp_cmp(const void *p1, const void *p2) @@ -260,7 +260,7 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data) return 0; } -static int check_str_bytes(const char *p, long long *val, void *data) +int check_str_bytes(const char *p, long long *val, void *data) { return str_to_decimal(p, val, 1, data); } @@ -770,14 +770,14 @@ static int opt_cmp(const void *p1, const void *p2) if (*(char **)p1) { s = strdup(*((char **) p1)); - o = get_option(s, fio_options, &foo); + o = get_option(s, __fio_options, &foo); if (o) prio1 = o->prio; free(s); } if (*(char **)p2) { s = strdup(*((char **) p2)); - o = get_option(s, fio_options, &foo); + o = get_option(s, __fio_options, &foo); if (o) prio2 = o->prio; free(s); @@ -788,9 +788,9 @@ static int opt_cmp(const void *p1, const void *p2) void sort_options(char **opts, struct fio_option *options, int num_opts) { - fio_options = options; + __fio_options = options; qsort(opts, num_opts, sizeof(char *), opt_cmp); - fio_options = NULL; + __fio_options = NULL; } int parse_cmd_option(const char *opt, const char *val, diff --git a/parse.h b/parse.h index 68a7338e..b3d86138 100644 --- a/parse.h +++ b/parse.h @@ -35,26 +35,6 @@ struct value_pair { #define OPT_LEN_MAX 4096 #define PARSE_MAX_VP 16 -enum opt_category { - FIO_OPT_G_DESC = 1UL << 0, - FIO_OPT_G_FILE = 1UL << 1, - FIO_OPT_G_MISC = 1UL << 2, - FIO_OPT_G_IO = 1UL << 3, - FIO_OPT_G_IO_DDIR = 1UL << 4, - FIO_OPT_G_IO_BUF = 1UL << 5, - FIO_OPT_G_RAND = 1UL << 6, - FIO_OPT_G_OS = 1UL << 7, - FIO_OPT_G_MEM = 1UL << 8, - FIO_OPT_G_VERIFY = 1UL << 9, - FIO_OPT_G_CPU = 1UL << 10, - FIO_OPT_G_LOG = 1UL << 11, - FIO_OPT_G_ZONE = 1UL << 12, - FIO_OPT_G_CACHE = 1UL << 13, - FIO_OPT_G_STAT = 1UL << 14, - FIO_OPT_G_ERR = 1UL << 15, - FIO_OPT_G_JOB = 1UL << 16, -}; - /* * Option define */ @@ -98,6 +78,7 @@ extern void options_free(struct fio_option *, void *); extern void strip_blank_front(char **); extern void strip_blank_end(char *); extern int str_to_decimal(const char *, long long *, int, void *); +extern int check_str_bytes(const char *p, long long *val, void *data); /* * Handlers for the options -- 2.25.1