summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsueloverso <sue@mongodb.com>2015-12-22 11:27:18 -0500
committersueloverso <sue@mongodb.com>2015-12-22 11:27:18 -0500
commit097a503145f9ad6f31883e198c2eed28575ae799 (patch)
treecf8ca26b6db7e03f58c41cbd221c7faa224c5a2b
parentd956d386cb60784f66558c99e000e5de7c799e60 (diff)
parente4bde0dfd63d25411db7b6430817ff88f4cc3039 (diff)
downloadmongo-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.c111
-rw-r--r--bench/wtperf/wtperf.c6
-rw-r--r--bench/wtperf/wtperf.h11
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 *);