r23531: added optional latency reporting in BENCH-NBENCH. To use it, you need
[samba.git] / source / torture / nbench / nbio.c
index c5cebdc8d26f3065ac479bc6e80ed0b163d42e7c..a382c92ceb9ed2da5cb7caa0ccc01be3edceb554 100644 (file)
@@ -1,4 +1,7 @@
-#define NBDEBUG 0
+/*
+  TODO: add splitting of writes for servers with signing
+*/
+
 
 /* 
    Unix SMB/CIFS implementation.
 #include "includes.h"
 #include "system/time.h"
 #include "system/filesys.h"
-#include "dlinklist.h"
+#include "lib/util/dlinklist.h"
 #include "libcli/libcli.h"
 #include "libcli/raw/libcliraw.h"
 #include "torture/torture.h"
-
-#define MAX_FILES 100
+#include "libcli/libcli.h"
+#include "torture/util.h"
 
 extern int nbench_line_count;
 static int nbio_id = -1;
@@ -50,8 +53,25 @@ static struct {
        double bytes, warmup_bytes;
        int line;
        int done;
+       double max_latency;
+       struct timeval starttime;
 } *children;
 
+void nbio_time_reset(void)
+{
+       children[nbio_id].starttime = timeval_current();        
+}
+
+void nbio_time_delay(double targett)
+{
+       double elapsed = timeval_elapsed(&children[nbio_id].starttime);
+       if (targett > elapsed) {
+               msleep(1000*(targett - elapsed));
+       } else if (elapsed - targett > children[nbio_id].max_latency) {
+               children[nbio_id].max_latency = elapsed - targett;
+       }
+}
+
 double nbio_result(void)
 {
        int i;
@@ -62,6 +82,19 @@ double nbio_result(void)
        return 1.0e-6 * total / timeval_elapsed2(&tv_start, &tv_end);
 }
 
+double nbio_latency(void)
+{
+       int i;
+       double max_latency = 0;
+       for (i=0;i<nprocs;i++) {
+               if (children[i].max_latency > max_latency) {
+                       max_latency = children[i].max_latency;
+                       children[i].max_latency = 0;
+               }
+       }
+       return max_latency;
+}
+
 BOOL nb_tick(void)
 {
        return children[nbio_id].done;
@@ -119,9 +152,9 @@ void nb_alarm(int sig)
                       nprocs, lines/nprocs, 
                       nbio_result(), t);
        } else {
-               printf("%4d  %8d  %.2f MB/sec  execute %.0f sec   \n", 
+               printf("%4d  %8d  %.2f MB/sec  execute %.0f sec  latency %.2f msec \n", 
                       nprocs, lines/nprocs, 
-                      nbio_result(), t);
+                      nbio_result(), t, nbio_latency() * 1.0e3);
        }
 
        fflush(stdout);
@@ -179,10 +212,11 @@ static struct smbcli_state *c;
 /*
   a handler function for oplock break requests
 */
-static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *private)
+static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, 
+                          uint16_t fnum, uint8_t level, void *private)
 {
        struct smbcli_tree *tree = private;
-       return smbcli_oplock_ack(tree, fnum, level);
+       return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
 }
 
 void nb_setup(struct smbcli_state *cli, int id)
@@ -286,12 +320,12 @@ void nb_createx(const char *fname,
 
        f = malloc_p(struct ftable);
        f->handle = handle;
-       f->fd = io.ntcreatex.file.fnum;
+       f->fd = io.ntcreatex.out.file.fnum;
 
        DLIST_ADD_END(ftable, f, struct ftable *);
 }
 
-void nb_writex(int handle, int offset, int size, int ret_size, NTSTATUS status)
+void nb_writex(int handle, off_t offset, int size, int ret_size, NTSTATUS status)
 {
        union smb_write io;
        int i;
@@ -306,7 +340,7 @@ void nb_writex(int handle, int offset, int size, int ret_size, NTSTATUS status)
        memset(buf, 0xab, size);
 
        io.writex.level = RAW_WRITE_WRITEX;
-       io.writex.file.fnum = i;
+       io.writex.in.file.fnum = i;
        io.writex.in.wmode = 0;
        io.writex.in.remaining = 0;
        io.writex.in.offset = offset;
@@ -328,7 +362,7 @@ void nb_writex(int handle, int offset, int size, int ret_size, NTSTATUS status)
        children[nbio_id].bytes += ret_size;
 }
 
-void nb_write(int handle, int offset, int size, int ret_size, NTSTATUS status)
+void nb_write(int handle, off_t offset, int size, int ret_size, NTSTATUS status)
 {
        union smb_write io;
        int i;
@@ -344,7 +378,7 @@ void nb_write(int handle, int offset, int size, int ret_size, NTSTATUS status)
        memset(buf, 0x12, size);
 
        io.write.level = RAW_WRITE_WRITE;
-       io.write.file.fnum = i;
+       io.write.in.file.fnum = i;
        io.write.in.remaining = 0;
        io.write.in.offset = offset;
        io.write.in.count = size;
@@ -366,7 +400,7 @@ void nb_write(int handle, int offset, int size, int ret_size, NTSTATUS status)
 }
 
 
