Support simple math on reserved keyword expressions
authorJens Axboe <jens.axboe@oracle.com>
Fri, 13 Nov 2009 11:19:49 +0000 (12:19 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 13 Nov 2009 11:19:49 +0000 (12:19 +0100)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
options.c

diff --git a/HOWTO b/HOWTO
index cdd6473b28f3574f7a8eca445715cb3d7156b93e..9b3a6848e11c1a43867cd5da6a666ecff12df444 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -203,7 +203,13 @@ $ncpus             Number of online available CPUs
 
 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
index 5b882558177c106028141ac076ecbb71587db639..211bca743048e5a16893634930a85b4eaa7f0e83 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1788,6 +1788,61 @@ void fio_keywords_init(void)
        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 @@ static char *fio_keyword_replace(char *opt)
                }
        }
 
-       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)