[dbench @ tridge@samba.org-20070717084152-smtpps3ihfko3s16]
authorAndrew Tridgell <tridge@samba.org>
Tue, 17 Jul 2007 08:41:52 +0000 (18:41 +1000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 17 Jul 2007 08:41:52 +0000 (18:41 +1000)
- fixed deltree
- added per operation reporting

child.c
dbench.c
dbench.h
fileio.c

diff --git a/child.c b/child.c
index a943537d017dde8d16efaf2638f2e8335a116e6f..5a399c8c9ba6f05b35786d1c463f35ebee8c693b 100644 (file)
--- a/child.c
+++ b/child.c
@@ -70,6 +70,17 @@ static void nb_time_delay(struct child_struct *child, double targett)
        }
 }
 
+static void finish_op(struct child_struct *child, struct op *op)
+{
+       double t = timeval_elapsed(&child->lasttime);
+       op->count++;
+       op->total_time += t;
+       if (t > op->max_latency) {
+               op->max_latency = t;
+       }
+}
+
+#define OP_LATENCY(opname) finish_op(child, &child->op.op_ ## opname)
 
 /*
   one child operation
@@ -77,48 +88,67 @@ static void nb_time_delay(struct child_struct *child, double targett)
 static void child_op(struct child_struct *child, char **params, 
                     const char *fname, const char *fname2, const char *status)
 {
+       child->lasttime = timeval_current();
+
        if (!strcmp(params[0],"NTCreateX")) {
                nb_createx(child, fname, ival(params[2]), ival(params[3]), 
                           ival(params[4]), status);
+               OP_LATENCY(NTCreateX);
        } else if (!strcmp(params[0],"Close")) {
                nb_close(child, ival(params[1]), status);
+               OP_LATENCY(Close);
        } else if (!strcmp(params[0],"Rename")) {
                nb_rename(child, fname, fname2, status);
+               OP_LATENCY(Rename);
        } else if (!strcmp(params[0],"Unlink")) {
                nb_unlink(child, fname, ival(params[2]), status);
+               OP_LATENCY(Unlink);
        } else if (!strcmp(params[0],"Deltree")) {
                nb_deltree(child, fname);
+               OP_LATENCY(Deltree);
        } else if (!strcmp(params[0],"Rmdir")) {
                nb_rmdir(child, fname, status);
+               OP_LATENCY(Rmdir);
        } else if (!strcmp(params[0],"Mkdir")) {
                nb_mkdir(child, fname, status);
+               OP_LATENCY(Mkdir);
        } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
                nb_qpathinfo(child, fname, ival(params[2]), status);
+               OP_LATENCY(Qpathinfo);
        } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
                nb_qfileinfo(child, ival(params[1]), ival(params[2]), status);
+               OP_LATENCY(Qfileinfo);
        } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
                nb_qfsinfo(child, ival(params[1]), status);
+               OP_LATENCY(Qfsinfo);
        } else if (!strcmp(params[0],"SET_FILE_INFORMATION")) {
                nb_sfileinfo(child, ival(params[1]), ival(params[2]), status);
+               OP_LATENCY(Sfileinfo);
        } else if (!strcmp(params[0],"FIND_FIRST")) {
                nb_findfirst(child, fname, ival(params[2]), 
                             ival(params[3]), ival(params[4]), status);
+               OP_LATENCY(Find);
        } else if (!strcmp(params[0],"WriteX")) {
                nb_writex(child, ival(params[1]), 
                          ival(params[2]), ival(params[3]), ival(params[4]),
                          status);
+               OP_LATENCY(WriteX);
        } else if (!strcmp(params[0],"LockX")) {
                nb_lockx(child, ival(params[1]), 
                         ival(params[2]), ival(params[3]), status);
+               OP_LATENCY(LockX);
        } else if (!strcmp(params[0],"UnlockX")) {
                nb_unlockx(child, ival(params[1]), 
                           ival(params[2]), ival(params[3]), status);
+               OP_LATENCY(UnlockX);
        } else if (!strcmp(params[0],"ReadX")) {
                nb_readx(child, ival(params[1]), 
                         ival(params[2]), ival(params[3]), ival(params[4]),
                         status);
+               OP_LATENCY(ReadX);
        } else if (!strcmp(params[0],"Flush")) {
                nb_flush(child, ival(params[1]), status);
+               OP_LATENCY(Flush);
        } else if (!strcmp(params[0],"Sleep")) {
                nb_sleep(child, ival(params[1]), status);
        } else {
@@ -227,8 +257,6 @@ again:
                        } else {
                                nb_time_delay(child, targett);
                        }
-                       child->lasttime = timeval_current();
-
                        child_op(child, params, fname, fname2, status);
                }
        }
index d15fa7a9c18eb954f1521bf19d22d3a4bd4b9946..2649ee2c5c76ed12fbd94f39b390b671931061be 100644 (file)
--- a/dbench.c
+++ b/dbench.c
@@ -83,7 +83,6 @@ static void sig_alarm(int sig)
        struct timeval tnow;
        int num_active = 0;
        int num_finished = 0;
-
        (void)sig;
 
        tnow = timeval_current();
@@ -156,6 +155,62 @@ next:
        alarm(PRINT_FREQ);
 }
 
+
+static const struct {
+       const char *name;
+       size_t offset;
+} op_names[] = {
+#define OP_NAME(opname) { #opname, offsetof(struct opnames, op_ ## opname) }
+       OP_NAME(NTCreateX),
+       OP_NAME(Close),
+       OP_NAME(Rename),
+       OP_NAME(Unlink),
+       OP_NAME(Deltree),
+       OP_NAME(Rmdir),
+       OP_NAME(Mkdir),
+       OP_NAME(Qpathinfo),
+       OP_NAME(Qfileinfo),
+       OP_NAME(Qfsinfo),
+       OP_NAME(Sfileinfo),
+       OP_NAME(Find),
+       OP_NAME(WriteX),
+       OP_NAME(ReadX),
+       OP_NAME(LockX),
+       OP_NAME(UnlockX),
+       OP_NAME(Flush),
+};
+
+static void report_latencies(void)
+{
+       struct opnames sum;
+       int i, j, n = (sizeof(op_names)/sizeof(op_names[0]));
+       struct op *op1, *op2;
+       struct child_struct *child;
+
+       memset(&sum, 0, sizeof(sum));
+       for (i=0;i<n;i++) {
+               op1 = (struct op *)(op_names[i].offset + (char *)&sum);
+               for (j=0;j<options.nprocs * options.clients_per_process;j++) {
+                       child = &children[j];
+                       op2 = (struct op *)(op_names[i].offset + (char *)&child->op);
+                       op1->count += op2->count;
+                       op1->total_time += op2->total_time;
+                       op1->max_latency = MAX(op1->max_latency, op2->max_latency);
+               }
+       }
+       printf(" Operation      Count    AvgLat    MaxLat\n");
+       printf(" ----------------------------------------\n");
+       for (i=0;i<n;i++) {
+               op1 = (struct op *)(op_names[i].offset + (char *)&sum);
+               if (op1->count == 0) continue;
+               printf(" %-12s %7u %9.03f %9.03f\n",
+                      op_names[i].name, op1->count, 
+                      1000*op1->total_time/op1->count,
+                      op1->max_latency*1000);
+       }
+       printf("\n");
+}
+
 /* this creates the specified number of child processes and runs fn()
    in all of them */
 static void create_procs(int nprocs, void (*fn)(struct child_struct *, const char *))
