diff options
author | sueloverso <sue@mongodb.com> | 2015-12-22 11:27:18 -0500 |
---|---|---|
committer | sueloverso <sue@mongodb.com> | 2015-12-22 11:27:18 -0500 |
commit | 097a503145f9ad6f31883e198c2eed28575ae799 (patch) | |
tree | cf8ca26b6db7e03f58c41cbd221c7faa224c5a2b | |
parent | d956d386cb60784f66558c99e000e5de7c799e60 (diff) | |
parent | e4bde0dfd63d25411db7b6430817ff88f4cc3039 (diff) | |
download | mongo-097a503145f9ad6f31883e198c2eed28575ae799.tar.gz |
Merge pull request #2378 from wiredtiger/wtperf-2269-dump-config
WT-2269 - Add ability to write config dump
-rw-r--r-- | bench/wtperf/config.c | 111 | ||||
-rw-r--r-- | bench/wtperf/wtperf.c | 6 | ||||
-rw-r--r-- | bench/wtperf/wtperf.h | 11 |
3 files changed, 127 insertions, 1 deletions
diff --git a/bench/wtperf/config.c b/bench/wtperf/config.c index 1238c25502c..1e867ee8083 100644 --- a/bench/wtperf/config.c +++ b/bench/wtperf/config.c @@ -106,9 +106,17 @@ config_assign(CONFIG *dest, const CONFIG *src) void config_free(CONFIG *cfg) { + CONFIG_QUEUE_ENTRY *config_line; size_t i; char **pstr; + while (!TAILQ_EMPTY(&cfg->config_head)) { + config_line = TAILQ_FIRST(&cfg->config_head); + TAILQ_REMOVE(&cfg->config_head, config_line, c); + free(config_line->string); + free(config_line); + } + for (i = 0; i < sizeof(config_opts) / sizeof(config_opts[0]); i++) if (config_opts[i].type == STRING_TYPE || config_opts[i].type == CONFIG_STRING_TYPE) { @@ -569,16 +577,34 @@ err: if (fd != -1) int config_opt_line(CONFIG *cfg, const char *optstr) { + CONFIG_QUEUE_ENTRY *config_line; WT_CONFIG_ITEM k, v; WT_CONFIG_PARSER *scan; + size_t len; int ret, t_ret; + char *string_copy; + len = strlen(optstr); if ((ret = wiredtiger_config_parser_open( - NULL, optstr, strlen(optstr), &scan)) != 0) { + NULL, optstr, len, &scan)) != 0) { lprintf(cfg, ret, 0, "Error in config_scan_begin"); return (ret); } + /* + * Append the current line to our copy of the config. The config is + * stored in the order it is processed, so added options will be after + * any parsed from the original config. We allocate len + 1 to allow for + * a null byte to be added. + */ + if ((string_copy = calloc(len + 1, 1)) == NULL) + return (enomem(cfg)); + + strncpy(string_copy, optstr, len); + config_line = calloc(sizeof(CONFIG_QUEUE_ENTRY), 1); + config_line->string = string_copy; + TAILQ_INSERT_TAIL(&cfg->config_head, config_line, c); + while (ret == 0) { if ((ret = scan->next(scan, &k, &v)) != 0) { /* Any parse error has already been reported. */ @@ -653,6 +679,89 @@ config_sanity(CONFIG *cfg) } /* + * config_consolidate -- + * Consolidate repeated configuration settings so that it only appears + * once in the configuration output file. + */ +void +config_consolidate(CONFIG *cfg) +{ + CONFIG_QUEUE_ENTRY *conf_line, *test_line, *tmp; + char *string_key; + + /* + * This loop iterates over the config queue and for entry checks if an + * entry later in the queue has the same key. If a match is found then + * the current queue entry is removed and we continue. + */ + conf_line = TAILQ_FIRST(&cfg->config_head); + while (conf_line != NULL) { + string_key = strchr(conf_line->string, '='); + tmp = test_line = TAILQ_NEXT(conf_line, c); + while (test_line != NULL) { + /* + * The + 1 here forces the '=' sign to be matched + * ensuring we don't match keys that have a common + * prefix such as "table_count" and "table_count_idle" + * as being the same key. + */ + if (strncmp(conf_line->string, test_line->string, + string_key - conf_line->string + 1) == 0) { + TAILQ_REMOVE(&cfg->config_head, conf_line, c); + free(conf_line->string); + free(conf_line); + break; + } + test_line = TAILQ_NEXT(test_line, c); + } + conf_line = tmp; + } +} + +/* + * config_to_file -- + * Write the final config used in this execution to a file. + */ +void +config_to_file(CONFIG *cfg) +{ + CONFIG_QUEUE_ENTRY *config_line; + FILE *fp; + size_t req_len; + char *path; + + fp = NULL; + + /* Backup the config */ + req_len = strlen(cfg->home) + 100; + if ((path = calloc(req_len, 1)) == NULL) { + (void)enomem(cfg); + goto err; + } + + snprintf(path, req_len + 14, "%s/CONFIG.wtperf", cfg->home); + if ((fp = fopen(path, "w")) == NULL) { + lprintf(cfg, errno, 0, "%s", path); + goto err; + } + + /* Print the config dump */ + fprintf(fp,"# Warning. This config includes " + "unwritten, implicit configuration defaults.\n" + "# Changes to those values may cause differences in behavior.\n"); + config_consolidate(cfg); + config_line = TAILQ_FIRST(&cfg->config_head); + while (config_line != NULL) { + fprintf(fp, "%s\n", config_line->string); + config_line = TAILQ_NEXT(config_line, c); + } + +err: free(path); + if (fp != NULL) + (void)fclose(fp); +} + +/* * config_print -- * Print out the configuration in verbose mode. */ diff --git a/bench/wtperf/wtperf.c b/bench/wtperf/wtperf.c index 2f1bc8e3b93..7b350c08231 100644 --- a/bench/wtperf/wtperf.c +++ b/bench/wtperf/wtperf.c @@ -60,6 +60,7 @@ static const CONFIG default_cfg = { 0, /* total seconds running */ 0, /* has truncate */ {NULL, NULL}, /* the truncate queue */ + {NULL, NULL}, /* the config queue */ #define OPT_DEFINE_DEFAULT #include "wtperf_opt.i" @@ -2178,6 +2179,8 @@ main(int argc, char *argv[]) if (config_assign(cfg, &default_cfg)) goto err; + TAILQ_INIT(&cfg->config_head); + /* Do a basic validation of options, and home is needed before open. */ while ((ch = __wt_getopt("wtperf", argc, argv, opts)) != EOF) switch (ch) { @@ -2383,6 +2386,9 @@ main(int argc, char *argv[]) if ((ret = config_sanity(cfg)) != 0) goto err; + /* Write a copy of the config. */ + config_to_file(cfg); + /* Display the configuration. */ if (cfg->verbose > 1) config_print(cfg); diff --git a/bench/wtperf/wtperf.h b/bench/wtperf/wtperf.h index 301aa33a601..361b135ced7 100644 --- a/bench/wtperf/wtperf.h +++ b/bench/wtperf/wtperf.h @@ -127,6 +127,12 @@ struct __truncate_queue_entry { }; typedef struct __truncate_queue_entry TRUNCATE_QUEUE_ENTRY; +struct __config_queue_entry { + char *string; + TAILQ_ENTRY(__config_queue_entry) c; +}; +typedef struct __config_queue_entry CONFIG_QUEUE_ENTRY; + #define LOG_PARTIAL_CONFIG ",log=(enabled=false)" /* * NOTE: If you add any fields to this structure here, you must also add @@ -181,6 +187,9 @@ struct __config { /* Configuration structure */ /* Queue head for use with the Truncate Logic */ TAILQ_HEAD(__truncate_qh, __truncate_queue_entry) stone_head; + /* Queue head to save a copy of the config to be output */ + TAILQ_HEAD(__config_qh, __config_queue_entry) config_head; + /* Fields changeable on command line are listed in wtperf_opt.i */ #define OPT_DECLARE_STRUCT #include "wtperf_opt.i" @@ -272,6 +281,8 @@ void config_free(CONFIG *); int config_opt_file(CONFIG *, const char *); int config_opt_line(CONFIG *, const char *); int config_opt_str(CONFIG *, const char *, const char *); +void config_to_file(CONFIG *); +void config_consolidate(CONFIG *); void config_print(CONFIG *); int config_sanity(CONFIG *); void latency_insert(CONFIG *, uint32_t *, uint32_t *, uint32_t *); |