summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/utils/locktest.c112
1 files changed, 81 insertions, 31 deletions
diff --git a/source3/utils/locktest.c b/source3/utils/locktest.c
index 9396bd8447..2e5a4fb65b 100644
--- a/source3/utils/locktest.c
+++ b/source3/utils/locktest.c
@@ -37,19 +37,36 @@ static BOOL analyze;
#define READ_PCT 50
#define LOCK_PCT 25
#define UNLOCK_PCT 65
+#define RANGE_MULTIPLE 1
struct record {
- int r1, r2;
- int conn, f;
+ char r1, r2;
+ char conn, f;
int start, len;
- BOOL needed;
+ char needed;
};
static struct record preset[] = {
+#if 1
+{36, 5, 1, 1, 1, 2, 1},
+{ 2, 6, 0, 1, 0, 2, 1},
+{53, 92, 1, 1, 0, 0, 1},
+{99, 11, 1, 1, 2, 1, 1},
+#endif
};
static struct record *recorded;
+static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
+ enum brl_type lock_type,
+ br_off start, br_off size)
+{
+ printf("%6d %05x:%05x %s %9.0f %9.0f\n",
+ (int)pid, (int)dev, (int)ino,
+ lock_type==READ_LOCK?"R":"W",
+ (double)start, (double)size);
+}
+
/*****************************************************
return a connection to a server
*******************************************************/
@@ -61,6 +78,8 @@ struct cli_state *connect_one(char *share)
fstring server;
struct in_addr ip;
extern struct in_addr ipzero;
+ fstring myname;
+ static int count;
fstrcpy(server,share+2);
share = strchr(server,'\\');
@@ -72,7 +91,9 @@ struct cli_state *connect_one(char *share)
ip = ipzero;
- make_nmb_name(&calling, "locktest", 0x0);
+ slprintf(myname,sizeof(myname), "lock-%d-%d", getpid(), count++);
+
+ make_nmb_name(&calling, myname, 0x0);
make_nmb_name(&called , server, 0x20);
again:
@@ -145,16 +166,23 @@ struct cli_state *connect_one(char *share)
}
-static void reconnect(struct cli_state *cli[2][2], char *share1, char *share2)
+static void reconnect(struct cli_state *cli[2][2], int fnum[2][2][2],
+ char *share1, char *share2)
{
- int server, conn;
+ int server, conn, f;
char *share[2];
share[0] = share1;
share[1] = share2;
+
+
for (server=0;server<2;server++)
for (conn=0;conn<2;conn++) {
if (cli[server][conn]) {
+ for (f=0;f<2;f++) {
+ cli_close(cli[server][conn], fnum[server][conn][f]);
+ }
+ cli_ulogoff(cli[server][conn]);
cli_shutdown(cli[server][conn]);
free(cli[server][conn]);
cli[server][conn] = NULL;
@@ -201,6 +229,7 @@ static BOOL test_one(struct cli_state *cli[2][2],
conn, f, start, len, op==READ_LOCK?"READ_LOCK":"WRITE_LOCK",
ret1, ret2);
}
+ if (showall) brl_forall(print_brl);
if (ret1 != ret2) return False;
} else if (r2 < LOCK_PCT+UNLOCK_PCT) {
/* unset a lock */
@@ -215,6 +244,7 @@ static BOOL test_one(struct cli_state *cli[2][2],
conn, f, start, len,
ret1, ret2);
}
+ if (showall) brl_forall(print_brl);
if (ret1 != ret2) return False;
} else {
/* reopen the file */
@@ -237,12 +267,13 @@ static BOOL test_one(struct cli_state *cli[2][2],
if (showall) {
printf("reopen conn=%d f=%d\n",
conn, f);
+ brl_forall(print_brl);
}
}
return True;
}
-static void open_files(struct cli_state *cli[2][2],
+static void close_files(struct cli_state *cli[2][2],
int fnum[2][2][2])
{
int server, conn, f;
@@ -252,7 +283,21 @@ static void open_files(struct cli_state *cli[2][2],
for (f=0;f<2;f++) {
if (fnum[server][conn][f] != -1) {
cli_close(cli[server][conn], fnum[server][conn][f]);
+ fnum[server][conn][f] = -1;
}
+ }
+ cli_unlink(cli[0][0], FILENAME);
+ cli_unlink(cli[1][0], FILENAME);
+}
+
+static void open_files(struct cli_state *cli[2][2],
+ int fnum[2][2][2])
+{
+ int server, conn, f;
+
+ for (server=0;server<2;server++)
+ for (conn=0;conn<2;conn++)
+ for (f=0;f<2;f++) {
fnum[server][conn][f] = cli_open(cli[server][conn], FILENAME,
O_RDWR|O_CREAT,
DENY_NONE);
@@ -270,15 +315,14 @@ static int retest(struct cli_state *cli[2][2],
int n)
{
int i;
- printf("retesting %d ...\n", n);
- open_files(cli, fnum);
+ printf("testing %d ...\n", n);
for (i=0; i<n; i++) {
- if (recorded[i].needed &&
- !test_one(cli, fnum, &recorded[i])) return i;
-
- if (i % 100 == 0) {
+ if (i && i % 100 == 0) {
printf("%d\n", i);
}
+
+ if (recorded[i].needed &&
+ !test_one(cli, fnum, &recorded[i])) return i;
}
return n;
}
@@ -299,11 +343,6 @@ static void test_locks(char *share1, char *share2)
ZERO_STRUCT(fnum);
ZERO_STRUCT(cli);
- reconnect(cli, share1, share2);
- cli_unlink(cli[0][0], FILENAME);
- cli_unlink(cli[1][0], FILENAME);
- open_files(cli, fnum);
-
recorded = (struct record *)malloc(sizeof(*recorded) * numops);
for (n=0; n<numops; n++) {
@@ -314,34 +353,35 @@ static void test_locks(char *share1, char *share2)
recorded[n].f = random() % 2;
recorded[n].start = random() % (LOCKRANGE-1);
recorded[n].len = 1 + random() % (LOCKRANGE-recorded[n].start);
+ recorded[n].start *= RANGE_MULTIPLE;
+ recorded[n].len *= RANGE_MULTIPLE;
recorded[n].r1 = random() % 100;
recorded[n].r2 = random() % 100;
recorded[n].needed = True;
}
-
- if (!test_one(cli, fnum, &recorded[n])) break;
-
- if (n % 100 == 0) {
- printf("%d\n", n);
- }
}
- if (n == numops || !analyze) return;
+ reconnect(cli, fnum, share1, share2);
+ open_files(cli, fnum);
+ n = retest(cli, fnum, numops);
+ if (n == numops || !analyze) return;
n++;
-
while (1) {
n1 = n;
- reconnect(cli, share1, share2);
- cli_unlink(cli[0][0], FILENAME);
- cli_unlink(cli[1][0], FILENAME);
+ close_files(cli, fnum);
+ reconnect(cli, fnum, share1, share2);
open_files(cli, fnum);
- for (i=0;i<n;i++) {
+ for (i=0;i<n-1;i++) {
int m;
recorded[i].needed = False;
+
+ close_files(cli, fnum);
+ open_files(cli, fnum);
+
m = retest(cli, fnum, n);
if (m == n) {
recorded[i].needed = True;
@@ -358,6 +398,16 @@ static void test_locks(char *share1, char *share2)
if (n1 == n) break;
}
+ close_files(cli, fnum);
+ reconnect(cli, fnum, share1, share2);
+ open_files(cli, fnum);
+ showall = True;
+ n1 = retest(cli, fnum, n);
+ if (n1 != n-1) {
+ printf("ERROR - inconsistent result (%d %d)\n", n1, n);
+ }
+ close_files(cli, fnum);
+
for (i=0;i<n;i++) {
printf("{%d, %d, %d, %d, %d, %d, %d},\n",
recorded[i].r1,
@@ -368,7 +418,6 @@ static void test_locks(char *share1, char *share2)
recorded[i].len,
recorded[i].needed);
}
-
}
@@ -470,6 +519,7 @@ static void usage(void)
DEBUG(0,("seed=%d\n", seed));
srandom(seed);
+ locking_init(1);
test_locks(share1, share2);
return(0);