Add more advanced "random' number use for loadfiles.
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Fri, 11 Dec 2009 22:15:53 +0000 (09:15 +1100)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Fri, 11 Dec 2009 22:15:53 +0000 (09:15 +1100)
Make it possible to use random number and add alignment, modulo and
offset to them so it is possible in nfs for example to specify offset as
*/0x1000%5000000
meaning : random number between 0 and 500000 aligned to 4096

update the nfs backend to accept 64 bit offsets

child.c
dbench.h
iscsi.c
libnfs.c
libnfs.h
loadfiles/nfs.txt
nfsio.c

diff --git a/child.c b/child.c
index 8427a3e1a7b808765d34b9c79c3ccff60a933a70..e196a308b66756206567defc2a67dc8809a30090 100644 (file)
--- a/child.c
+++ b/child.c
@@ -28,7 +28,7 @@
 #include "dbench.h"
 #include <zlib.h>
 
-#define ival(s) strtol(s, NULL, 0)
+#define ival(s) strtoll(s, NULL, 0)
 
 static void nb_sleep(int usec)
 {
@@ -90,6 +90,69 @@ static void finish_op(struct child_struct *child, struct op *op)
 
 #define OP_LATENCY(opname) finish_op(child, &child->op.op_ ## opname)
 
+/* here we parse "special" arguments that start with '*'
+ * '*' itself means a random 64 bit number, but this can be qualified as
+ *
+ * '*'     a random 64 bit number
+ * '...%y' modulo y
+ * '.../y' align the number as an integer multiple of y  (( x = (x/y)*y))
+ * '...+y' add 'y'
+ *
+ * Examples :
+ * '*'       : random 64 bit number
+ * '*%1024'  : random number between 0 and 1023
+ * '* /1024'  : random 64 bit number aligned to n*1024
+ * '*%1024/2 : random even number between 0 and 1023
+ */
+uint64_t parse_special(const char *fmt)
+{
+       char q;
+       uint64_t num;
+       uint64_t val;
+
+       num = random();
+       num = (num <<32) | random();
+
+       fmt++;
+       while (*fmt != '\0') {
+               q = *fmt++;
+               val = strtoll(fmt, NULL, 0);
+               if (val == 0) {
+                       printf("Illegal value in random number qualifier. Can not be zero\n");
+                       return num;
+               }
+
+               switch (q) {
+               case '/':
+                       num = (num/val)*val;
+                       break;
+               case '%':
+                       num = num%val;
+                       break;
+               case '+':
+                       num = num+val;
+                       break;
+               default:
+                       printf("Unknown qualifier '%c' for randum number qualifier\n", q);
+               }
+
+               /* skip until the next token */
+               while (*fmt != '\0') {
+                       switch (*fmt) {
+                       case '0'...'9':
+                       case 'a'...'f':
+                       case 'A'...'F':
+                       case 'x':
+                       case 'X':
+                               fmt++;
+                               continue;
+                       }
+                       break;
+               }
+       }
+
+       return num;
+}
 /*
   one child operation
  */
@@ -109,8 +172,8 @@ static void child_op(struct child_struct *child, const char *opname,
        op.fname2 = fname2;
        op.status = status;
        for (i=0;i<sizeof(op.params)/sizeof(op.params[0]);i++) {
-               if (!strcmp(params[i], "*")) {
-                       op.params[i] = random();
+               if (params[i][0] == '*') {
+                       op.params[i] = parse_special(params[i]);
                } else {
                        op.params[i] = params[i]?ival(params[i]):0;
                }
index 5d73cbf8775766dc5fb3c3bf8f0ba67cc64dce7b..484b68d9c046e9bf62b3f6e6b48ac695cb90884d 100644 (file)
--- a/dbench.h
+++ b/dbench.h
@@ -170,7 +170,7 @@ struct dbench_op {
        const char *fname;
        const char *fname2;
        const char *status;
-       int params[10];
+       int64_t params[10];
 };
 
 struct backend_op {
diff --git a/iscsi.c b/iscsi.c
index 914dc1aab82b21e1aeba0fa7ec75ceac4ad6615d..752758ba3e7a5e54620b737a79956c3a7515fc54 100644 (file)
--- a/iscsi.c
+++ b/iscsi.c
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <stdint.h>
+#include <arpa/inet.h>
 #include "dbench.h"
 
 #define discard_const(ptr) ((void *)((intptr_t)(ptr)))
index a98b2cd722a558624f9a76f4678267ba4036e19a..5fde97d53bbb5abb6477638949155c75fa9adca3 100644 (file)
--- a/libnfs.c
+++ b/libnfs.c
@@ -16,7 +16,7 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
-
+#define _FILE_OFFSET_BITS 64
 #include "mount.h"
 #include "nfs.h"
 #include "libnfs.h"
@@ -34,7 +34,7 @@ typedef struct _data_t {
 typedef struct _tree_t {
        data_t key;
        data_t fh;
-       ssize_t size;
+       off_t  file_size;
        struct _tree_t *parent;
        struct _tree_t *left;
        struct _tree_t *right;
@@ -115,7 +115,7 @@ static data_t *recursive_lookup_fhandle(struct nfsio *nfsio, const char *name)
        return ;
 }
 
-static data_t *lookup_fhandle(struct nfsio *nfsio, const char *name, ssize_t *size)
+static data_t *lookup_fhandle(struct nfsio *nfsio, const char *name, off_t *off)
 {
        tree_t *t;
 
@@ -130,8 +130,8 @@ static data_t *lookup_fhandle(struct nfsio *nfsio, const char *name, ssize_t *si
                return recursive_lookup_fhandle(nfsio, name);
        }
 
-       if (size) {
-               *size = t->size;
+       if (off) {
+               *off = t->file_size;
        }
 
        return &t->fh;
@@ -232,7 +232,7 @@ static void delete_fhandle(struct nfsio *nfsio, const char *name)
        return;
 }
 
-static void insert_fhandle(struct nfsio *nfsio, const char *name, const char *fhandle, int length, ssize_t size)
+static void insert_fhandle(struct nfsio *nfsio, const char *name, const char *fhandle, int length, off_t off)
 {
        tree_t *tmp_t;
        tree_t *t;
@@ -262,8 +262,7 @@ static void insert_fhandle(struct nfsio *nfsio, const char *name, const char *fh
        memcpy(discard_const(t->fh.dptr), fhandle, length);
        t->fh.dsize = length;   
        
-       t->size   = size;
-
+       t->file_size = off;
        t->left   = NULL;
        t->right  = NULL;
        t->parent = NULL;
@@ -817,13 +816,13 @@ finished:
        return ret;
 }
 
-nfsstat3 nfsio_read(struct nfsio *nfsio, const char *name, char *buf, uint32 offset, int len, int *count, int *eof)
+nfsstat3 nfsio_read(struct nfsio *nfsio, const char *name, char *buf, uint64_t offset, int len, int *count, int *eof)
 {
        struct READ3args READ3args;
        struct READ3res *READ3res;
        int ret = NFS3_OK;
        data_t *fh;
-       ssize_t size;
+       off_t size;
 
        fh = lookup_fhandle(nfsio, name, &size);
        if (fh == NULL) {
index 6145dc6ca34197e09ab18e7bdb9db99a2d98e10f..0b0dd8bee214d9770d9bb4f92d014ab0b3c51e49 100644 (file)
--- a/libnfs.h
+++ b/libnfs.h
@@ -8,7 +8,7 @@ nfsstat3 nfsio_create(struct nfsio *nfsio, const char *name);
 nfsstat3 nfsio_remove(struct nfsio *nfsio, const char *name);
 nfsstat3 nfsio_write(struct nfsio *nfsio, const char *name, char *buf, uint32 offset, int len, int stable);
 nfsstat3 nfsio_commit(struct nfsio *nfsio, const char *name);
-nfsstat3 nfsio_read(struct nfsio *nfsio, const char *name, char *buf, uint32 offset, int len, int *count, int *eof);
+nfsstat3 nfsio_read(struct nfsio *nfsio, const char *name, char *buf, uint64_t offset, int len, int *count, int *eof);
 nfsstat3 nfsio_fsinfo(struct nfsio *nfsio);
 nfsstat3 nfsio_fsstat(struct nfsio *nfsio);
 nfsstat3 nfsio_pathconf(struct nfsio *nfsio, char *name);
index bbb02e1f81761f7900de04152bc651ce817b237e..0dd21d7a92b437993c2ac778b027a0de1fec6734 100644 (file)
@@ -1,27 +1,64 @@
+# The READ3 command takes an offset. This can be specified eitehr as an absolute
+# number, but also as a simple expression for generation of random I/O
+#
+# Offset is then a string starting with a '*' followed by one or more
+# qualifier :
+# '*'    : Random 64 bit integer
+# '/yyy' : align the number to yyy. This is the same as x = (x/y)*y
+# '%yyy' : modulo yyy. This si teh same as x = x%y
+# '+yyy' : Add y
+#
+# Examples :
+# '*'         A random offset between 0 and 2**64-1
+# '*/0x1000'  A random offset aligned to a page boundary (4096)
+# '*/0x1000%5000000' A random offset between 0 and 500000 aligned to page
+#                    boundary
+#
+# '*%100+25'  A random offset between 25 and 124
+#
+#
+#
+#
 # DELTREE if we want to delete the client directory everytime we restart 
 # the script. Remove these two lines if the script is only "read-only"
 # reading from pre-existing files in the /clients/clientX/ tree
 0.000 Deltree "/clients/client1" 0x00000000
 #
+#
+#
 # Make sure these directories exist. We specify * as the status code
 # since these directories might already exist and in which case
 # we dont care that the command returned an error.
+#
+#
+# MKDIR3 <path> <status>
 0.000 MKDIR3 "/clients" *
 0.000 MKDIR3 "/clients/client1" *
 #
+#
+#
 # This lookup must be performed to pre-load the name to filehandle cache.
 # Othervise we will get errors like this :
 #     failed to fetch handle in nfsio_read
 #
+# LOOKUP3 <path> <status>
 0.000 LOOKUP3 "/clients/client1" 0x00000000
 #
+#
+#
 # Here is where the script starts
 #
+# GETATTR3 <path> <status>
 0.010 GETATTR3 "/clients/client1" 0x00000000
 0.020 GETATTR3 "/clients/client1" 0x00000000
 0.030 GETATTR3 "/clients/client1" 0x00000000
 0.040 CREATE3  "/clients/client1/test.file" 0x00000000
 0.050 CREATE3  "/clients/client1/tmp.file" 0x00000000
+#
+#
+#
+# WRITE3 <path> <offset> <size> <status>
+#
 # second last argument to WRITE is the "stable' field.
 #  0 : UNSTABLE (default for NFS)
 #  1 : DATA STABLE
 1.010 WRITE3 "/clients/client1/test.file" 1024 1024 0 0x00000000
 1.020 WRITE3 "/clients/client1/test.file" 2048 2048 0 0x00000000
 1.030 COMMIT3 "/clients/client1/test.file" 0x00000000
+#
+#
+#
+# READ <path> <offset> <size> <status>
 1.040 READ3 "/clients/client1/test.file" 2048 2048 0x00000000
+#
+#
+#
+#
 1.050 LOOKUP3 "/clients/client1/test.file" 0x00000000
 1.060 LINK3 "/clients/client1/hard.link" "/clients/client1/test.file" 0x00000000
 1.070 REMOVE3 "/clients/client1/hard.link" 0x00000000
diff --git a/nfsio.c b/nfsio.c
index af34c09eb09ac7a232cbd12105a42f0da17bbad8..4c6e50f41979956cabbf621b5a6191a7373c5d4d 100644 (file)
--- a/nfsio.c
+++ b/nfsio.c
@@ -15,6 +15,8 @@
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
+#define _FILE_OFFSET_BITS 64
+
 #define _GNU_SOURCE
 #include <stdio.h>
 #undef _GNU_SOURCE
@@ -217,7 +219,7 @@ static void nfs3_create(struct dbench_op *op)
 
 static void nfs3_write(struct dbench_op *op)
 {
-       int offset = op->params[0];
+       off_t offset = op->params[0];
        int len = op->params[1];
        int stable = op->params[2];
        nfsstat3 res;
@@ -251,7 +253,7 @@ static void nfs3_commit(struct dbench_op *op)
 
 static void nfs3_read(struct dbench_op *op)
 {
-       int offset = op->params[0];
+       off_t offset = op->params[0];
        int len = op->params[1];
        nfsstat3 res = 0;