X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=options.c;h=ebf5d2e6b240932ae5cbcfa04963e4c16ff26c85;hb=23d2461974c334d77eb7a06a2dbd1f37aeee85d4;hp=bd7a85e528d554d0f66ecdce74d3f45b3ba7b6a6;hpb=a639f0bbd278365a2fa15031afd29a24dc917437;p=fio.git diff --git a/options.c b/options.c index bd7a85e5..ebf5d2e6 100644 --- a/options.c +++ b/options.c @@ -15,8 +15,6 @@ #include "parse.h" #include "lib/fls.h" -unsigned int fio_kb_base = 1024; - #define td_var_offset(var) ((size_t) &((struct thread_options *)0)->var) /* @@ -84,7 +82,7 @@ static int bssplit_ddir(struct thread_data *td, int ddir, char *str) } else perc = -1; - if (str_to_decimal(fname, &val, 1)) { + if (str_to_decimal(fname, &val, 1, &td)) { log_err("fio: bssplit conversion failed\n"); free(td->o.bssplit); return 1; @@ -451,6 +449,52 @@ static int check_dir(struct thread_data *td, char *fname) return 0; } +/* + * Return next file in the string. Files are separated with ':'. If the ':' + * is escaped with a '\', then that ':' is part of the filename and does not + * indicate a new file. + */ +static char *get_next_file_name(char **ptr) +{ + char *str = *ptr; + char *p, *start; + + if (!str || !strlen(str)) + return NULL; + + start = str; + do { + /* + * No colon, we are done + */ + p = strchr(str, ':'); + if (!p) { + *ptr = NULL; + break; + } + + /* + * We got a colon, but it's the first character. Skip and + * continue + */ + if (p == start) { + str = ++start; + continue; + } + + if (*(p - 1) != '\\') { + *p = '\0'; + *ptr = p + 1; + break; + } + + memmove(p - 1, p, strlen(p) + 1); + str = p; + } while (1); + + return start; +} + static int str_filename_cb(void *data, const char *input) { struct thread_data *td = data; @@ -464,7 +508,7 @@ static int str_filename_cb(void *data, const char *input) if (!td->files_index) td->o.nr_files = 0; - while ((fname = strsep(&str, ":")) != NULL) { + while ((fname = get_next_file_name(&str)) != NULL) { if (!strlen(fname)) break; if (check_dir(td, fname)) { @@ -639,7 +683,6 @@ static int kb_base_verify(struct fio_option *o, void *data) return 1; } - fio_kb_base = td->o.kb_base; return 0; } @@ -1163,6 +1206,10 @@ static struct fio_option options[] = { .oval = VERIFY_CRC7, .help = "Use crc7 checksums for verification", }, + { .ival = "sha1", + .oval = VERIFY_SHA1, + .help = "Use sha1 checksums for verification", + }, { .ival = "sha256", .oval = VERIFY_SHA256, .help = "Use sha256 checksums for verification", @@ -1655,14 +1702,102 @@ void fio_options_dup_and_init(struct option *long_options) } } +struct fio_keyword { + const char *word; + const char *desc; + char *replace; +}; + +static struct fio_keyword fio_keywords[] = { + { + .word = "$pagesize", + .desc = "Page size in the system", + }, + { + .word = "$mb_memory", + .desc = "Megabytes of memory online", + }, + { + .word = "$ncpus", + .desc = "Number of CPUs online in the system", + }, + { + .word = NULL, + }, +}; + +void fio_keywords_init(void) +{ + unsigned long mb_memory; + char buf[128]; + long l; + + sprintf(buf, "%lu", page_size); + fio_keywords[0].replace = strdup(buf); + + l = sysconf(_SC_PHYS_PAGES); + mb_memory = l * (page_size / 1024UL); + sprintf(buf, "%lu", mb_memory); + fio_keywords[1].replace = strdup(buf); + + l = sysconf(_SC_NPROCESSORS_ONLN); + sprintf(buf, "%lu", l); + fio_keywords[2].replace = strdup(buf); +} + +/* + * Look for reserved variable names and replace them with real values + */ +static char *fio_keyword_replace(char *opt) +{ + char *s; + int i; + + for (i = 0; fio_keywords[i].word != NULL; i++) { + struct fio_keyword *kw = &fio_keywords[i]; + + while ((s = strstr(opt, kw->word)) != NULL) { + char *new = malloc(strlen(opt) + 1); + char *o_org = opt; + int olen = s - opt; + int len; + + /* + * Copy part of the string before the keyword and + * sprintf() the replacement after it. + */ + memcpy(new, opt, olen); + len = sprintf(new + olen, "%s", kw->replace); + + /* + * If there's more in the original string, copy that + * in too + */ + opt += strlen(kw->word) + olen; + if (strlen(opt)) + memcpy(new + olen + len, opt, opt - o_org - 1); + + /* + * replace opt and free the old opt + */ + opt = new; + free(o_org); + } + } + + return opt; +} + int fio_options_parse(struct thread_data *td, char **opts, int num_opts) { int i, ret; sort_options(opts, options, num_opts); - for (ret = 0, i = 0; i < num_opts; i++) + for (ret = 0, i = 0; i < num_opts; i++) { + opts[i] = fio_keyword_replace(opts[i]); ret |= parse_option(opts[i], options, td); + } return ret; } @@ -1719,3 +1854,16 @@ void options_mem_free(struct thread_data fio_unused *td) __options_mem(td, 0); #endif } + +unsigned int fio_get_kb_base(void *data) +{ + struct thread_data *td = data; + unsigned int kb_base = 0; + + if (td) + kb_base = td->o.kb_base; + if (!kb_base) + kb_base = 1024; + + return kb_base; +}