r23531: added optional latency reporting in BENCH-NBENCH. To use it, you need
[samba.git] / source / torture / nbench / nbio.c
index 32bd108442a10bc0a61b502fcf4e8bd9410ab478..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 "dlinklist.h"
-#include "librpc/gen_ndr/ndr_security.h"
-
-#define MAX_FILES 100
+#include "system/filesys.h"
+#include "lib/util/dlinklist.h"
+#include "libcli/libcli.h"
+#include "libcli/raw/libcliraw.h"
+#include "torture/torture.h"
+#include "libcli/libcli.h"
+#include "torture/util.h"
 
 extern int nbench_line_count;
 static int nbio_id = -1;
@@ -47,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;
@@ -59,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;
@@ -116,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);
@@ -176,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)
@@ -218,14 +255,14 @@ static void check_status(const char *op, NTSTATUS status, NTSTATUS ret)
 
 void nb_unlink(const char *fname, int attr, NTSTATUS status)
 {
-       struct smb_unlink io;
+       union smb_unlink io;
        NTSTATUS ret;
 
-       io.in.pattern = fname;
+       io.unlink.in.pattern = fname;
 
-       io.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
+       io.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
        if (strchr(fname, '*') == 0) {
-               io.in.attrib |= FILE_ATTRIBUTE_DIRECTORY;
+               io.unlink.in.attrib |= FILE_ATTRIBUTE_DIRECTORY;
        }
 
        ret = smb_raw_unlink(c->tree, &io);
@@ -275,7 +312,7 @@ void nb_createx(const char *fname,
 
        ret = smb_raw_open(c->tree, mem_ctx, &io);
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
        check_status("NTCreateX", status, ret);
 
@@ -283,17 +320,17 @@ void nb_createx(const char *fname,
 
        f = malloc_p(struct ftable);
        f->handle = handle;
-       f->fd = io.ntcreatex.out.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;
        NTSTATUS ret;
-       char *buf;
+       uint8_t *buf;
 
        i = find_handle(handle);
 
@@ -303,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.in.fnum = i;
+       io.writex.in.file.fnum = i;
        io.writex.in.wmode = 0;
        io.writex.in.remaining = 0;
        io.writex.in.offset = offset;
@@ -325,12 +362,12 @@ 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;
        NTSTATUS ret;
-       char *buf;
+       uint8_t *buf;
 
        i = find_handle(handle);
 
@@ -341,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.in.fnum = i;
+       io.write.in.file.fnum = i;
        io.write.in.remaining = 0;
        io.write.in.offset = offset;
        io.write.in.count = size;
@@ -363,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;
@@ -377,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.in.fnum = i;
+       io.lockx.in.file.fnum = i;
        io.lockx.in.mode = 0;
        io.lockx.in.timeout = 0;
        io.lockx.in.ulock_cnt = 0;
@@ -403,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.in.fnum = i;
+       io.lockx.in.file.fnum = i;
        io.lockx.in.mode = 0;
        io.lockx.in.timeout = 0;
        io.lockx.in.ulock_cnt = 1;
@@ -415,12 +452,12 @@ 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;
        NTSTATUS ret;
-       char *buf;
+       uint8_t *buf;
 
        i = find_handle(handle);
 
@@ -429,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.in.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);
@@ -461,7 +499,7 @@ void nb_close(int handle, NTSTATUS status)
        i = find_handle(handle);
 
        io.close.level = RAW_CLOSE_CLOSE;
-       io.close.in.fnum = i;
+       io.close.in.file.fnum = i;
        io.close.in.write_time = 0;
 
        ret = smb_raw_close(c->tree, &io);
@@ -523,11 +561,11 @@ void nb_qpathinfo(const char *fname, int level, NTSTATUS status)
        mem_ctx = talloc_init("nb_qpathinfo");
 
        io.generic.level = level;
-       io.generic.in.fname = fname;
+       io.generic.in.file.path = fname;
 
        ret = smb_raw_pathinfo(c->tree, mem_ctx, &io);
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
        check_status("Pathinfo", status, ret);
 }
@@ -545,11 +583,11 @@ void nb_qfileinfo(int fnum, int level, NTSTATUS status)
        mem_ctx = talloc_init("nb_qfileinfo");
 
        io.generic.level = level;
-       io.generic.in.fnum = i;
+       io.generic.in.file.fnum = i;
 
        ret = smb_raw_fileinfo(c->tree, mem_ctx, &io);
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
        check_status("Fileinfo", status, ret);
 }
@@ -570,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);
@@ -593,13 +631,13 @@ void nb_qfsinfo(int level, NTSTATUS status)
        io.generic.level = level;
        ret = smb_raw_fsinfo(c->tree, mem_ctx, &io);
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
        
        check_status("Fsinfo", status, ret);    
 }
 
 /* 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;
 }
@@ -612,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;
@@ -621,7 +660,7 @@ void nb_findfirst(const char *mask, int level, int maxcnt, int count, NTSTATUS s
                        
        ret = smb_raw_search_first(c->tree, mem_ctx, &io, NULL, findfirst_callback);
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
        check_status("Search", status, ret);
 
@@ -634,12 +673,13 @@ void nb_findfirst(const char *mask, int level, int maxcnt, int count, NTSTATUS s
 
 void nb_flush(int fnum, NTSTATUS status)
 {
-       struct smb_flush io;
+       union smb_flush io;
        NTSTATUS ret;
        int i;
        i = find_handle(fnum);
 
-       io.in.fnum = i;
+       io.flush.level          = RAW_FLUSH_FLUSH;
+       io.flush.in.file.fnum   = i;
 
        ret = smb_raw_flush(c->tree, &io);
 
@@ -648,8 +688,7 @@ void nb_flush(int fnum, NTSTATUS status)
 
 void nb_sleep(int usec, NTSTATUS status)
 {
-       (void)status;
-       sys_usleep(usec);
+       usleep(usec);
 }
 
 void nb_deltree(const char *dname)