Support simple math on reserved keyword expressions
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/HOWTO b/HOWTO
index cdd6473..9b3a684 100644
--- a/HOWTO
+++ b/HOWTO
@@ -203,7 +203,13 @@
These can be used on the command line or in the job file, and will be
automatically substituted with the current system values when the job
-is run.
+is run. Simple math is also supported on these keywords, so you can
+perform actions like:
+
+size=8*$mb_memory
+
+and get that properly expanded to 8 times the size of memory in the
+machine.
5.0 Detailed list of parameters
diff --git a/options.c b/options.c
index 5b88255..211bca7 100644
--- a/options.c
+++ b/options.c
@@ -1788,6 +1788,61 @@
fio_keywords[2].replace = strdup(buf);
}
+#define BC_APP "bc"
+
+static char *bc_calc(char *str)
+{
+ char *buf, *tmp, opt[80];
+ FILE *f;
+ int ret;
+
+ /*
+ * No math, just return string
+ */
+ if (!strchr(str, '+') && !strchr(str, '-') && !strchr(str, '*') &&
+ !strchr(str, '/'))
+ return str;
+
+ /*
+ * Split option from value, we only need to calculate the value
+ */
+ tmp = strchr(str, '=');
+ if (!tmp)
+ return str;
+
+ tmp++;
+ strncpy(opt, str, tmp - str);
+
+ buf = malloc(128);
+
+ sprintf(buf, "which %s > /dev/null", BC_APP);
+ if (system(buf)) {
+ log_err("fio: bc is needed for performing math\n");
+ free(buf);
+ return NULL;
+ }
+
+ sprintf(buf, "echo %s | %s", tmp, BC_APP);
+ f = popen(buf, "r");
+ if (!f) {
+ free(buf);
+ return NULL;
+ }
+
+ ret = fread(buf, 1, 128, f);
+ if (ret <= 0) {
+ free(buf);
+ return NULL;
+ }
+
+ buf[ret - 1] = '\0';
+ strcat(opt, buf);
+ strcpy(buf, opt);
+ pclose(f);
+ free(str);
+ return buf;
+}
+
/*
* Look for reserved variable names and replace them with real values
*/
@@ -1828,7 +1883,10 @@
}
}
- return opt;
+ /*
+ * Check for potential math and invoke bc, if possible
+ */
+ return bc_calc(opt);
}
int fio_options_parse(struct thread_data *td, char **opts, int num_opts)