-void nb_lockx(int handle, uint_t offset, int size, NTSTATUS status)
+void nb_lockx(int handle, off_t offset, int size, NTSTATUS status)
 {
        union smb_lock io;
        int i;
@@ -380,7 +414,7 @@ void nb_lockx(int handle, uint_t offset, int size, NTSTATUS status)
        lck.count = size;
 
        io.lockx.level = RAW_LOCK_LOCKX;
-       io.lockx.file.fnum = i;
+       io.lockx.in.file.fnum = i;
        io.lockx.in.mode = 0;
        io.lockx.in.timeout = 0;
        io.lockx.in.ulock_cnt = 0;
@@ -406,7 +440,7 @@ void nb_unlockx(int handle, uint_t offset, int size, NTSTATUS status)
        lck.count = size;
 
        io.lockx.level = RAW_LOCK_LOCKX;
-       io.lockx.file.fnum = i;
+       io.lockx.in.file.fnum = i;
        io.lockx.in.mode = 0;
        io.lockx.in.timeout = 0;
        io.lockx.in.ulock_cnt = 1;
@@ -418,7 +452,7 @@ void nb_unlockx(int handle, uint_t offset, int size, NTSTATUS status)
        check_status("UnlockX", status, ret);
 }
 
-void nb_readx(int handle, int offset, int size, int ret_size, NTSTATUS status)
+void nb_readx(int handle, off_t offset, int size, int ret_size, NTSTATUS status)
 {
        union smb_read io;
        int i;
@@ -432,13 +466,14 @@ void nb_readx(int handle, int offset, int size, int ret_size, NTSTATUS status)
        buf = malloc(size);
 
        io.readx.level = RAW_READ_READX;
-       io.readx.file.fnum = i;
+       io.readx.in.file.fnum = i;
        io.readx.in.offset    = offset;
        io.readx.in.mincnt    = size;
        io.readx.in.maxcnt    = size;
        io.readx.in.remaining = 0;
+       io.readx.in.read_for_execute = False;
        io.readx.out.data     = buf;
-               
+       
        ret = smb_raw_read(c->tree, &io);
 
        free(buf);
@@ -464,7 +499,7 @@ void nb_close(int handle, NTSTATUS status)
        i = find_handle(handle);
 
        io.close.level = RAW_CLOSE_CLOSE;
-       io.close.file.fnum = i;
+       io.close.in.file.fnum = i;
        io.close.in.write_time = 0;
 
        ret = smb_raw_close(c->tree, &io);
@@ -526,7 +561,7 @@ void nb_qpathinfo(const char *fname, int level, NTSTATUS status)
        mem_ctx = talloc_init("nb_qpathinfo");
 
        io.generic.level = level;
-       io.generic.file.path = fname;
+       io.generic.in.file.path = fname;
 
        ret = smb_raw_pathinfo(c->tree, mem_ctx, &io);
 
@@ -548,7 +583,7 @@ void nb_qfileinfo(int fnum, int level, NTSTATUS status)
        mem_ctx = talloc_init("nb_qfileinfo");
 
        io.generic.level = level;
-       io.generic.file.fnum = i;
+       io.generic.in.file.fnum = i;
 
        ret = smb_raw_fileinfo(c->tree, mem_ctx, &io);
 
@@ -573,7 +608,7 @@ void nb_sfileinfo(int fnum, int level, NTSTATUS status)
        i = find_handle(fnum);
 
        io.generic.level = level;
-       io.generic.file.fnum = i;
+       io.generic.in.file.fnum = i;
        unix_to_nt_time(&io.basic_info.in.create_time, time(NULL));
        unix_to_nt_time(&io.basic_info.in.access_time, 0);
        unix_to_nt_time(&io.basic_info.in.write_time, 0);
@@ -602,7 +637,7 @@ void nb_qfsinfo(int level, NTSTATUS status)
 }
 
 /* callback function used for trans2 search */
-static BOOL findfirst_callback(void *private, union smb_search_data *file)
+static BOOL findfirst_callback(void *private, const union smb_search_data *file)
 {
        return True;
 }
@@ -615,7 +650,8 @@ void nb_findfirst(const char *mask, int level, int maxcnt, int count, NTSTATUS s
 
        mem_ctx = talloc_init("smbcli_dskattr");
 
-       io.t2ffirst.level = level;
+       io.t2ffirst.level = RAW_SEARCH_TRANS2;
+       io.t2ffirst.data_level = level;
        io.t2ffirst.in.max_count = maxcnt;
        io.t2ffirst.in.search_attrib = FILE_ATTRIBUTE_DIRECTORY;
        io.t2ffirst.in.pattern = mask;
@@ -642,7 +678,8 @@ void nb_flush(int fnum, NTSTATUS status)
        int i;
        i = find_handle(fnum);
 
-       io.flush.file.fnum = i;
+       io.flush.level          = RAW_FLUSH_FLUSH;
+       io.flush.in.file.fnum   = i;
 
        ret = smb_raw_flush(c->tree, &io);