@@ -277,6 +332,8 @@ static void create_procs(int nprocs, void (*fn)(struct child_struct *, const cha
        sig_alarm(SIGALRM);
 
        printf("\n");
+
+       report_latencies();
 }
 
 
index 4e6d7e8524c62d3ab60f698e7ff2b46ec496b2ff..71578e5ee4a1ef3b71f05673f814e6649f1be94a 100644 (file)
--- a/dbench.h
+++ b/dbench.h
@@ -19,6 +19,7 @@
 #include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <stddef.h>
 #include <signal.h>
 #include <unistd.h>
 #include <string.h>
 #define False 0
 #define uint32 unsigned
 
+struct op {
+       unsigned count;
+       double total_time;
+       double max_latency;
+};
+
 struct child_struct {
        int id;
        int failed;
@@ -111,6 +118,25 @@ struct child_struct {
                double last_bytes;
                struct timeval last_time;
        } rate;
+       struct opnames {
+               struct op op_NTCreateX;
+               struct op op_Close;
+               struct op op_Rename;
+               struct op op_Unlink;
+               struct op op_Deltree;
+               struct op op_Rmdir;
+               struct op op_Mkdir;
+               struct op op_Qpathinfo;
+               struct op op_Qfileinfo;
+               struct op op_Qfsinfo;
+               struct op op_Sfileinfo;
+               struct op op_Find;
+               struct op op_WriteX;
+               struct op op_ReadX;
+               struct op op_LockX;
+               struct op op_UnlockX;
+               struct op op_Flush;
+       } op;
        void *private;
 };
 
index 838bf6a90f5bd0e10aa971af3c39c16e23b75322..041493b58b88aede5fb2824934406ffcb40634ea 100644 (file)
--- a/fileio.c
+++ b/fileio.c
@@ -155,6 +155,8 @@ static void resolve_name(const char *name)
        char *p;
        struct dirent *d;
 
+       return;
+
        if (name == NULL) return;
 
        if (stat(name, &st) == 0) {
@@ -463,11 +465,39 @@ void nb_cleanup(struct child_struct *child)
 
 void nb_deltree(struct child_struct *child, const char *dname)
 {
-       char *path;
+       DIR *d;
+       struct dirent *de;
        (void)child;
-       asprintf(&path, "/bin/rm -rf %s", dname);
-       system(path);
-       free(path);
+       
+       d = opendir(dname);
+       if (d == NULL) return;
+
+       for (de=readdir(d);de;de=readdir(d)) {
+               struct stat st;
+               char *fname = NULL;
+               if (strcmp(de->d_name, ".") == 0 ||
+                   strcmp(de->d_name, "..") == 0) {
+                       continue;
+               }
+               asprintf(&fname, "%s/%s", dname, de->d_name);
+               if (fname == NULL) {
+                       printf("Out of memory\n");
+                       exit(1);
+               }
+               if (stat(fname, &st) != 0) {
+                       continue;
+               }
+               if (S_ISDIR(st.st_mode)) {
+                       nb_deltree(child, fname);
+               } else {
+                       if (unlink(fname) != 0) {
+                               printf("[%d] unlink '%s' failed - %s\n",
+                                      child->line, fname, strerror(errno));
+                       }
+               }
+               free(fname);
+       }
+       closedir(d);
 }
 
 void nb_sfileinfo(struct child_struct *child, int handle, int level, const char *status)