1cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe/*
2cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe * This file contains the ini and command liner parser main.
3cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe */
4cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include <stdio.h>
5cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include <stdlib.h>
6cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include <unistd.h>
7cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include <ctype.h>
8cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include <string.h>
9cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include <errno.h>
10cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include <limits.h>
1188b5a391bc2f9eb85066219e453682a746730eadAaron Carroll#include <stdlib.h>
12833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong#include <math.h>
13ab9461eaea21e861cc777aae2420db8f486ed1e2Bruce Cran#include <float.h>
14cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
15cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe#include "parse.h"
16a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe#include "debug.h"
179f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe#include "options.h"
18e25839d4cb5fefcb5ffce76128a4faedb177e7afJens Axboe#include "minmax.h"
19fd112d34a2cfdc2d9efcd394e38b6d87b357c23dVincent Kang Fu#include "lib/ieee754.h"
20cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
2188b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#ifdef CONFIG_ARITHMETIC
2288b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#include "y.tab.h"
2388b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#endif
2488b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron
259af4a24408ea7d4cea084a4fe214b81145cc36acJens Axboestatic struct fio_option *__fio_options;
263b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
27f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboestatic int vp_cmp(const void *p1, const void *p2)
28f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe{
29f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	const struct value_pair *vp1 = p1;
30f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	const struct value_pair *vp2 = p2;
31f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
32f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	return strlen(vp2->ival) - strlen(vp1->ival);
33f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe}
34f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
35ce952ab65a46f728ffada9613bb50ace7aeaa7c8Jens Axboestatic void posval_sort(struct fio_option *o, struct value_pair *vpmap)
36f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe{
37f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	const struct value_pair *vp;
38f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	int entries;
39f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
40f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	memset(vpmap, 0, PARSE_MAX_VP * sizeof(struct value_pair));
41f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
42f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	for (entries = 0; entries < PARSE_MAX_VP; entries++) {
43f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe		vp = &o->posval[entries];
44f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe		if (!vp->ival || vp->ival[0] == '\0')
45f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe			break;
46f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
47f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe		memcpy(&vpmap[entries], vp, sizeof(*vp));
48f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	}
49f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
50f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe	qsort(vpmap, entries, sizeof(struct value_pair), vp_cmp);
51f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe}
52f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
5306b0be6efb3da5131bc8386251d017f0abafbdacJens Axboestatic void show_option_range(struct fio_option *o,
5406b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe				int (*logger)(const char *format, ...))
55b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe{
563c037bcf2334ca75b23103a954232a48e4ce6dc4Jens Axboe	if (o->type == FIO_OPT_FLOAT_LIST) {
57ab9461eaea21e861cc777aae2420db8f486ed1e2Bruce Cran		if (o->minfp == DBL_MIN && o->maxfp == DBL_MAX)
58833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			return;
59833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong
6006b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger("%20s: min=%f", "range", o->minfp);
61ab9461eaea21e861cc777aae2420db8f486ed1e2Bruce Cran		if (o->maxfp != DBL_MAX)
6206b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe			logger(", max=%f", o->maxfp);
6306b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger("\n");
643c037bcf2334ca75b23103a954232a48e4ce6dc4Jens Axboe	} else if (!o->posval[0].ival) {
65833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		if (!o->minval && !o->maxval)
66833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			return;
67b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
6806b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger("%20s: min=%d", "range", o->minval);
69833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		if (o->maxval)
7006b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe			logger(", max=%d", o->maxval);
7106b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger("\n");
72833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong	}
73b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe}
74b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
75b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboestatic void show_option_values(struct fio_option *o)
76b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe{
77a3073f4a296bba2cbd026603fe284341c370bfb0Jens Axboe	int i;
78b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
79a3073f4a296bba2cbd026603fe284341c370bfb0Jens Axboe	for (i = 0; i < PARSE_MAX_VP; i++) {
807837213b66e20a8d91e7069f5823852f42c41440Jens Axboe		const struct value_pair *vp = &o->posval[i];
81b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
827837213b66e20a8d91e7069f5823852f42c41440Jens Axboe		if (!vp->ival)
83a3073f4a296bba2cbd026603fe284341c370bfb0Jens Axboe			continue;
84b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
8506b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_info("%20s: %-10s", i == 0 ? "valid values" : "", vp->ival);
867837213b66e20a8d91e7069f5823852f42c41440Jens Axboe		if (vp->help)
8706b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe			log_info(" %s", vp->help);
8806b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_info("\n");
89a3073f4a296bba2cbd026603fe284341c370bfb0Jens Axboe	}
90b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
91b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe	if (i)
9206b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_info("\n");
93b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe}
94b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
9506b0be6efb3da5131bc8386251d017f0abafbdacJens Axboestatic void show_option_help(struct fio_option *o, int is_err)
96d447a8c25a735519089626b3047da646597a7c6fJens Axboe{
97d447a8c25a735519089626b3047da646597a7c6fJens Axboe	const char *typehelp[] = {
9807b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe		"invalid",
99d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"string (opt=bla)",
100ae3fb6fbaf7dd68291f5de8e8aaac0d28e24c9eeJens Axboe		"string (opt=bla)",
101d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"string with possible k/m/g postfix (opt=4k)",
102d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"string with time postfix (opt=10s)",
103d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"string (opt=bla)",
104d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"string with dual range (opt=1k-4k,4k-8k)",
105d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"integer value (opt=100)",
106d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"boolean value (opt=1)",
107833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		"list of floating point values separated by ':' (opt=5.9:7.8)",
108d447a8c25a735519089626b3047da646597a7c6fJens Axboe		"no argument (opt)",
10907b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe		"deprecated",
110d447a8c25a735519089626b3047da646597a7c6fJens Axboe	};
11106b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe	int (*logger)(const char *format, ...);
11206b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe
11306b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe	if (is_err)
11406b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger = log_err;
11506b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe	else
11606b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger = log_info;
117d447a8c25a735519089626b3047da646597a7c6fJens Axboe
118d447a8c25a735519089626b3047da646597a7c6fJens Axboe	if (o->alias)
11906b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger("%20s: %s\n", "alias", o->alias);
120d447a8c25a735519089626b3047da646597a7c6fJens Axboe
12106b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe	logger("%20s: %s\n", "type", typehelp[o->type]);
12206b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe	logger("%20s: %s\n", "default", o->def ? o->def : "no default");
12307b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe	if (o->prof_name)
12406b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		logger("%20s: only for profile '%s'\n", "valid", o->prof_name);
12506b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe	show_option_range(o, logger);
126d447a8c25a735519089626b3047da646597a7c6fJens Axboe	show_option_values(o);
127d447a8c25a735519089626b3047da646597a7c6fJens Axboe}
128d447a8c25a735519089626b3047da646597a7c6fJens Axboe
1290de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboestatic unsigned long long get_mult_time(const char *str, int len,
1300de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe					int is_seconds)
131cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
13274454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	const char *p = str;
13374454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	char *c;
134e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe	unsigned long long mult = 1;
13574454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt
13674454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	/*
13774454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt         * Go forward until we hit a non-digit, or +/- sign
13874454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt         */
13974454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	while ((p - str) <= len) {
14074454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt		if (!isdigit((int) *p) && (*p != '+') && (*p != '-'))
14174454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt			break;
14274454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt		p++;
143cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe	}
14474454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt
1450de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe	if (!isalpha((int) *p)) {
1460de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe		if (is_seconds)
1470de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe			return 1000000UL;
1480de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe		else
1490de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe			return 1;
1500de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe	}
15174454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt
15274454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	c = strdup(p);
15374454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	for (int i = 0; i < strlen(c); i++)
15474454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt		c[i] = tolower(c[i]);
15574454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt
156e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe	if (!strncmp("us", c, 2) || !strncmp("usec", c, 4))
15774454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt		mult = 1;
158e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe	else if (!strncmp("ms", c, 2) || !strncmp("msec", c, 4))
15974454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt		mult = 1000;
160e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe	else if (!strcmp("s", c))
161e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe		mult = 1000000;
16274454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	else if (!strcmp("m", c))
163e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe		mult = 60 * 1000000UL;
16474454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	else if (!strcmp("h", c))
165e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe		mult = 60 * 60 * 1000000UL;
16674454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	else if (!strcmp("d", c))
167e4668264df255e8d01680920a4e78fd4186aeff1Jens Axboe		mult = 24 * 60 * 60 * 1000000UL;
16874454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt
16974454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	free(c);
17074454ce40f1a5e1e682da0a8acb824a7f6910270Christian Ehrhardt	return mult;
171cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
172cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
173a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboestatic int is_separator(char c)
174a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe{
175a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	switch (c) {
176a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	case ':':
177a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	case '-':
178a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	case ',':
179a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	case '/':
180a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe		return 1;
181a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	default:
182a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe		return 0;
183a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	}
184a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe}
185a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe
1867bb591020669b7266c57108f2a68b48a03ae72eeJens Axboestatic unsigned long long __get_mult_bytes(const char *p, void *data,
1877bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe					   int *percent)
188cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
189d6978a3242daad9cb7b0710b724f19225d1ed7e2Jens Axboe	unsigned int kb_base = fio_get_kb_base(data);
190a639f0bbd278365a2fa15031afd29a24dc917437Jens Axboe	unsigned long long ret = 1;
19157fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe	unsigned int i, pow = 0, mult = kb_base;
19257fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe	char *c;
193a639f0bbd278365a2fa15031afd29a24dc917437Jens Axboe
19457fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe	if (!p)
19557fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		return 1;
196a639f0bbd278365a2fa15031afd29a24dc917437Jens Axboe
19757fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe	c = strdup(p);
19857fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe
199a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	for (i = 0; i < strlen(c); i++) {
20057fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		c[i] = tolower(c[i]);
201a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe		if (is_separator(c[i])) {
202a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe			c[i] = '\0';
203a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe			break;
204a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe		}
205a03fb65f4e5d657ee3bb68309cfa70ae2d5bc44bJens Axboe	}
20657fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe
207a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	if (!strncmp("pib", c, 3)) {
20857fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 5;
20957fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		mult = 1000;
210a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	} else if (!strncmp("tib", c, 3)) {
21157fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 4;
21257fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		mult = 1000;
213a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	} else if (!strncmp("gib", c, 3)) {
21457fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 3;
21557fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		mult = 1000;
216a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	} else if (!strncmp("mib", c, 3)) {
21757fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 2;
21857fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		mult = 1000;
219a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	} else if (!strncmp("kib", c, 3)) {
22057fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 1;
22157fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		mult = 1000;
222a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	} else if (!strncmp("p", c, 1) || !strncmp("pb", c, 2))
22357fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 5;
224a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	else if (!strncmp("t", c, 1) || !strncmp("tb", c, 2))
22557fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 4;
226a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	else if (!strncmp("g", c, 1) || !strncmp("gb", c, 2))
22757fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 3;
228a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	else if (!strncmp("m", c, 1) || !strncmp("mb", c, 2))
22957fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 2;
230a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	else if (!strncmp("k", c, 1) || !strncmp("kb", c, 2))
23157fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		pow = 1;
232a04f158df11fce840dbd7b5e426245929e6276a3Jens Axboe	else if (!strncmp("%", c, 1)) {
2337bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe		*percent = 1;
234e721c57fc77e0155bb73a2c266dba0c6ce0bd3b5Jens Axboe		free(c);
2357bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe		return ret;
2367bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe	}
23757fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe
23857fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe	while (pow--)
23957fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		ret *= (unsigned long long) mult;
24057fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe
24157fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe	free(c);
242a639f0bbd278365a2fa15031afd29a24dc917437Jens Axboe	return ret;
243cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
244cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
2457bb591020669b7266c57108f2a68b48a03ae72eeJens Axboestatic unsigned long long get_mult_bytes(const char *str, int len, void *data,
2466925dd356191bc40e8a1ebc8fd92a40b476658c3Jens Axboe					 int *percent)
24757fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe{
24855ed9636e82b8dee419b5a76c07098bff4d980b6Jens Axboe	const char *p = str;
249ba4ddd690a04f39abada885f1b4ea3b228e790a8Jens Axboe	int digit_seen = 0;
25057fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe
2511d1c187b36fd4ee28d72d04660b37a7c3edd64e6Jens Axboe	if (len < 2)
2527bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe		return __get_mult_bytes(str, data, percent);
2531d1c187b36fd4ee28d72d04660b37a7c3edd64e6Jens Axboe
254d0c814ececb7410e97d1a437e80fc2dfd5c6de38Steven Lang	/*
255d0c814ececb7410e97d1a437e80fc2dfd5c6de38Steven Lang	 * Go forward until we hit a non-digit, or +/- sign
256d0c814ececb7410e97d1a437e80fc2dfd5c6de38Steven Lang	 */
25755ed9636e82b8dee419b5a76c07098bff4d980b6Jens Axboe	while ((p - str) <= len) {
258ba4ddd690a04f39abada885f1b4ea3b228e790a8Jens Axboe		if (!isdigit((int) *p) &&
259ba4ddd690a04f39abada885f1b4ea3b228e790a8Jens Axboe		    (((*p != '+') && (*p != '-')) || digit_seen))
26055ed9636e82b8dee419b5a76c07098bff4d980b6Jens Axboe			break;
2613c703d13b1323869de7e51b9c5c7feb9d9c8211dJens Axboe		digit_seen |= isdigit((int) *p);
26255ed9636e82b8dee419b5a76c07098bff4d980b6Jens Axboe		p++;
26355ed9636e82b8dee419b5a76c07098bff4d980b6Jens Axboe	}
26455ed9636e82b8dee419b5a76c07098bff4d980b6Jens Axboe
2657bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe	if (!isalpha((int) *p) && (*p != '%'))
26657fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		p = NULL;
26757fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe
2687bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe	return __get_mult_bytes(p, data, percent);
26957fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe}
27057fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe
27188b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameronextern int evaluate_arithmetic_expression(const char *buffer, long long *ival,
27279dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron					  double *dval, double implied_units,
27379dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron					  int is_time);
27488b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron
275cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe/*
276833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong * Convert string into a floating number. Return 1 for success and 0 otherwise.
277833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong */
27879dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameronint str_to_float(const char *str, double *val, int is_time)
279833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong{
28088b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#ifdef CONFIG_ARITHMETIC
28188b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	int rc;
28288b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	long long ival;
28388b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	double dval;
28488b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron
28588b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	if (str[0] == '(') {
28679dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron		rc = evaluate_arithmetic_expression(str, &ival, &dval, 1.0, is_time);
28788b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron		if (!rc) {
28888b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron			*val = dval;
28988b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron			return 1;
29088b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron		}
29188b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	}
29288b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#endif
29388b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	return 1 == sscanf(str, "%lf", val);
294833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong}
295833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong
296833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong/*
297e1f365035a952233463d85d659bd960ba78f012eJens Axboe * convert string into decimal value, noting any size suffix
298cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe */
2990de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboeint str_to_decimal(const char *str, long long *val, int kilo, void *data,
30079dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron		   int is_seconds, int is_time)
301cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
302b347f9daece7d65a6e596cd3bd0ef3602e40b059Jens Axboe	int len, base;
30388b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	int rc = 1;
30488b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#ifdef CONFIG_ARITHMETIC
30588b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	long long ival;
30688b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	double dval;
30764c9d60b95a121b4d7a4ca3b0fdf2390236d17b2Stephen M. Cameron	double implied_units = 1.0;
30888b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#endif
309cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
310cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe	len = strlen(str);
311f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe	if (!len)
312f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe		return 1;
313cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
31488b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#ifdef CONFIG_ARITHMETIC
31564c9d60b95a121b4d7a4ca3b0fdf2390236d17b2Stephen M. Cameron	if (is_seconds)
31664c9d60b95a121b4d7a4ca3b0fdf2390236d17b2Stephen M. Cameron		implied_units = 1000000.0;
31788b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	if (str[0] == '(')
31879dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron		rc = evaluate_arithmetic_expression(str, &ival, &dval, implied_units, is_time);
319c3805eb1451972285565504e11be642f082fe7dfStephen M. Cameron	if (str[0] == '(' && !rc) {
320c3805eb1451972285565504e11be642f082fe7dfStephen M. Cameron		if (!kilo && is_seconds)
321c3805eb1451972285565504e11be642f082fe7dfStephen M. Cameron			*val = ival / 1000000LL;
322c3805eb1451972285565504e11be642f082fe7dfStephen M. Cameron		else
323c3805eb1451972285565504e11be642f082fe7dfStephen M. Cameron			*val = ival;
324c3805eb1451972285565504e11be642f082fe7dfStephen M. Cameron	}
32588b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron#endif
326b347f9daece7d65a6e596cd3bd0ef3602e40b059Jens Axboe
32788b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	if (rc == 1) {
32888b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron		if (strstr(str, "0x") || strstr(str, "0X"))
32988b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron			base = 16;
33088b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron		else
33188b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron			base = 10;
33288b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron
33388b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron		*val = strtoll(str, NULL, base);
33488b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron		if (*val == LONG_MAX && errno == ERANGE)
33588b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron			return 1;
33688b635b84d831b109f0807922449fa7a900f5dbdStephen M. Cameron	}
337cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
3387bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe	if (kilo) {
3397bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe		unsigned long long mult;
3407bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe		int perc = 0;
3417bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe
3426925dd356191bc40e8a1ebc8fd92a40b476658c3Jens Axboe		mult = get_mult_bytes(str, len, data, &perc);
3437bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe		if (perc)
3447bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe			*val = -1ULL - *val;
3457bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe		else
3467bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe			*val *= mult;
3477bb591020669b7266c57108f2a68b48a03ae72eeJens Axboe	} else
3480de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe		*val *= get_mult_time(str, len, is_seconds);
3497126d86baaad3a2b46f1efb05caa4bb691eaa477Jens Axboe
350cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe	return 0;
351cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
352cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
3539af4a24408ea7d4cea084a4fe214b81145cc36acJens Axboeint check_str_bytes(const char *p, long long *val, void *data)
354cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
35579dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron	return str_to_decimal(p, val, 1, data, 0, 0);
356cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
357cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
3580de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboeint check_str_time(const char *p, long long *val, int is_seconds)
359cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
36079dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron	return str_to_decimal(p, val, 0, NULL, is_seconds, 1);
361cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
362cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
363cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboevoid strip_blank_front(char **p)
364cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
365cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe	char *s = *p;
366cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
3674c8e9640702d90f9e2c5d5d5f5f9e299c67978ebJens Axboe	if (!strlen(s))
3684c8e9640702d90f9e2c5d5d5f5f9e299c67978ebJens Axboe		return;
36976cd9378b90dddf2cedc9a5d49f317aaad485b90Jens Axboe	while (isspace((int) *s))
370cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe		s++;
3714d651dad4b3ee17a9be223fc1c0489cd4e304f65Jens Axboe
3724d651dad4b3ee17a9be223fc1c0489cd4e304f65Jens Axboe	*p = s;
373cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
374cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
375cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboevoid strip_blank_end(char *p)
376cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
377853ee7fc686293cd45fbb177c75114ed2489144dJens Axboe	char *start = p, *s;
378523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe
3794c8e9640702d90f9e2c5d5d5f5f9e299c67978ebJens Axboe	if (!strlen(p))
3804c8e9640702d90f9e2c5d5d5f5f9e299c67978ebJens Axboe		return;
3814c8e9640702d90f9e2c5d5d5f5f9e299c67978ebJens Axboe
382523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe	s = strchr(p, ';');
383523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe	if (s)
384523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe		*s = '\0';
385523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe	s = strchr(p, '#');
386523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe	if (s)
387523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe		*s = '\0';
388523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe	if (s)
389523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe		p = s;
390523bfadbd46b375012eb5f3898201455b057a1c4Jens Axboe
3917f7e6e59f48bbd754847c825075a9c46962e0116Jens Axboe	s = p + strlen(p);
39276cd9378b90dddf2cedc9a5d49f317aaad485b90Jens Axboe	while ((isspace((int) *s) || iscntrl((int) *s)) && (s > start))
393cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe		s--;
394cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
395cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe	*(s + 1) = '\0';
396cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
397cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
398d6978a3242daad9cb7b0710b724f19225d1ed7e2Jens Axboestatic int check_range_bytes(const char *str, long *val, void *data)
399cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
40057fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe	long long __val;
401cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
40279dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron	if (!str_to_decimal(str, &__val, 1, data, 0, 0)) {
40357fc29faae372cb474b5f2ef921638ab28bb9dc0Jens Axboe		*val = __val;
404cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe		return 0;
405cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe	}
406cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
407cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe	return 1;
408cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
409cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
41063f29372bc1bd69b66816c96d88b9c0bd8f3d8b9Jens Axboestatic int check_int(const char *p, int *val)
411cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
412787f7e95a3fb3bbe88431da53337bb9551d2357cJens Axboe	if (!strlen(p))
413787f7e95a3fb3bbe88431da53337bb9551d2357cJens Axboe		return 1;
414d78ee463665c7eb710e5ee5070b7873bee6dc611Jens Axboe	if (strstr(p, "0x") || strstr(p, "0X")) {
415a61bdfd8846317f431c318e0fe1fb841084ca9eaJens Axboe		if (sscanf(p, "%x", val) == 1)
416a61bdfd8846317f431c318e0fe1fb841084ca9eaJens Axboe			return 0;
417a61bdfd8846317f431c318e0fe1fb841084ca9eaJens Axboe	} else {
418a61bdfd8846317f431c318e0fe1fb841084ca9eaJens Axboe		if (sscanf(p, "%u", val) == 1)
419a61bdfd8846317f431c318e0fe1fb841084ca9eaJens Axboe			return 0;
420a61bdfd8846317f431c318e0fe1fb841084ca9eaJens Axboe	}
421cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
422e1f365035a952233463d85d659bd960ba78f012eJens Axboe	return 1;
423e1f365035a952233463d85d659bd960ba78f012eJens Axboe}
424cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
4258adb452ea0c7bcaae35d0dadcc273162e75232f2Jens Axboestatic size_t opt_len(const char *str)
426808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe{
427808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe	char *postfix;
428808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe
429808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe	postfix = strchr(str, ':');
430808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe	if (!postfix)
431808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe		return strlen(str);
432808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe
433808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe	return (int)(postfix - str);
434808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe}
435808def7036ddfaf6f0ec2f5ecce031fd46ce40efJens Axboe
436119cd939010b646825d06ac04af41dc5268f2765Jens Axboestatic int str_match_len(const struct value_pair *vp, const char *str)
437119cd939010b646825d06ac04af41dc5268f2765Jens Axboe{
438119cd939010b646825d06ac04af41dc5268f2765Jens Axboe	return max(strlen(vp->ival), opt_len(str));
439119cd939010b646825d06ac04af41dc5268f2765Jens Axboe}
440119cd939010b646825d06ac04af41dc5268f2765Jens Axboe
441f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe#define val_store(ptr, val, off, or, data, o)		\
442f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe	do {						\
443f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe		ptr = td_var((data), (o), (off));	\
444f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe		if ((or))				\
445f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe			*ptr |= (val);			\
446f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe		else					\
447f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe			*ptr = (val);			\
44817abbe89b8d3a4c7a4deab00a7cc98fbd215f1efJens Axboe	} while (0)
44917abbe89b8d3a4c7a4deab00a7cc98fbd215f1efJens Axboe
450f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboestatic int __handle_option(struct fio_option *o, const char *ptr, void *data,
451833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			   int first, int more, int curr)
452cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
4532fdbefdd43968f3bf354a488288b9794b5f5c6bbErwan Velu	int il=0, *ilp;
454fd112d34a2cfdc2d9efcd394e38b6d87b357c23dVincent Kang Fu	fio_fp64_t *flp;
45563f29372bc1bd69b66816c96d88b9c0bd8f3d8b9Jens Axboe	long long ull, *ullp;
45663f29372bc1bd69b66816c96d88b9c0bd8f3d8b9Jens Axboe	long ul1, ul2;
457833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong	double uf;
458bfe1d59237aeb5a9c3540b0beb69c686af41dfa9Jens Axboe	char **cp = NULL;
459e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe	int ret = 0, is_time = 0;
460c44b1ff54402c589e8f07436ec56efb4f8b1ac23Jens Axboe	const struct value_pair *vp;
461c44b1ff54402c589e8f07436ec56efb4f8b1ac23Jens Axboe	struct value_pair posval[PARSE_MAX_VP];
462c44b1ff54402c589e8f07436ec56efb4f8b1ac23Jens Axboe	int i, all_skipped = 1;
463cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
464a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe	dprint(FD_PARSE, "__handle_option=%s, type=%d, ptr=%s\n", o->name,
465a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe							o->type, ptr);
466a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe
467e3cedca76d9fc104eb4f6f869606fb5bf4c0d59cJens Axboe	if (!ptr && o->type != FIO_OPT_STR_SET && o->type != FIO_OPT_STR) {
46828d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe		log_err("Option %s requires an argument\n", o->name);
46908e26e3579fdae51cc9aafc71a80c638563bf2cdJens Axboe		return 1;
47008e26e3579fdae51cc9aafc71a80c638563bf2cdJens Axboe	}
47108e26e3579fdae51cc9aafc71a80c638563bf2cdJens Axboe
472e1f365035a952233463d85d659bd960ba78f012eJens Axboe	switch (o->type) {
4735f6ddf1e568d5014925a98da316d92f9e6e03eb4Jens Axboe	case FIO_OPT_STR:
4745f6ddf1e568d5014925a98da316d92f9e6e03eb4Jens Axboe	case FIO_OPT_STR_MULTI: {
475e1f365035a952233463d85d659bd960ba78f012eJens Axboe		fio_opt_str_fn *fn = o->cb;
476b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe
477f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe		posval_sort(o, posval);
478f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe
4795f6ddf1e568d5014925a98da316d92f9e6e03eb4Jens Axboe		ret = 1;
480b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe		for (i = 0; i < PARSE_MAX_VP; i++) {
481f085737f15364ba194e5582b19a71eb35d4b8d11Jens Axboe			vp = &posval[i];
482b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe			if (!vp->ival || vp->ival[0] == '\0')
483a3073f4a296bba2cbd026603fe284341c370bfb0Jens Axboe				continue;
484ae2ddba4e74f06b5ec986d1c3387cd14e69f8146Jens Axboe			all_skipped = 0;
485119cd939010b646825d06ac04af41dc5268f2765Jens Axboe			if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
486b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe				ret = 0;
4877b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				if (o->off1)
488ebadc0ce34c11b3e0130d5602b18f4ed0e638386Daniel Gollub					val_store(ilp, vp->oval, o->off1, vp->orval, data, o);
4895f6ddf1e568d5014925a98da316d92f9e6e03eb4Jens Axboe				continue;
490b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe			}
491b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe		}
492cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
493ae2ddba4e74f06b5ec986d1c3387cd14e69f8146Jens Axboe		if (ret && !all_skipped)
494b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe			show_option_values(o);
495b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe		else if (fn)
496b1ec1da670aab645e32303ea5ffaa1e5ca336936Jens Axboe			ret = fn(data, ptr);
497e1f365035a952233463d85d659bd960ba78f012eJens Axboe		break;
498e1f365035a952233463d85d659bd960ba78f012eJens Axboe	}
499e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe	case FIO_OPT_STR_VAL_TIME:
500e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe		is_time = 1;
5011a1137d9ba2603e295aaac579777ab0d3524faa6Jens Axboe	case FIO_OPT_INT:
502e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe	case FIO_OPT_STR_VAL: {
503e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe		fio_opt_str_val_fn *fn = o->cb;
5046eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li		char tmp[128], *p;
5056eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li
50679dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron		if (!is_time && o->is_time)
50779dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron			is_time = o->is_time;
50879dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron
509eaa89f5256b92e78067dc3649e4d9b7a70149302Jens Axboe		tmp[sizeof(tmp) - 1] = '\0';
5106eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li		strncpy(tmp, ptr, sizeof(tmp) - 1);
5116eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li		p = strchr(tmp, ',');
5126eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li		if (p)
5136eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			*p = '\0';
514e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe
515e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe		if (is_time)
5160de5b26f6e177aacac0683306c47e0cbaf58b0b6Jens Axboe			ret = check_str_time(tmp, &ull, o->is_seconds);
517e42b01eba09c9d2f5e943b67eaf66c8a443c230fJens Axboe		else
5186eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			ret = check_str_bytes(tmp, &ull, data);
519e1f365035a952233463d85d659bd960ba78f012eJens Axboe
520ae3fcb5afb2479f142912e64cad3c271541af5feJens Axboe		dprint(FD_PARSE, "  ret=%d, out=%llu\n", ret, ull);
521ae3fcb5afb2479f142912e64cad3c271541af5feJens Axboe
522e1f365035a952233463d85d659bd960ba78f012eJens Axboe		if (ret)
523e1f365035a952233463d85d659bd960ba78f012eJens Axboe			break;
524e1f365035a952233463d85d659bd960ba78f012eJens Axboe
525db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		if (o->maxval && ull > o->maxval) {
526d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe			log_err("max value out of range: %llu"
527d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe					" (%u max)\n", ull, o->maxval);
528db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe			return 1;
529db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		}
530db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		if (o->minval && ull < o->minval) {
531d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe			log_err("min value out of range: %llu"
532d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe					" (%u min)\n", ull, o->minval);
533db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe			return 1;
534db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		}
535d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe		if (o->posval[0].ival) {
536d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe			posval_sort(o, posval);
537d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe
538d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe			ret = 1;
539d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe			for (i = 0; i < PARSE_MAX_VP; i++) {
540d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe				vp = &posval[i];
541d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe				if (!vp->ival || vp->ival[0] == '\0')
542d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe					continue;
543d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe				if (vp->oval == ull) {
544d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe					ret = 0;
545d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe					break;
546d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe				}
547d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe			}
548d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe			if (ret) {
549128e4caf9db24d81b564fe004d471b3550186f51Jens Axboe				log_err("fio: value %llu not allowed:\n", ull);
550128e4caf9db24d81b564fe004d471b3550186f51Jens Axboe				show_option_values(o);
551d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe				return 1;
552d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe			}
553d926d535c7e1a12ff1a57a718ed8e84f617b0172Jens Axboe		}
554e1f365035a952233463d85d659bd960ba78f012eJens Axboe
555e1f365035a952233463d85d659bd960ba78f012eJens Axboe		if (fn)
556e1f365035a952233463d85d659bd960ba78f012eJens Axboe			ret = fn(data, &ull);
557e1f365035a952233463d85d659bd960ba78f012eJens Axboe		else {
558e01b22b8fe3f20376fe8fdc6f2c28cc3682d698eJens Axboe			if (o->type == FIO_OPT_INT) {
5597b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				if (first)
5607b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					val_store(ilp, ull, o->off1, 0, data, o);
5616eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				if (curr == 1) {
5627b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					if (o->off2)
5637b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						val_store(ilp, ull, o->off2, 0, data, o);
56402c6aad501477833c7e017eec0bb14f8e6957b68Jens Axboe				}
5656eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				if (curr == 2) {
5667b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					if (o->off3)
5677b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						val_store(ilp, ull, o->off3, 0, data, o);
5686eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				}
5696eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				if (!more) {
5706eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li					if (curr < 1) {
5717b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						if (o->off2)
5727b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe							val_store(ilp, ull, o->off2, 0, data, o);
5736eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li					}
5746eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li					if (curr < 2) {
5757b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						if (o->off3)
5767b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe							val_store(ilp, ull, o->off3, 0, data, o);
5776eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li					}
5786eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				}
57975e6f36fae06978f29296fce76a7f00ca0df7b56Jens Axboe			} else {
5807b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				if (first)
5817b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					val_store(ullp, ull, o->off1, 0, data, o);
58202c6aad501477833c7e017eec0bb14f8e6957b68Jens Axboe				if (!more) {
5837b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					if (o->off2)
5847b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						val_store(ullp, ull, o->off2, 0, data, o);
58502c6aad501477833c7e017eec0bb14f8e6957b68Jens Axboe				}
58675e6f36fae06978f29296fce76a7f00ca0df7b56Jens Axboe			}
587e1f365035a952233463d85d659bd960ba78f012eJens Axboe		}
588e1f365035a952233463d85d659bd960ba78f012eJens Axboe		break;
589e1f365035a952233463d85d659bd960ba78f012eJens Axboe	}
590833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong	case FIO_OPT_FLOAT_LIST: {
591eef02441621aa969f01a1a331e0215dd587d25afJens Axboe		char *cp2;
592eef02441621aa969f01a1a331e0215dd587d25afJens Axboe
593435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		if (first) {
594435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu			/*
595435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu			** Initialize precision to 0 and zero out list
596435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu			** in case specified list is shorter than default
597435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu			*/
5983e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe			if (o->off2) {
5993e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe				ul2 = 0;
600f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe				ilp = td_var(data, o, o->off2);
6013e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe				*ilp = ul2;
6023e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe			}
603435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu
604f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe			flp = td_var(data, o, o->off1);
605435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu			for(i = 0; i < o->maxlen; i++)
606435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu				flp[i].u.f = 0.0;
607435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		}
608833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		if (curr >= o->maxlen) {
60928d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("the list exceeding max length %d\n",
610833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong					o->maxlen);
611833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			return 1;
612833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		}
61379dc914fcf76e8f6c8f8e20dc75bd424cc833d27Stephen M. Cameron		if (!str_to_float(ptr, &uf, 0)) { /* this breaks if we ever have lists of times */
61428d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("not a floating point value: %s\n", ptr);
615833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			return 1;
616833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		}
617266506958a1dbaa41800f0b1170217d81c702f47Jens Axboe		if (uf > o->maxfp) {
61828d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("value out of range: %f"
619833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong				" (range max: %f)\n", uf, o->maxfp);
620833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			return 1;
621833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		}
622266506958a1dbaa41800f0b1170217d81c702f47Jens Axboe		if (uf < o->minfp) {
62328d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("value out of range: %f"
624833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong				" (range min: %f)\n", uf, o->minfp);
625833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			return 1;
626833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		}
627833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong
628f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe		flp = td_var(data, o, o->off1);
629fd112d34a2cfdc2d9efcd394e38b6d87b357c23dVincent Kang Fu		flp[curr].u.f = uf;
630833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong
631ae3fcb5afb2479f142912e64cad3c271541af5feJens Axboe		dprint(FD_PARSE, "  out=%f\n", uf);
632ae3fcb5afb2479f142912e64cad3c271541af5feJens Axboe
633435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		/*
634435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		** Calculate precision for output by counting
635435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		** number of digits after period. Find first
636435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		** period in entire remaining list each time
637435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		*/
638435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		cp2 = strchr(ptr, '.');
639435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		if (cp2 != NULL) {
640eef02441621aa969f01a1a331e0215dd587d25afJens Axboe			int len = 0;
641435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu
642435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu			while (*++cp2 != '\0' && *cp2 >= '0' && *cp2 <= '9')
643435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu				len++;
644435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu
6453e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe			if (o->off2) {
646f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe				ilp = td_var(data, o, o->off2);
6473e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe				if (len > *ilp)
6483e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe					*ilp = len;
6493e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe			}
650435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu		}
651435d195a9da120c5a618129cdb73418f4748c20aVincent Kang Fu
652833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		break;
653833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong	}
654af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe	case FIO_OPT_STR_STORE: {
655af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe		fio_opt_str_fn *fn = o->cb;
656af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe
657f75c69a1e26166b5c205c6d4c0a6a9412ee6cd86Jens Axboe		if (!strlen(ptr))
658f75c69a1e26166b5c205c6d4c0a6a9412ee6cd86Jens Axboe			return 1;
659f75c69a1e26166b5c205c6d4c0a6a9412ee6cd86Jens Axboe
6607b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe		if (o->off1) {
661f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe			cp = td_var(data, o, o->off1);
662184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			*cp = strdup(ptr);
6631c964ce59ba23b1ab515a8f0b6506329c1c3d3e1Jens Axboe		}
66402c6aad501477833c7e017eec0bb14f8e6957b68Jens Axboe
665184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang		if (fn)
666184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			ret = fn(data, ptr);
667184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang		else if (o->posval[0].ival) {
668184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			posval_sort(o, posval);
669184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang
670184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			ret = 1;
671184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			for (i = 0; i < PARSE_MAX_VP; i++) {
672184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang				vp = &posval[i];
673ab50817f68faf742e7725922b9225fc067275750Jens Axboe				if (!vp->ival || vp->ival[0] == '\0' || !cp)
674184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					continue;
675184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang				all_skipped = 0;
676119cd939010b646825d06ac04af41dc5268f2765Jens Axboe				if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
677184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					char *rest;
678184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang
679184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					ret = 0;
680184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					if (vp->cb)
681184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang						fn = vp->cb;
682184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					rest = strstr(*cp ?: ptr, ":");
683184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					if (rest) {
684184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang						if (*cp)
685184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang							*rest = '\0';
686184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang						ptr = rest + 1;
687184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					} else
688184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang						ptr = NULL;
689184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang					break;
690184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang				}
691af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe			}
692af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe		}
693c44b1ff54402c589e8f07436ec56efb4f8b1ac23Jens Axboe
694184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang		if (!all_skipped) {
695184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			if (ret && !*cp)
696184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang				show_option_values(o);
697184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			else if (ret && *cp)
698184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang				ret = 0;
699184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang			else if (fn && ptr)
700184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang				ret = fn(data, ptr);
701184b4098cccb8392eb8ecdd23cdc6597b540df36Steven Lang		}
702c44b1ff54402c589e8f07436ec56efb4f8b1ac23Jens Axboe
703e1f365035a952233463d85d659bd960ba78f012eJens Axboe		break;
704af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe	}
705e1f365035a952233463d85d659bd960ba78f012eJens Axboe	case FIO_OPT_RANGE: {
706b765a37296e6a08b6e06d9186832546a18b0d2d7Jens Axboe		char tmp[128];
707e1f365035a952233463d85d659bd960ba78f012eJens Axboe		char *p1, *p2;
708e1f365035a952233463d85d659bd960ba78f012eJens Axboe
709eaa89f5256b92e78067dc3649e4d9b7a70149302Jens Axboe		tmp[sizeof(tmp) - 1] = '\0';
7100bbab0e789d4d8438d63327da052d64b45f0596aJens Axboe		strncpy(tmp, ptr, sizeof(tmp) - 1);
711b765a37296e6a08b6e06d9186832546a18b0d2d7Jens Axboe
71231d23f47d5ee53f74fbf20e17e83c7cb42e39878Dave Engberg		/* Handle bsrange with separate read,write values: */
71331d23f47d5ee53f74fbf20e17e83c7cb42e39878Dave Engberg		p1 = strchr(tmp, ',');
71431d23f47d5ee53f74fbf20e17e83c7cb42e39878Dave Engberg		if (p1)
71531d23f47d5ee53f74fbf20e17e83c7cb42e39878Dave Engberg			*p1 = '\0';
71631d23f47d5ee53f74fbf20e17e83c7cb42e39878Dave Engberg
717b765a37296e6a08b6e06d9186832546a18b0d2d7Jens Axboe		p1 = strchr(tmp, '-');
718e1f365035a952233463d85d659bd960ba78f012eJens Axboe		if (!p1) {
7190c9baf913d6d251973798048d29c60507f486ee6Jens Axboe			p1 = strchr(tmp, ':');
7200c9baf913d6d251973798048d29c60507f486ee6Jens Axboe			if (!p1) {
7210c9baf913d6d251973798048d29c60507f486ee6Jens Axboe				ret = 1;
7220c9baf913d6d251973798048d29c60507f486ee6Jens Axboe				break;
7230c9baf913d6d251973798048d29c60507f486ee6Jens Axboe			}
724e1f365035a952233463d85d659bd960ba78f012eJens Axboe		}
725e1f365035a952233463d85d659bd960ba78f012eJens Axboe
726e1f365035a952233463d85d659bd960ba78f012eJens Axboe		p2 = p1 + 1;
727e1f365035a952233463d85d659bd960ba78f012eJens Axboe		*p1 = '\0';
728b765a37296e6a08b6e06d9186832546a18b0d2d7Jens Axboe		p1 = tmp;
729e1f365035a952233463d85d659bd960ba78f012eJens Axboe
730e1f365035a952233463d85d659bd960ba78f012eJens Axboe		ret = 1;
731d6978a3242daad9cb7b0710b724f19225d1ed7e2Jens Axboe		if (!check_range_bytes(p1, &ul1, data) &&
732d6978a3242daad9cb7b0710b724f19225d1ed7e2Jens Axboe		    !check_range_bytes(p2, &ul2, data)) {
733e1f365035a952233463d85d659bd960ba78f012eJens Axboe			ret = 0;
734e1f365035a952233463d85d659bd960ba78f012eJens Axboe			if (ul1 > ul2) {
735f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe				unsigned long foo = ul1;
736f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe
737f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe				ul1 = ul2;
738f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe				ul2 = foo;
739f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe			}
740f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe
741f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe			if (first) {
7427b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				val_store(ilp, ul1, o->off1, 0, data, o);
7437b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				val_store(ilp, ul2, o->off2, 0, data, o);
74417abbe89b8d3a4c7a4deab00a7cc98fbd215f1efJens Axboe			}
7456eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			if (curr == 1) {
7467b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				if (o->off3 && o->off4) {
7477b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					val_store(ilp, ul1, o->off3, 0, data, o);
7487b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					val_store(ilp, ul2, o->off4, 0, data, o);
7496eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				}
7506eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			}
7516eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			if (curr == 2) {
7527b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				if (o->off5 && o->off6) {
7537b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					val_store(ilp, ul1, o->off5, 0, data, o);
7547b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					val_store(ilp, ul2, o->off6, 0, data, o);
7556eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				}
7566eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			}
7576eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			if (!more) {
7586eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				if (curr < 1) {
7597b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					if (o->off3 && o->off4) {
7607b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						val_store(ilp, ul1, o->off3, 0, data, o);
7617b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						val_store(ilp, ul2, o->off4, 0, data, o);
7626eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li					}
7636eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				}
7646eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				if (curr < 2) {
7657b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					if (o->off5 && o->off6) {
7667b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						val_store(ilp, ul1, o->off5, 0, data, o);
7677b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe						val_store(ilp, ul2, o->off6, 0, data, o);
7686eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li					}
7696eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li				}
770e1f365035a952233463d85d659bd960ba78f012eJens Axboe			}
77117abbe89b8d3a4c7a4deab00a7cc98fbd215f1efJens Axboe		}
77217abbe89b8d3a4c7a4deab00a7cc98fbd215f1efJens Axboe
773e1f365035a952233463d85d659bd960ba78f012eJens Axboe		break;
774e1f365035a952233463d85d659bd960ba78f012eJens Axboe	}
77574ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe	case FIO_OPT_BOOL:
77674ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe	case FIO_OPT_STR_SET: {
777e1f365035a952233463d85d659bd960ba78f012eJens Axboe		fio_opt_int_fn *fn = o->cb;
778e1f365035a952233463d85d659bd960ba78f012eJens Axboe
77974ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe		if (ptr)
78074ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe			ret = check_int(ptr, &il);
78174ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe		else if (o->type == FIO_OPT_BOOL)
78274ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe			ret = 1;
78374ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe		else
78474ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe			il = 1;
78574ba1808c32e978229eefa7cf28c08bcb73b5b5dJens Axboe
786ae3fcb5afb2479f142912e64cad3c271541af5feJens Axboe		dprint(FD_PARSE, "  ret=%d, out=%d\n", ret, il);
787ae3fcb5afb2479f142912e64cad3c271541af5feJens Axboe
788e1f365035a952233463d85d659bd960ba78f012eJens Axboe		if (ret)
789e1f365035a952233463d85d659bd960ba78f012eJens Axboe			break;
790e1f365035a952233463d85d659bd960ba78f012eJens Axboe
791db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		if (o->maxval && il > (int) o->maxval) {
79228d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("max value out of range: %d (%d max)\n",
7935ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe								il, o->maxval);
794db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe			return 1;
795db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		}
796db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		if (o->minval && il < o->minval) {
79728d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("min value out of range: %d (%d min)\n",
7985ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe								il, o->minval);
799db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe			return 1;
800db8e0165bd86c5a4e9909b846acdbd5b22d263b1Jens Axboe		}
801e1f365035a952233463d85d659bd960ba78f012eJens Axboe
80276a43db448f9fd5e9f1397428a433466d98e0d5dJens Axboe		if (o->neg)
80376a43db448f9fd5e9f1397428a433466d98e0d5dJens Axboe			il = !il;
80476a43db448f9fd5e9f1397428a433466d98e0d5dJens Axboe
805e1f365035a952233463d85d659bd960ba78f012eJens Axboe		if (fn)
806e1f365035a952233463d85d659bd960ba78f012eJens Axboe			ret = fn(data, &il);
807e1f365035a952233463d85d659bd960ba78f012eJens Axboe		else {
8087b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe			if (first)
8097b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				val_store(ilp, il, o->off1, 0, data, o);
81002c6aad501477833c7e017eec0bb14f8e6957b68Jens Axboe			if (!more) {
8117b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe				if (o->off2)
8127b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe					val_store(ilp, il, o->off2, 0, data, o);
81302c6aad501477833c7e017eec0bb14f8e6957b68Jens Axboe			}
814e1f365035a952233463d85d659bd960ba78f012eJens Axboe		}
815e1f365035a952233463d85d659bd960ba78f012eJens Axboe		break;
816e1f365035a952233463d85d659bd960ba78f012eJens Axboe	}
81715ca150e8dbfd68aa5beb479fcb3f07447417a04Jens Axboe	case FIO_OPT_DEPRECATED:
81806b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_info("Option %s is deprecated\n", o->name);
819d94722713ebd7bbdbf8b284b7563f2dd17964e24Jens Axboe		ret = 1;
82015ca150e8dbfd68aa5beb479fcb3f07447417a04Jens Axboe		break;
821e1f365035a952233463d85d659bd960ba78f012eJens Axboe	default:
82206b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_err("Bad option type %u\n", o->type);
823e1f365035a952233463d85d659bd960ba78f012eJens Axboe		ret = 1;
824e1f365035a952233463d85d659bd960ba78f012eJens Axboe	}
825cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
82670a4c0c8417bba7c2e1e9a384b9acf226f5b9782Jens Axboe	if (ret)
82770a4c0c8417bba7c2e1e9a384b9acf226f5b9782Jens Axboe		return ret;
82870a4c0c8417bba7c2e1e9a384b9acf226f5b9782Jens Axboe
829d447a8c25a735519089626b3047da646597a7c6fJens Axboe	if (o->verify) {
83070a4c0c8417bba7c2e1e9a384b9acf226f5b9782Jens Axboe		ret = o->verify(o, data);
831d447a8c25a735519089626b3047da646597a7c6fJens Axboe		if (ret) {
83228d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("Correct format for offending option\n");
83328d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe			log_err("%20s: %s\n", o->name, o->help);
83406b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe			show_option_help(o, 1);
835d447a8c25a735519089626b3047da646597a7c6fJens Axboe		}
836d447a8c25a735519089626b3047da646597a7c6fJens Axboe	}
83770a4c0c8417bba7c2e1e9a384b9acf226f5b9782Jens Axboe
838e1f365035a952233463d85d659bd960ba78f012eJens Axboe	return ret;
839cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe}
840cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe
8417c8f1a5ce2ecde0ef8372e983895855ac838c76cJens Axboestatic int handle_option(struct fio_option *o, const char *__ptr, void *data)
842f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe{
843b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	char *o_ptr, *ptr, *ptr2;
844b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	int ret, done;
845f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe
8467c8f1a5ce2ecde0ef8372e983895855ac838c76cJens Axboe	dprint(FD_PARSE, "handle_option=%s, ptr=%s\n", o->name, __ptr);
8477c8f1a5ce2ecde0ef8372e983895855ac838c76cJens Axboe
848b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	o_ptr = ptr = NULL;
8497c8f1a5ce2ecde0ef8372e983895855ac838c76cJens Axboe	if (__ptr)
850b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		o_ptr = ptr = strdup(__ptr);
851a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe
852f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe	/*
853b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	 * See if we have another set of parameters, hidden after a comma.
854b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	 * Do this before parsing this round, to check if we should
855787f7e95a3fb3bbe88431da53337bb9551d2357cJens Axboe	 * copy set 1 options to set 2.
856f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe	 */
857b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	done = 0;
858b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	ret = 1;
859b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	do {
860b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		int __ret;
861b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe
862b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		ptr2 = NULL;
863b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		if (ptr &&
864b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		    (o->type != FIO_OPT_STR_STORE) &&
865833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		    (o->type != FIO_OPT_STR) &&
866833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		    (o->type != FIO_OPT_FLOAT_LIST)) {
867b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe			ptr2 = strchr(ptr, ',');
868b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe			if (ptr2 && *(ptr2 + 1) == '\0')
869b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe				*ptr2 = '\0';
8706eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li			if (o->type != FIO_OPT_STR_MULTI && o->type != FIO_OPT_RANGE) {
871b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe				if (!ptr2)
872b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe					ptr2 = strchr(ptr, ':');
873b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe				if (!ptr2)
874b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe					ptr2 = strchr(ptr, '-');
875b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe			}
876833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		} else if (ptr && o->type == FIO_OPT_FLOAT_LIST) {
877833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong			ptr2 = strchr(ptr, ':');
878b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		}
879787f7e95a3fb3bbe88431da53337bb9551d2357cJens Axboe
880b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		/*
881b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		 * Don't return early if parsing the first option fails - if
882b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		 * we are doing multiple arguments, we can allow the first one
883b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		 * being empty.
884b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		 */
885833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong		__ret = __handle_option(o, ptr, data, !done, !!ptr2, done);
886b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		if (ret)
887b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe			ret = __ret;
888787f7e95a3fb3bbe88431da53337bb9551d2357cJens Axboe
889b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		if (!ptr2)
890b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe			break;
891f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe
892b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		ptr = ptr2 + 1;
893b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		done++;
894b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	} while (1);
895787f7e95a3fb3bbe88431da53337bb9551d2357cJens Axboe
896b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	if (o_ptr)
897b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe		free(o_ptr);
898b62bdf2c3e8877c276796d1ed7909df194fc846cJens Axboe	return ret;
899f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe}
900f90eff5a414f6e8c16a51c3a7d9b5e077ab49aacJens Axboe
901de890a1e48d40238dac69f302708dde8719de240Steven Langstatic struct fio_option *get_option(char *opt,
90207b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe				     struct fio_option *options, char **post)
9033b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe{
9043b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	struct fio_option *o;
9053b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	char *ret;
9063b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
9073b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	ret = strchr(opt, '=');
9083b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	if (ret) {
9093b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe		*post = ret;
9103b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe		*ret = '\0';
911de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = opt;
9123b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe		(*post)++;
91343c129b4ff85a7f7f7e0929f9dd73e756e37a2e3Jens Axboe		strip_blank_end(ret);
91407b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe		o = find_option(options, ret);
9153b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	} else {
91607b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe		o = find_option(options, opt);
9173b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe		*post = NULL;
9183b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	}
9193b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
9203b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	return o;
9213b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe}
9223b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
9233b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboestatic int opt_cmp(const void *p1, const void *p2)
9243b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe{
925de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct fio_option *o;
926de890a1e48d40238dac69f302708dde8719de240Steven Lang	char *s, *foo;
9278cdabc1df71ec546d47ba4eb1190b8c7b6e62f9aJens Axboe	int prio1, prio2;
9283b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
9298cdabc1df71ec546d47ba4eb1190b8c7b6e62f9aJens Axboe	prio1 = prio2 = 0;
9303b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
931de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (*(char **)p1) {
932de890a1e48d40238dac69f302708dde8719de240Steven Lang		s = strdup(*((char **) p1));
9339af4a24408ea7d4cea084a4fe214b81145cc36acJens Axboe		o = get_option(s, __fio_options, &foo);
934de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o)
935de890a1e48d40238dac69f302708dde8719de240Steven Lang			prio1 = o->prio;
936de890a1e48d40238dac69f302708dde8719de240Steven Lang		free(s);
937de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
938de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (*(char **)p2) {
939de890a1e48d40238dac69f302708dde8719de240Steven Lang		s = strdup(*((char **) p2));
9409af4a24408ea7d4cea084a4fe214b81145cc36acJens Axboe		o = get_option(s, __fio_options, &foo);
941de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o)
942de890a1e48d40238dac69f302708dde8719de240Steven Lang			prio2 = o->prio;
943de890a1e48d40238dac69f302708dde8719de240Steven Lang		free(s);
944de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
945de890a1e48d40238dac69f302708dde8719de240Steven Lang
9468cdabc1df71ec546d47ba4eb1190b8c7b6e62f9aJens Axboe	return prio2 - prio1;
9473b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe}
9483b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
9493b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboevoid sort_options(char **opts, struct fio_option *options, int num_opts)
9503b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe{
9519af4a24408ea7d4cea084a4fe214b81145cc36acJens Axboe	__fio_options = options;
9523b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe	qsort(opts, num_opts, sizeof(char *), opt_cmp);
9539af4a24408ea7d4cea084a4fe214b81145cc36acJens Axboe	__fio_options = NULL;
9543b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe}
9553b8b7135602a4d3a7132fee10da9c1203ab643adJens Axboe
956b46928282e0a890f49250e79b81af773a2b7108fJens Axboeint parse_cmd_option(const char *opt, const char *val,
95707b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe		     struct fio_option *options, void *data)
958b46928282e0a890f49250e79b81af773a2b7108fJens Axboe{
959b46928282e0a890f49250e79b81af773a2b7108fJens Axboe	struct fio_option *o;
960b46928282e0a890f49250e79b81af773a2b7108fJens Axboe
96107b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe	o = find_option(options, opt);
962b46928282e0a890f49250e79b81af773a2b7108fJens Axboe	if (!o) {
96306b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_err("Bad option <%s>\n", opt);
964b46928282e0a890f49250e79b81af773a2b7108fJens Axboe		return 1;
965b46928282e0a890f49250e79b81af773a2b7108fJens Axboe	}
966b46928282e0a890f49250e79b81af773a2b7108fJens Axboe
967b1508cf9ead36dc789a4e289f7522a070e57058cJens Axboe	if (!handle_option(o, val, data))
968b1508cf9ead36dc789a4e289f7522a070e57058cJens Axboe		return 0;
969b1508cf9ead36dc789a4e289f7522a070e57058cJens Axboe
97006b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe	log_err("fio: failed parsing %s=%s\n", opt, val);
971b1508cf9ead36dc789a4e289f7522a070e57058cJens Axboe	return 1;
972b46928282e0a890f49250e79b81af773a2b7108fJens Axboe}
973b46928282e0a890f49250e79b81af773a2b7108fJens Axboe
974de890a1e48d40238dac69f302708dde8719de240Steven Langint parse_option(char *opt, const char *input,
975292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		 struct fio_option *options, struct fio_option **o, void *data,
976292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		 int dump_cmdline)
977cb2c86fdf03241fee32fd2e2caff43af1022403cJens Axboe{
978d0c814ececb7410e97d1a437e80fc2dfd5c6de38Steven Lang	char *post;
979e1f365035a952233463d85d659bd960ba78f012eJens Axboe
980d0c814ececb7410e97d1a437e80fc2dfd5c6de38Steven Lang	if (!opt) {
981d0c814ececb7410e97d1a437e80fc2dfd5c6de38Steven Lang		log_err("fio: failed parsing %s\n", input);
982de890a1e48d40238dac69f302708dde8719de240Steven Lang		*o = NULL;
98338789b58775ee5e00f4669f01b3c9da31a7345e3Jens Axboe		return 1;
984d0c814ececb7410e97d1a437e80fc2dfd5c6de38Steven Lang	}
985e1f365035a952233463d85d659bd960ba78f012eJens Axboe
986de890a1e48d40238dac69f302708dde8719de240Steven Lang	*o = get_option(opt, options, &post);
987de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (!*o) {
988de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (post) {
989de890a1e48d40238dac69f302708dde8719de240Steven Lang			int len = strlen(opt);
990de890a1e48d40238dac69f302708dde8719de240Steven Lang			if (opt + len + 1 != post)
991de890a1e48d40238dac69f302708dde8719de240Steven Lang				memmove(opt + len + 1, post, strlen(post));
992de890a1e48d40238dac69f302708dde8719de240Steven Lang			opt[len] = '=';
993de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
994e1f365035a952233463d85d659bd960ba78f012eJens Axboe		return 1;
995e1f365035a952233463d85d659bd960ba78f012eJens Axboe	}
996e1f365035a952233463d85d659bd960ba78f012eJens Axboe
997292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe	if (handle_option(*o, post, data)) {
998292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		log_err("fio: failed parsing %s\n", input);
999292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		return 1;
1000292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe	}
1001b1508cf9ead36dc789a4e289f7522a070e57058cJens Axboe
1002292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe	if (dump_cmdline) {
1003292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		const char *delim;
1004292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe
1005292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		if (!strcmp("description", (*o)->name))
1006292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe			delim = "\"";
1007292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		else
1008292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe			delim = "";
1009292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe
1010292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		log_info("--%s%s", (*o)->name, post ? "" : " ");
1011292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe		if (post)
1012292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe			log_info("=%s%s%s ", delim, post, delim);
1013292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe	}
1014292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe
1015292cc475b1f26ae4c94c3028fc33dee96b22655bJens Axboe	return 0;
1016e1f365035a952233463d85d659bd960ba78f012eJens Axboe}
1017fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe
10180e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe/*
10190e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe * Option match, levenshtein distance. Handy for not quite remembering what
10200e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe * the option name is.
10210e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe */
1022786715eaa81c267b4a372e22f028e7a5543e5698Jens Axboeint string_distance(const char *s1, const char *s2)
10230e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe{
10240e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	unsigned int s1_len = strlen(s1);
10250e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	unsigned int s2_len = strlen(s2);
10260e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	unsigned int *p, *q, *r;
10270e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	unsigned int i, j;
10280e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
10290e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	p = malloc(sizeof(unsigned int) * (s2_len + 1));
10300e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	q = malloc(sizeof(unsigned int) * (s2_len + 1));
10310e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
10320e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	p[0] = 0;
10330e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	for (i = 1; i <= s2_len; i++)
10340e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		p[i] = p[i - 1] + 1;
10350e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
10360e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	for (i = 1; i <= s1_len; i++) {
10370e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		q[0] = p[0] + 1;
10380e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		for (j = 1; j <= s2_len; j++) {
10390e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe			unsigned int sub = p[j - 1];
10400f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe			unsigned int pmin;
10410e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
10420e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe			if (s1[i - 1] != s2[j - 1])
10430e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe				sub++;
10440e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
10450f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe			pmin = min(q[j - 1] + 1, sub);
10460f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe			q[j] = min(p[j] + 1, pmin);
10470e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		}
10480e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		r = p;
10490e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		p = q;
10500e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		q = r;
10510e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	}
10520e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
10530e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	i = p[s2_len];
10540e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	free(p);
10550e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	free(q);
10560e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	return i;
10570e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe}
10580e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
1059afdf935261b23cdf08214e708133318548ddf2c4Jens Axboestatic struct fio_option *find_child(struct fio_option *options,
1060afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe				     struct fio_option *o)
1061afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe{
1062afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe	struct fio_option *__o;
1063afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe
1064fdf287440fa8486f0e96c8597349d5d25e98fb6aJens Axboe	for (__o = options + 1; __o->name; __o++)
1065fdf287440fa8486f0e96c8597349d5d25e98fb6aJens Axboe		if (__o->parent && !strcmp(__o->parent, o->name))
1066afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe			return __o;
1067afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe
1068afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe	return NULL;
1069afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe}
1070afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe
1071323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboestatic void __print_option(struct fio_option *o, struct fio_option *org,
1072323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe			   int level)
1073afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe{
1074afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe	char name[256], *p;
1075323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	int depth;
1076afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe
1077afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe	if (!o)
1078afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe		return;
1079ef9aff52b10c71a4cb2b3649deaea270fa3944a0Jens Axboe	if (!org)
1080ef9aff52b10c71a4cb2b3649deaea270fa3944a0Jens Axboe		org = o;
10815ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe
1082afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe	p = name;
1083323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	depth = level;
1084323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	while (depth--)
1085323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe		p += sprintf(p, "%s", "  ");
1086afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe
1087afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe	sprintf(p, "%s", o->name);
1088afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe
108928d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe	log_info("%-24s: %s\n", name, o->help);
1090323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe}
1091323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe
1092323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboestatic void print_option(struct fio_option *o)
1093323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe{
1094323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	struct fio_option *parent;
1095323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	struct fio_option *__o;
1096323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	unsigned int printed;
1097323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	unsigned int level;
1098323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe
1099323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	__print_option(o, NULL, 0);
1100323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	parent = o;
1101323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	level = 0;
1102323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	do {
1103323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe		level++;
1104323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe		printed = 0;
1105323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe
1106323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe		while ((__o = find_child(o, parent)) != NULL) {
1107323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe			__print_option(__o, o, level);
1108323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe			o = __o;
1109323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe			printed++;
1110323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe		}
1111323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe
1112323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe		parent = o;
1113323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe	} while (printed);
1114afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe}
1115afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe
111607b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboeint show_cmd_help(struct fio_option *options, const char *name)
11170e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe{
11180e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	struct fio_option *o, *closest;
1119d091d099aa867596745f2fa0d58631a14a746520Jens Axboe	unsigned int best_dist = -1U;
112029fc6afe1bfcb97dd7f33d8e58b99b2d93237d47Jens Axboe	int found = 0;
1121320beefe2d0c5f05f24b4e0c1d13fcb2f1286a78Jens Axboe	int show_all = 0;
1122320beefe2d0c5f05f24b4e0c1d13fcb2f1286a78Jens Axboe
1123320beefe2d0c5f05f24b4e0c1d13fcb2f1286a78Jens Axboe	if (!name || !strcmp(name, "all"))
1124320beefe2d0c5f05f24b4e0c1d13fcb2f1286a78Jens Axboe		show_all = 1;
1125fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe
11260e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	closest = NULL;
11270e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	best_dist = -1;
11284945ba127a43cad1424ebc75164b7a16a8160933Jens Axboe	for (o = &options[0]; o->name; o++) {
1129320beefe2d0c5f05f24b4e0c1d13fcb2f1286a78Jens Axboe		int match = 0;
1130320beefe2d0c5f05f24b4e0c1d13fcb2f1286a78Jens Axboe
113115ca150e8dbfd68aa5beb479fcb3f07447417a04Jens Axboe		if (o->type == FIO_OPT_DEPRECATED)
113215ca150e8dbfd68aa5beb479fcb3f07447417a04Jens Axboe			continue;
113307b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe		if (!exec_profile && o->prof_name)
113407b3232de97ac32a873f0b5d17c8f49c18ed3ae7Jens Axboe			continue;
11354ac23d27a5e5dea73c4db4a4fcc46a6afe645bd0Jens Axboe		if (exec_profile && !(o->prof_name && !strcmp(exec_profile, o->prof_name)))
11364ac23d27a5e5dea73c4db4a4fcc46a6afe645bd0Jens Axboe			continue;
113715ca150e8dbfd68aa5beb479fcb3f07447417a04Jens Axboe
11380e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		if (name) {
11397f9348f80b8734e0f00d7f4b14e58d2255d46ee7Jens Axboe			if (!strcmp(name, o->name) ||
11407f9348f80b8734e0f00d7f4b14e58d2255d46ee7Jens Axboe			    (o->alias && !strcmp(name, o->alias)))
11410e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe				match = 1;
11420e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe			else {
11430e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe				unsigned int dist;
11440e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
11450e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe				dist = string_distance(name, o->name);
11460e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe				if (dist < best_dist) {
11470e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe					best_dist = dist;
11480e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe					closest = o;
11490e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe				}
11500e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe			}
11510e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe		}
1152fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe
1153fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe		if (show_all || match) {
115429fc6afe1bfcb97dd7f33d8e58b99b2d93237d47Jens Axboe			found = 1;
1155c167dedce798151c8aa8a59be45ce57a5260b1aaJens Axboe			if (match)
115628d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe				log_info("%20s: %s\n", o->name, o->help);
1157c167dedce798151c8aa8a59be45ce57a5260b1aaJens Axboe			if (show_all) {
1158afdf935261b23cdf08214e708133318548ddf2c4Jens Axboe				if (!o->parent)
1159323d9113db91a8fb2efe93b9916c22f74ff9af3fJens Axboe					print_option(o);
11604945ba127a43cad1424ebc75164b7a16a8160933Jens Axboe				continue;
1161c167dedce798151c8aa8a59be45ce57a5260b1aaJens Axboe			}
1162fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe		}
1163fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe
116470df2f19d2a456224fee54e17066298b307c3667Jens Axboe		if (!match)
116570df2f19d2a456224fee54e17066298b307c3667Jens Axboe			continue;
116670df2f19d2a456224fee54e17066298b307c3667Jens Axboe
116706b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		show_option_help(o, 0);
1168fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe	}
1169fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe
117029fc6afe1bfcb97dd7f33d8e58b99b2d93237d47Jens Axboe	if (found)
117129fc6afe1bfcb97dd7f33d8e58b99b2d93237d47Jens Axboe		return 0;
1172fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe
117328d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe	log_err("No such command: %s", name);
1174d091d099aa867596745f2fa0d58631a14a746520Jens Axboe
1175d091d099aa867596745f2fa0d58631a14a746520Jens Axboe	/*
1176d091d099aa867596745f2fa0d58631a14a746520Jens Axboe	 * Only print an appropriately close option, one where the edit
1177d091d099aa867596745f2fa0d58631a14a746520Jens Axboe	 * distance isn't too big. Otherwise we get crazy matches.
1178d091d099aa867596745f2fa0d58631a14a746520Jens Axboe	 */
1179d091d099aa867596745f2fa0d58631a14a746520Jens Axboe	if (closest && best_dist < 3) {
118028d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe		log_info(" - showing closest match\n");
118128d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe		log_info("%20s: %s\n", closest->name, closest->help);
118206b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		show_option_help(closest, 0);
11830e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe	} else
118428d7c363e2f82d09cf7f6aa772d255712aff5c5cJens Axboe		log_info("\n");
11850e9f7fac2a501f2baeedd11446e9fe102720c27dJens Axboe
118629fc6afe1bfcb97dd7f33d8e58b99b2d93237d47Jens Axboe	return 1;
1187fd28ca4948aa67b76585c6c23d7f70a2cdc7a0d5Jens Axboe}
1188ee738499877bb1ee913e839cb4a8d4edad2d52adJens Axboe
118913335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe/*
119013335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe * Handle parsing of default parameters.
119113335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe */
1192ee738499877bb1ee913e839cb4a8d4edad2d52adJens Axboevoid fill_default_options(void *data, struct fio_option *options)
1193ee738499877bb1ee913e839cb4a8d4edad2d52adJens Axboe{
11944945ba127a43cad1424ebc75164b7a16a8160933Jens Axboe	struct fio_option *o;
1195ee738499877bb1ee913e839cb4a8d4edad2d52adJens Axboe
1196a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe	dprint(FD_PARSE, "filling default options\n");
1197a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe
11984945ba127a43cad1424ebc75164b7a16a8160933Jens Axboe	for (o = &options[0]; o->name; o++)
1199ee738499877bb1ee913e839cb4a8d4edad2d52adJens Axboe		if (o->def)
1200ee738499877bb1ee913e839cb4a8d4edad2d52adJens Axboe			handle_option(o, o->def, data);
1201ee738499877bb1ee913e839cb4a8d4edad2d52adJens Axboe}
120213335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe
12039f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboevoid option_init(struct fio_option *o)
12049f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe{
12059f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe	if (o->type == FIO_OPT_DEPRECATED)
12069f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe		return;
12079f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe	if (o->type == FIO_OPT_BOOL) {
12089f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe		o->minval = 0;
12099f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe		o->maxval = 1;
12109f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe	}
1211d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe	if (o->type == FIO_OPT_INT) {
1212d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe		if (!o->maxval)
1213d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe			o->maxval = UINT_MAX;
1214d4fc2f04e5fa3cbad31d04eefa39632a301a3d95Jens Axboe	}
1215833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong	if (o->type == FIO_OPT_FLOAT_LIST) {
1216ab9461eaea21e861cc777aae2420db8f486ed1e2Bruce Cran		o->minfp = DBL_MIN;
1217ab9461eaea21e861cc777aae2420db8f486ed1e2Bruce Cran		o->maxfp = DBL_MAX;
1218833491908a1afd67d27ce79257de3a4d80143d9fYu-ju Hong	}
1219ef7035a9b2c7af1e745b7cd2448685527ef7eeb0Jens Axboe	if (o->type == FIO_OPT_STR_SET && o->def && !o->no_warn_def) {
122006b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_err("Option %s: string set option with"
12219f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe				" default will always be true\n", o->name);
12229f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe	}
12237b504eddc4b039f2db3a0626bd08f880c5f4de27Jens Axboe	if (!o->cb && !o->off1)
122406b0be6efb3da5131bc8386251d017f0abafbdacJens Axboe		log_err("Option %s: neither cb nor offset given\n", o->name);
122522754746e5dc2552f0c7b995a2095b5723119784Jens Axboe	if (!o->category) {
1226cca5b5bc3a622b4f4a103d05c55284fc167a0b82Jens Axboe		log_info("Option %s: no category defined. Setting to misc\n", o->name);
122722754746e5dc2552f0c7b995a2095b5723119784Jens Axboe		o->category = FIO_OPT_C_GENERAL;
1228ffd7821f3dadaf8972730d0543301f77d1956a47Jens Axboe		o->group = FIO_OPT_G_INVALID;
122922754746e5dc2552f0c7b995a2095b5723119784Jens Axboe	}
12305f6ddf1e568d5014925a98da316d92f9e6e03eb4Jens Axboe	if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE ||
12315f6ddf1e568d5014925a98da316d92f9e6e03eb4Jens Axboe	    o->type == FIO_OPT_STR_MULTI)
12329f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe		return;
12339f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe}
12349f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe
123513335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe/*
123613335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe * Sanitize the options structure. For now it just sets min/max for bool
12375b0a8880e2a0dafbdd12cabcb82f8fe728937e65Jens Axboe * values and whether both callback and offsets are given.
123813335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe */
123913335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboevoid options_init(struct fio_option *options)
124013335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe{
12414945ba127a43cad1424ebc75164b7a16a8160933Jens Axboe	struct fio_option *o;
124213335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe
1243a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe	dprint(FD_PARSE, "init options\n");
1244a3d741fa3bc3120d5b62a56826a97524daa32803Jens Axboe
124590265353af8dbf1c43804996909777d4c1a5998eJens Axboe	for (o = &options[0]; o->name; o++) {
12469f988e2ebb3bff7087cc9681a54bd7f0d0e42140Jens Axboe		option_init(o);
124790265353af8dbf1c43804996909777d4c1a5998eJens Axboe		if (o->inverse)
124890265353af8dbf1c43804996909777d4c1a5998eJens Axboe			o->inv_opt = find_option(options, o->inverse);
124990265353af8dbf1c43804996909777d4c1a5998eJens Axboe	}
125013335ddb0e304efa0fc96593dd1fd995ec6f68d7Jens Axboe}
12517e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe
12527e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboevoid options_free(struct fio_option *options, void *data)
12537e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe{
12547e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe	struct fio_option *o;
12557e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe	char **ptr;
12567e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe
12577e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe	dprint(FD_PARSE, "free options\n");
12587e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe
12597e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe	for (o = &options[0]; o->name; o++) {
1260de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o->type != FIO_OPT_STR_STORE || !o->off1)
12617e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe			continue;
12627e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe
1263f0fdbcafc3a62b84250e5ccdcaec47e3ffa93a00Jens Axboe		ptr = td_var(data, o, o->off1);
12647e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe		if (*ptr) {
12657e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe			free(*ptr);
12667e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe			*ptr = NULL;
12677e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe		}
12687e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe	}
12697e356b2dee2e86f3684424fc6e903f1ef9f00ef4Jens Axboe}
1270