cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2007-01-04 20:34 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2007-01-04 20:34 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-01-04 20:34:19

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	added "flood n mode" function a while ago, doesn't equate to pjc's
	"flood" program even though that's what I was originally hoping to
	emulate

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.3&r2=1.4

--- cluster/dlm/tests/usertest/dlmtest2.c	2006/12/12 21:17:56	1.3
+++ cluster/dlm/tests/usertest/dlmtest2.c	2007/01/04 20:34:18	1.4
@@ -219,6 +219,69 @@
 	}
 }
 
+void astfn_flood_unlock(void *arg)
+{
+	struct lk *lk = arg;
+	int i = lk->id, unlock = 0, rv;
+
+	if (!lk->wait_ast) {
+		printf("lk %d not waiting for ast\n", lk->id);
+		exit(-1);
+	}
+
+	lk->wait_ast = 0;
+
+	if (lk->lksb.sb_status == EUNLOCK) {
+		memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+		lk->grmode = -1;
+		lk->rqmode = -1;
+		unlock = 1;
+		locks_flood_ast_done++;
+	} else if (lk->lksb.sb_status == EAGAIN) {
+		if (lk->grmode == -1)
+			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+		lk->rqmode = -1;
+	} else {
+		if (lk->lksb.sb_status != 0) {
+			printf("lk %d unknown sb_status %d\n", lk->id,
+				lk->lksb.sb_status);
+			exit(-1);
+		}
+
+		/* lock completed, now unlock it immediately */
+
+		lk->grmode = lk->rqmode;
+		lk->rqmode = -1;
+
+		rv = dlm_ls_unlock(dh, lk->lksb.sb_lkid, 0, &lk->lksb,
+				   (void *)lk);
+		if (!rv) {
+			lk->wait_ast = 1;
+			lk->rqmode = -1;
+		} else {
+			char input[32];
+			printf("astfn_flood_unlock: dlm_ls_unlock: %d rv %d "
+			       "errno %d\n", i, rv, errno);
+			printf("press X to exit, D to dispatch, "
+			       "other to continue\n");
+			fgets(input, 32, stdin);
+			if (input[0] == 'X')
+				exit(-1);
+			else if (input[0] == 'D')
+				dlm_dispatch(libdlm_fd);
+		}
+	}
+
+	if (locks_flood_ast_done == locks_flood_n) {
+		printf("astfn_flood_unlock all %d unlocked\n", locks_flood_n);
+		if (unlock) {
+			free(locks_flood);
+			locks_flood = NULL;
+			locks_flood_n = 0;
+		}
+	}
+}
+
 void process_libdlm(void)
 {
 	dlm_dispatch(libdlm_fd);
@@ -453,6 +516,44 @@
 	}
 }
 
+void flood(int n, int mode)
+{
+	struct lk *lk;
+	char name[DLM_RESNAME_MAXLEN];
+	int flags = 0, rv, i;
+
+	if (noqueue)
+		flags |= LKF_NOQUEUE;
+
+	if (locks_flood) {
+		printf("unlock_flood required first\n");
+		return;
+	}
+
+	locks_flood = malloc(n * sizeof(struct lk));
+	if (!locks_flood) {
+		printf("no mem for %d locks\n", n);
+		return;
+	}
+	locks_flood_n = n;
+	locks_flood_ast_done = 0;
+	memset(locks_flood, 0, sizeof(*locks_flood));
+
+	for (i = 0; i < n; i++) {
+		memset(name, 0, sizeof(name));
+		snprintf(name, sizeof(name), "testflood%d", i);
+		lk = &locks_flood[i];
+
+		rv = dlm_ls_lock(dh, mode, &lk->lksb, flags,
+			 name, strlen(name), 0, astfn_flood_unlock, (void *) lk,
+			 bastfn_flood, NULL);
+		if (!rv) {
+			lk->wait_ast = 1;
+			lk->rqmode = mode;
+		}
+	}
+}
+
 void loop(int i, int num)
 {
 	int n;
@@ -598,6 +699,11 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "flood", 5)) {
+		flood(x, y);
+		return;
+	}
+
 	if (!strncmp(cmd, "hold", 4)) {
 		lock_all(LKM_PRMODE);
 		return;
@@ -650,6 +756,7 @@
 		printf("unlock_flood-kill - unlock all from lock_flood and exit\n");
 		printf("ex x		 - equivalent to: lock x 5\n");
 		printf("pr x		 - equivalent to: lock x 3\n");
+		printf("flood n mode     - request n locks, unlock each as it completes\n");
 		printf("hold		 - for x in 0 to MAX, lock x 3\n");
 		printf("release		 - for x in 0 to MAX, unlock x\n");
 		printf("dump		 - show info for all resources\n");



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2008-02-21 17:49 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2008-02-21 17:49 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2008-02-21 17:49:16

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	updates

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.11&r2=1.12

--- cluster/dlm/tests/usertest/dlmtest2.c	2008/01/17 21:49:00	1.11
+++ cluster/dlm/tests/usertest/dlmtest2.c	2008/02/21 17:49:15	1.12
@@ -61,18 +61,37 @@
 static unsigned int sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain, sts_other, sts_zero;
 static unsigned int bast_unlock, bast_skip;
 
+
 #define log_print(fmt, args...) \
 do { \
 	if (!quiet) \
 		printf(fmt , ##args); \
 } while (0)
 
-#define log_verbose(fmt, args...) \
+#define log_op(fmt, args...) \
+do { \
+	if (!quiet) \
+		printf(fmt , ##args); \
+} while (0)
+
+#define log_ast(fmt, args...) \
 do { \
 	if (verbose) \
 		printf(fmt , ##args); \
 } while (0)
 
+#define log_bast(fmt, args...) \
+do { \
+	if (verbose > 1) \
+		printf(fmt , ##args); \
+} while (0)
+
+#define log_verbose(fmt, args...) \
+do { \
+	if (verbose > 2) \
+		printf(fmt , ##args); \
+} while (0)
+
 struct client {
 	int fd;
 	char type[32];
@@ -220,10 +239,10 @@
 
 	if (skip) {
 		bast_skip++;
-		printf("    bast: skip    %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
+		log_bast("    bast: skip    %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
 	} else {
 		bast_unlock++;
-		printf("    bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
+		log_bast("    bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
 		unlockf(lk->id);
 	}
 	lk->bast = 0;
@@ -261,8 +280,8 @@
 		       op_str(lk->lastop), status_str(lk->last_status));
 	}
 
-	log_print("     ast: %s %3d\t%x\n",
-		  status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid);
+	log_ast("     ast: %s %3d\t%x\n",
+		status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid);
 
 	lk->last_status = lk->lksb.sb_status;
 
@@ -845,7 +864,7 @@
 
 			lock(i, rand_int(0, 5));
 			lock_ops++;
-			printf("%8x: lock    %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			log_op("%8x: lock    %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 
 		case Op_unlock:
@@ -864,7 +883,7 @@
 
 			unlock(i);
 			unlock_ops++;
-			printf("%8x: unlock  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			log_op("%8x: unlock  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 
 		case Op_unlockf:
@@ -879,7 +898,7 @@
 
 			unlockf(i);
 			unlockf_ops++;
-			printf("%8x: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			log_op("%8x: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 
 		case Op_cancel:
@@ -894,7 +913,7 @@
 
 			cancel(i);
 			cancel_ops++;
-			printf("%8x: cancel  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			log_op("%8x: cancel  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 		}
 
@@ -1253,7 +1272,7 @@
 	int optchar;
 
 	while (cont) {
-		optchar = getopt(argc, argv, "n:r:c:i:thVo");
+		optchar = getopt(argc, argv, "n:r:c:i:thVoq:v:");
 
 		switch (optchar) {
 
@@ -1282,6 +1301,14 @@
 			openclose_ls = 1;
 			break;
 
+		case 'q':
+			quiet = atoi(optarg);
+			break;
+
+		case 'v':
+			verbose = atoi(optarg);
+			break;
+
 		case 'h':
 			print_usage();
 			exit(EXIT_SUCCESS);
@@ -1398,7 +1425,7 @@
 
 	client_add(libdlm_fd, &maxi);
 
-	if (opt_cmd) {
+	if (cmd) {
 		process_command(&quit);
 		goto out;
 	}



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2008-01-17 21:49 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2008-01-17 21:49 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2008-01-17 21:49:00

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	odds and ends not commited

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.10&r2=1.11

--- cluster/dlm/tests/usertest/dlmtest2.c	2007/08/23 19:13:54	1.10
+++ cluster/dlm/tests/usertest/dlmtest2.c	2008/01/17 21:49:00	1.11
@@ -21,6 +21,7 @@
 #include <time.h>
 #include <signal.h>
 #include <syslog.h>
+#include <sys/time.h>
 #include <asm/types.h>
 #include <sys/socket.h>
 #include <sys/poll.h>
@@ -54,6 +55,8 @@
 static int stress_lock_only = 0;
 static int openclose_ls = 0;
 static uint64_t our_xid;
+static char cmd[32];
+static int opt_cmd = 0;
 
 static unsigned int sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain, sts_other, sts_zero;
 static unsigned int bast_unlock, bast_skip;
@@ -102,16 +105,16 @@
 
 struct lk *locks;
 
-void unlock(int i);
-void unlockf(int i);
+static void unlock(int i);
+static void unlockf(int i);
 
 
-int rand_int(int a, int b)
+static int rand_int(int a, int b)
 {
 	return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0)); 
 }
 
-char *status_str(int status)
+static char *status_str(int status)
 {
 	static char sts_str[8];
 
@@ -136,7 +139,7 @@
 	}
 }
 
-char *op_str(int op)
+static char *op_str(int op)
 {
 	switch (op) {
 	case Op_lock:
@@ -152,7 +155,7 @@
 	}
 }
 
-struct lk *get_lock(int i)
+static struct lk *get_lock(int i)
 {
 	if (i < 0)
 		return NULL;
@@ -161,7 +164,7 @@
 	return &locks[i];
 }
 
-int all_unlocks_done(void)
+static int all_unlocks_done(void)
 {
 	struct lk *lk;
 	int i;
@@ -175,7 +178,7 @@
 	return 1;
 }
 
-void dump(void)
+static void dump(void)
 {
 	struct timeval now;
 	struct lk *lk;
@@ -193,18 +196,18 @@
 			lk->wait_ast,
 			op_str(lk->lastop),
 			status_str(lk->last_status),
-			lk->wait_ast ? now.tv_sec - lk->begin.tv_sec : 0);
+			lk->wait_ast ? (unsigned int)(now.tv_sec - lk->begin.tv_sec) : 0);
 	}
 }
 
-void bastfn(void *arg)
+static void bastfn(void *arg)
 {
 	struct lk *lk = arg;
 	lk->bast = 1;
 	bast_cb = 1;
 }
 
-void do_bast(struct lk *lk)
+static void do_bast(struct lk *lk)
 {
 	int skip = 0;
 
@@ -226,7 +229,7 @@
 	lk->bast = 0;
 }
 
-void do_bast_unlocks(void)
+static void do_bast_unlocks(void)
 {
 	struct lk *lk;
 	int i;
@@ -239,14 +242,14 @@
 	bast_cb = 0;
 }
 
-void process_libdlm(void)
+static void process_libdlm(void)
 {
 	dlm_dispatch(libdlm_fd);
 	if (bast_cb && !ignore_bast)
 		do_bast_unlocks();
 }
 
-void astfn(void *arg)
+static void astfn(void *arg)
 {
 	struct lk *lk = arg;
 	int i = lk->id;
@@ -341,7 +344,7 @@
    and issues the second lock before the reply for the overlapping
    cancel (which did nothing) has been received in the dlm. */
 
-void lock(int i, int mode)
+static void lock(int i, int mode)
 {
 	char name[DLM_RESNAME_MAXLEN];
 	struct lk *lk;
@@ -397,7 +400,7 @@
 	lk->lastop = Op_lock;
 }
 
-void lock_sync(int i, int mode)
+static void lock_sync(int i, int mode)
 {
 	char name[DLM_RESNAME_MAXLEN];
 	int flags = 0;
@@ -441,7 +444,7 @@
 	}
 }
 
-void lock_all(int mode)
+static void lock_all(int mode)
 {
 	int i;
 
@@ -449,7 +452,7 @@
 		lock(i, mode);
 }
 
-char *uflags(uint32_t flags)
+static char *uflags(uint32_t flags)
 {
 	if (flags == LKF_FORCEUNLOCK)
 		return "FORCEUNLOCK";
@@ -462,7 +465,7 @@
    try to do an unlockf during an outstanding op that will free
    the lock itself */
 
-void _unlock(int i, uint32_t flags)
+static void _unlock(int i, uint32_t flags)
 {
 	struct lk *lk;
 	uint32_t lkid;
@@ -494,7 +497,7 @@
 	}
 }
 
-void unlock(int i)
+static void unlock(int i)
 {
 	struct lk *lk = get_lock(i);
 
@@ -508,7 +511,7 @@
 		if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
 			printf("        : unlock  %3d\t%x: gr %d rq %d held %u of %u s\n",
 				i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
-				now.tv_sec - lk->acquired.tv_sec, lk->minhold);
+				(unsigned int)(now.tv_sec - lk->acquired.tv_sec), lk->minhold);
 			return;
 		}
 	}
@@ -518,7 +521,7 @@
 	lk->lastop = Op_unlock;
 }
 
-void unlockf(int i)
+static void unlockf(int i)
 {
 	struct lk *lk = get_lock(i);
 
@@ -532,7 +535,7 @@
 		if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
 			printf("        : unlockf %3d\t%x: gr %d rq %d held %u of %u s\n",
 				i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
-				now.tv_sec - lk->acquired.tv_sec, lk->minhold);
+				(unsigned int)(now.tv_sec - lk->acquired.tv_sec), lk->minhold);
 			return;
 		}
 	}
@@ -542,14 +545,14 @@
 	lk->lastop = Op_unlockf;
 }
 
-void cancel(int i)
+static void cancel(int i)
 {
 	struct lk *lk = get_lock(i);
 	_unlock(i, LKF_CANCEL);
 	lk->lastop = Op_cancel;
 }
 
-void canceld(int i, uint32_t lkid)
+static void canceld(int i, uint32_t lkid)
 {
 	int rv;
 
@@ -558,7 +561,7 @@
 	printf("canceld %x: %d %d\n", lkid, rv, errno);
 }
 
-void unlock_sync(int i)
+static void unlock_sync(int i)
 {
 	uint32_t lkid;
 	int rv;
@@ -586,7 +589,7 @@
 	lk->rqmode = -1;
 }
 
-void unlock_all(void)
+static void unlock_all(void)
 {
 	struct lk *lk;
 	int i;
@@ -597,7 +600,7 @@
 	}
 }
 
-void purge(int nodeid, int pid)
+static void purge(int nodeid, int pid)
 {
 	struct lk *lk;
 	int i, rv;
@@ -616,7 +619,7 @@
 	}
 }
 
-void purgetest(int nodeid, int pid)
+static void purgetest(int nodeid, int pid)
 {
 	struct lk *lk;
 	int i, mid = maxn / 2;
@@ -645,7 +648,7 @@
 	purge(nodeid, pid);
 }
 
-void tstress_unlocks(void)
+static void tstress_unlocks(void)
 {
 	struct lk *lk;
 	struct timeval now;
@@ -667,7 +670,7 @@
 		if (now.tv_sec >= lk->acquired.tv_sec + minhold) {
 			printf("        : unlock  %3d\t%x: gr %d rq %d held %u of %u s\n",
 				i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
-				now.tv_sec - lk->acquired.tv_sec, minhold);
+				(unsigned int)(now.tv_sec - lk->acquired.tv_sec), minhold);
 
 			_unlock(i, 0);
 			lk->rqmode = -1;
@@ -677,10 +680,10 @@
 	}
 }
 
-void tstress(int num)
+static void tstress(int num)
 {
-	int i, o, op, max_op, skip;
 	unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
+	int i;
 	struct lk *lk;
 
 	n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
@@ -732,10 +735,10 @@
 	printf("ast status: zero %d other %d\n", sts_zero, sts_other);
 }
 
-void dstress(int num)
+static void dstress(int num)
 {
-	int i, o, op, max_op, skip;
 	unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
+	int i;
 	struct lk *lk;
 
 	n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
@@ -780,7 +783,7 @@
 	printf("ast status: zero %d other %d\n", sts_zero, sts_other);
 }
 
-void stress(int num)
+static void stress(int num)
 {
 	int i, o, op, max_op, skip;
 	unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
@@ -824,6 +827,8 @@
 		case 5:
 			op = Op_cancel;
 			break;
+		default:
+			op = 0;
 		}
 
 		skip = 0;
@@ -940,11 +945,11 @@
 		client[i].fd = -1;
 }
 
-void print_commands(void)
+static void print_commands(void)
 {
 	printf("Usage:\n");
 	printf("max locks (maxn) is %d (x of 0 to %d)\n", maxn, maxn-1);
-	printf("max resources (maxr) is %d, lock x used on resource (x % maxr)\n", maxr);
+	printf("max resources (maxr) is %d, lock x used on resource (x %% maxr)\n", maxr);
 	printf("EXIT		 - exit program after unlocking any held locks\n");
 	printf("kill		 - exit program without unlocking any locks\n");
 	printf("lock x mode	 - request/convert lock x\n");
@@ -984,7 +989,7 @@
 	printf("purgetest nodeid pid\n");
 }
 
-void print_settings(void)
+static void print_settings(void)
 {
 	printf("timewarn %d\n", timewarn);
 	printf("timeout %llu\n", (unsigned long long) timeout);
@@ -1000,18 +1005,18 @@
 	printf("stress_stop %d\n", stress_stop);
 	printf("stress_delay %d\n", stress_delay);
 	printf("stress_lock_only %d\n", stress_lock_only);
-	printf("our_xid %x\n", (unsigned long long)our_xid);
+	printf("our_xid %llx\n", (unsigned long long)our_xid);
 }
 
-void process_command(int *quit)
+static void process_command(int *quit)
 {
 	char inbuf[132];
-	char cmd[32];
-	int x = 0, y = 0, z = 0;
-
-	fgets(inbuf, sizeof(inbuf), stdin);
+	int x = 0, y = 0;
 
-	sscanf(inbuf, "%s %d %d", cmd, &x, &y, &z);
+	if (!opt_cmd) {
+		fgets(inbuf, sizeof(inbuf), stdin);
+		sscanf(inbuf, "%s %d %d", cmd, &x, &y);
+	}
 
 	if (!strncmp(cmd, "EXIT", 4)) {
 		*quit = 1;
@@ -1128,6 +1133,8 @@
 	}
 
 	if (!strncmp(cmd, "stress", 6) && strlen(cmd) == 6) {
+		if (iterations && !x)
+			x = iterations;
 		stress(x);
 		return;
 	}
@@ -1230,7 +1237,7 @@
 	printf("unknown command %s\n", cmd);
 }
 
-void print_usage(void)
+static void print_usage(void)
 {
 	printf("Options:\n");
 	printf("\n");
@@ -1246,7 +1253,7 @@
 	int optchar;
 
 	while (cont) {
-		optchar = getopt(argc, argv, "n:r:i:thVo");
+		optchar = getopt(argc, argv, "n:r:c:i:thVo");
 
 		switch (optchar) {
 
@@ -1258,6 +1265,11 @@
 			maxr = atoi(optarg);
 			break;
 
+		case 'c':
+			strcpy(cmd, optarg);
+			opt_cmd = 1;
+			break;
+
 		case 'i':
 			iterations = atoi(optarg);
 			break;
@@ -1334,7 +1346,7 @@
 	locks = malloc(maxn * sizeof(struct lk));
 	if (!locks) {
 		printf("no mem for %d locks\n", maxn);
-		return;
+		return 0;
 	}
 	memset(locks, 0, sizeof(*locks));
 
@@ -1367,7 +1379,8 @@
 	} else {
 		printf("dlm_new_lockspace...\n");
 
-		dh = dlm_new_lockspace("test", 0600, timewarn ? DLM_LSFL_TIMEWARN : 0);
+		dh = dlm_new_lockspace("test", 0600,
+				       timewarn ? DLM_LSFL_TIMEWARN : 0);
 		if (!dh) {
 			printf("dlm_new_lockspace error %lu %d\n",
 				(unsigned long)dh, errno);
@@ -1384,10 +1397,13 @@
 	libdlm_fd = rv;
 
 	client_add(libdlm_fd, &maxi);
-	client_add(STDIN_FILENO, &maxi);
 
-	if (strstr(argv[0], "dlmstress"))
-		stress(iterations);
+	if (opt_cmd) {
+		process_command(&quit);
+		goto out;
+	}
+
+	client_add(STDIN_FILENO, &maxi);
 
 	printf("Type EXIT to finish, help for usage\n");
 
@@ -1417,6 +1433,7 @@
 			break;
 	}
 
+ out:
 	if (openclose_ls) {
 		printf("dlm_close_lockspace\n");
 



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2007-08-23 19:13 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2007-08-23 19:13 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-08-23 19:13:54

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	dstress fixes

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.9&r2=1.10

--- cluster/dlm/tests/usertest/dlmtest2.c	2007/08/22 14:01:09	1.9
+++ cluster/dlm/tests/usertest/dlmtest2.c	2007/08/23 19:13:54	1.10
@@ -754,6 +754,7 @@
 
 		if (n && !(n % 60))
 			unlock_all();
+		n++;
 
 		i = rand_int(0, maxn-1);
 		lk = get_lock(i);
@@ -1309,6 +1310,8 @@
 	struct lk *lk;
 	int i, rv, maxi = 0, quit = 0;
 
+	srandom(time(NULL));
+
 	decode_arguments(argc, argv);
 
 	if (maxn < maxr) {



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2007-08-22 14:01 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2007-08-22 14:01 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-08-22 14:01:10

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	add new test for deadlocks

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.8&r2=1.9

--- cluster/dlm/tests/usertest/dlmtest2.c	2007/05/30 19:31:28	1.8
+++ cluster/dlm/tests/usertest/dlmtest2.c	2007/08/22 14:01:09	1.9
@@ -732,6 +732,53 @@
 	printf("ast status: zero %d other %d\n", sts_zero, sts_other);
 }
 
+void dstress(int num)
+{
+	int i, o, op, max_op, skip;
+	unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
+	struct lk *lk;
+
+	n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
+	sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
+	bast_unlock = bast_skip = 0;
+
+	noqueue = 0;
+	ignore_bast = 1;
+	quiet = 0;
+
+	while (!stress_stop && n < num) {
+
+		sleep(1);
+
+		process_libdlm();
+
+		if (n && !(n % 60))
+			unlock_all();
+
+		i = rand_int(0, maxn-1);
+		lk = get_lock(i);
+		if (!lk)
+			continue;
+
+		if (lk->wait_ast || lk->grmode > -1) {
+			printf("%8x: lock    %3d\t%x: skip gr %d wait_ast %d\n",
+				n, i, lk->lksb.sb_lkid, lk->grmode, lk->wait_ast);
+			continue;
+		}
+
+		lock(i, rand_int(0, 5));
+		lock_ops++;
+		printf("%8x: lock    %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+	}
+
+	printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
+		skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
+	printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
+	printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
+		sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
+	printf("ast status: zero %d other %d\n", sts_zero, sts_other);
+}
+
 void stress(int num)
 {
 	int i, o, op, max_op, skip;
@@ -913,6 +960,7 @@
 	printf("purge nodeid pid - purge orphan locks of process\n");
 	printf("stress n	 - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
 	printf("tstress n	 - stress timeouts\n");
+	printf("dstress n	 - stress deadlock\n");
 	printf("timeout n	 - enable lock timeouts, set timeout to n seconds\n");
 	printf("dump		 - show info for all locks\n");
 	printf("minhold		 - set minimum number of seconds locks will be held\n");
@@ -921,6 +969,7 @@
 	printf("persistent	 - toggle PERSISTENT flag for all requests\n");
 	printf("quiet		 - toggle quiet flag\n");
 	printf("verbose		 - toggle verbose flag\n");
+	printf("settings	 - show settings\n");
 
 	printf("\ncombined operations\n");
 	printf("hold-kill                     - hold; kill\n");
@@ -950,6 +999,7 @@
 	printf("stress_stop %d\n", stress_stop);
 	printf("stress_delay %d\n", stress_delay);
 	printf("stress_lock_only %d\n", stress_lock_only);
+	printf("our_xid %x\n", (unsigned long long)our_xid);
 }
 
 void process_command(int *quit)
@@ -1086,6 +1136,11 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "dstress", 7) && strlen(cmd) == 7) {
+		dstress(x);
+		return;
+	}
+
 	if (!strncmp(cmd, "stress_delay", 12) && strlen(cmd) == 12) {
 		stress_delay = x;
 		return;
@@ -1097,12 +1152,25 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "stress_stop", 11) && strlen(cmd) == 11) {
+		stress_stop = !stress_stop;
+		printf("stress_stop is %d\n", stress_stop);
+		return;
+	}
+
 	if (!strncmp(cmd, "ignore_bast", 11) && strlen(cmd) == 11) {
 		ignore_bast = !ignore_bast;
 		printf("ignore_bast is %s\n", ignore_bast ? "on" : "off");
 		return;
 	}
 
+	if (!strncmp(cmd, "our_xid", 7) && strlen(cmd) == 7) {
+		our_xid = x;
+		printf("our_xid is %llx\n", (unsigned long long)our_xid);
+		return;
+	}
+
+
 	if (!strncmp(cmd, "purge", 5) && strlen(cmd) == 5) {
 		purge(x, y);
 		return;



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2007-05-30 19:31 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2007-05-30 19:31 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-05-30 19:31:28

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	bunch of stuff to test new features

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.7&r2=1.8

--- cluster/dlm/tests/usertest/dlmtest2.c	2007/04/27 19:09:54	1.7
+++ cluster/dlm/tests/usertest/dlmtest2.c	2007/05/30 19:31:28	1.8
@@ -41,6 +41,7 @@
 static uint64_t timeout = 0;
 static int noqueue = 1;
 static int persistent = 0;
+static int ignore_bast = 0;
 static int quiet = 1;
 static int verbose = 0;
 static int bast_cb;
@@ -49,8 +50,14 @@
 static int iterations;
 static int minhold = 0;
 static int stress_stop = 0;
+static int stress_delay = 0;
+static int stress_lock_only = 0;
+static int openclose_ls = 0;
 static uint64_t our_xid;
 
+static unsigned int sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain, sts_other, sts_zero;
+static unsigned int bast_unlock, bast_skip;
+
 #define log_print(fmt, args...) \
 do { \
 	if (!quiet) \
@@ -121,6 +128,8 @@
 		return "EBUSY  ";
 	case ETIMEDOUT:
 		return "ETIMEDO";
+	case EDEADLK:
+		return "EDEADLK";
 	default:
 		snprintf(sts_str, 8, "%8x", status);
 		return sts_str;
@@ -206,9 +215,11 @@
 		skip = 1;
 	}
 
-	if (skip)
+	if (skip) {
+		bast_skip++;
 		printf("    bast: skip    %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
-	else {
+	} else {
+		bast_unlock++;
 		printf("    bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
 		unlockf(lk->id);
 	}
@@ -231,7 +242,7 @@
 void process_libdlm(void)
 {
 	dlm_dispatch(libdlm_fd);
-	if (bast_cb)
+	if (bast_cb && !ignore_bast)
 		do_bast_unlocks();
 }
 
@@ -253,11 +264,13 @@
 	lk->last_status = lk->lksb.sb_status;
 
 	if (lk->lksb.sb_status == EUNLOCK) {
+		sts_eunlock++;
 		memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
 		lk->grmode = -1;
 		lk->wait_ast = 0;
 
 	} else if (lk->lksb.sb_status == ECANCEL) {
+		sts_ecancel++;
 		if (lk->grmode == -1) {
 			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
 			lk->wait_ast = 0;
@@ -267,6 +280,17 @@
 		}
 
 	} else if (lk->lksb.sb_status == ETIMEDOUT) {
+		sts_etimedout++;
+		if (lk->grmode == -1) {
+			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+			lk->wait_ast = 0;
+		} else {
+			if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
+				lk->wait_ast = 0;
+		}
+
+	} else if (lk->lksb.sb_status == EDEADLK) {
+		sts_edeadlk++;
 		if (lk->grmode == -1) {
 			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
 			lk->wait_ast = 0;
@@ -276,6 +300,7 @@
 		}
 
 	} else if (lk->lksb.sb_status == EAGAIN) {
+		sts_eagain++;
 		if (lk->grmode == -1) {
 			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
 			lk->wait_ast = 0;
@@ -286,10 +311,17 @@
 
 	} else {
 		if (lk->lksb.sb_status != 0) {
-			printf("unknown sb_status %x\n", lk->lksb.sb_status);
-			exit(-1);
+			sts_other++;
+			printf("BAD  ast: %d %3d\t%x: gr %d rq %d last op %s %s\n",
+		       		lk->lksb.sb_status, i, lk->lksb.sb_lkid,
+				lk->grmode, lk->rqmode, op_str(lk->lastop),
+				status_str(lk->last_status));
+			stress_stop = 1;
+			return;
 		}
 
+		sts_zero++;
+
 		if (lk->lastop != Op_unlockf)
 			lk->wait_ast = 0;
 
@@ -297,8 +329,7 @@
 
 		if (minhold) {
 			gettimeofday(&lk->acquired, NULL);
-			/* lk->minhold = rand_int(1, 30); */
-			lk->minhold = 10;
+			lk->minhold = minhold;
 		}
 	}
 
@@ -340,8 +371,13 @@
 	log_verbose("lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
 	            i, lk->grmode, mode, flags, lk->lksb.sb_lkid, name);
 
+#if 0
+	rv = dlm_ls_lock(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
+			  astfn, (void *) lk, bastfn, NULL);
+#else
 	rv = dlm_ls_lockx(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
 			  astfn, (void *) lk, bastfn, &our_xid, timeout_arg);
+#endif
 	if (!rv) {
 		lk->wait_ast = 1;
 		lk->rqmode = mode;
@@ -513,6 +549,15 @@
 	lk->lastop = Op_cancel;
 }
 
+void canceld(int i, uint32_t lkid)
+{
+	int rv;
+
+	rv = dlm_ls_deadlock_cancel(dh, lkid, 0);
+
+	printf("canceld %x: %d %d\n", lkid, rv, errno);
+}
+
 void unlock_sync(int i)
 {
 	uint32_t lkid;
@@ -600,15 +645,107 @@
 	purge(nodeid, pid);
 }
 
+void tstress_unlocks(void)
+{
+	struct lk *lk;
+	struct timeval now;
+	int i;
+
+	for (i = 0; i < maxn; i++) {
+		lk = get_lock(i);
+		if (!lk)
+			continue;
+		if (lk->wait_ast)
+			continue;
+		if (lk->grmode < 0)
+			continue;
+
+		/* if we've held the lock for minhold seconds, then unlock */
+
+		gettimeofday(&now, NULL);
+
+		if (now.tv_sec >= lk->acquired.tv_sec + minhold) {
+			printf("        : unlock  %3d\t%x: gr %d rq %d held %u of %u s\n",
+				i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
+				now.tv_sec - lk->acquired.tv_sec, minhold);
+
+			_unlock(i, 0);
+			lk->rqmode = -1;
+			lk->lastop = Op_unlock;
+		}
+
+	}
+}
+
+void tstress(int num)
+{
+	int i, o, op, max_op, skip;
+	unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
+	struct lk *lk;
+
+	n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
+	sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
+	bast_unlock = bast_skip = 0;
+
+	noqueue = 0;
+	ignore_bast = 1;
+	quiet = 0;
+
+	if (!timeout)
+		timeout = 4;
+	if (!minhold)
+		minhold = 5;
+
+	while (!stress_stop) {
+		if (stress_delay)
+			usleep(stress_delay);
+
+		process_libdlm();
+
+		tstress_unlocks();
+
+		if (++n == num) {
+			if (all_unlocks_done())
+				break;
+			else
+				continue;
+		}
+
+		i = rand_int(0, maxn-1);
+		lk = get_lock(i);
+		if (!lk)
+			continue;
+
+		if (lk->wait_ast || lk->grmode > -1)
+			continue;
+
+		lock(i, rand_int(0, 5));
+		lock_ops++;
+		printf("%8x: lock    %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+	}
+
+	printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
+		skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
+	printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
+	printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
+		sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
+	printf("ast status: zero %d other %d\n", sts_zero, sts_other);
+}
+
 void stress(int num)
 {
-	int i, o, op, skip;
+	int i, o, op, max_op, skip;
 	unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
 	struct lk *lk;
 
 	n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
+	sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
+	bast_unlock = bast_skip = 0;
 
 	while (!stress_stop) {
+		if (stress_delay)
+			usleep(stress_delay);
+
 		process_libdlm();
 
 		if (++n == num)
@@ -619,7 +756,11 @@
 		if (!lk)
 			continue;
 
-		o = rand_int(0, 5);
+		max_op = 5;
+		if (stress_lock_only)
+			max_op = 2;
+
+		o = rand_int(0, max_op);
 		switch (o) {
 		case 0:
 		case 1:
@@ -708,8 +849,12 @@
 			skips++;
 	}
 
-	printf("skip %d lock %d unlock %d unlockf %d cancel %d\n",
+	printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
 		skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
+	printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
+	printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
+		sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
+	printf("ast status: zero %d other %d\n", sts_zero, sts_other);
 }
 
 static int client_add(int fd, int *maxi)
@@ -758,6 +903,7 @@
 	printf("unlock x 	 - unlock lock x\n");
 	printf("unlockf x 	 - force unlock lock x\n");
 	printf("cancel x 	 - cancel lock x\n");
+	printf("canceld x lkid	 - cancel lock x, return EDEADLK as status\n");
 	printf("lock_sync x mode - synchronous version of lock\n");
 	printf("unlock_sync x 	 - synchronous version of unlock\n");
 	printf("ex x		 - equivalent to: lock x 5\n");
@@ -766,11 +912,13 @@
 	printf("release		 - for x in 0 to max, unlock x\n");
 	printf("purge nodeid pid - purge orphan locks of process\n");
 	printf("stress n	 - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
+	printf("tstress n	 - stress timeouts\n");
 	printf("timeout n	 - enable lock timeouts, set timeout to n seconds\n");
 	printf("dump		 - show info for all locks\n");
+	printf("minhold		 - set minimum number of seconds locks will be held\n");
+	printf("ignore_bast	 - ignore all basts\n");
 	printf("noqueue		 - toggle NOQUEUE flag for all requests\n");
 	printf("persistent	 - toggle PERSISTENT flag for all requests\n");
-	printf("minhold		 - toggle minhold mode, lock will be held for random minimum time\n");
 	printf("quiet		 - toggle quiet flag\n");
 	printf("verbose		 - toggle verbose flag\n");
 
@@ -786,6 +934,24 @@
 	printf("purgetest nodeid pid\n");
 }
 
+void print_settings(void)
+{
+	printf("timewarn %d\n", timewarn);
+	printf("timeout %llu\n", (unsigned long long) timeout);
+	printf("noqueue %d\n", noqueue);
+	printf("persistent %d\n", persistent);
+	printf("ignore_bast %d\n", ignore_bast);
+	printf("quiet %d\n", quiet);
+	printf("verbose %d\n", verbose);
+	printf("maxn %d\n", maxn);
+	printf("maxr %d\n", maxr);
+	printf("iterations %d\n", iterations);
+	printf("minhold %d\n", minhold);
+	printf("stress_stop %d\n", stress_stop);
+	printf("stress_delay %d\n", stress_delay);
+	printf("stress_lock_only %d\n", stress_lock_only);
+}
+
 void process_command(int *quit)
 {
 	char inbuf[132];
@@ -802,6 +968,13 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "CLOSE", 5)) {
+		*quit = 1;
+		openclose_ls = 1;
+		unlock_all();
+		return;
+	}
+
 	if (!strncmp(cmd, "kill", 4)) {
 		printf("process exiting\n");
 		exit(0);
@@ -827,6 +1000,11 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "canceld", 7) && strlen(cmd) == 7) {
+		canceld(x, y);
+		return;
+	}
+
 	if (!strncmp(cmd, "lock_sync", 9) && strlen(cmd) == 9) {
 		lock_sync(x, y);
 		return;
@@ -898,11 +1076,33 @@
 		return;
 	}
 
-	if (!strncmp(cmd, "stress", 6)) {
+	if (!strncmp(cmd, "stress", 6) && strlen(cmd) == 6) {
 		stress(x);
 		return;
 	}
 
+	if (!strncmp(cmd, "tstress", 7) && strlen(cmd) == 7) {
+		tstress(x);
+		return;
+	}
+
+	if (!strncmp(cmd, "stress_delay", 12) && strlen(cmd) == 12) {
+		stress_delay = x;
+		return;
+	}
+
+	if (!strncmp(cmd, "stress_lock_only", 16) && strlen(cmd) == 16) {
+		stress_lock_only = !stress_lock_only;
+		printf("stress_lock_only is %s\n", stress_lock_only ? "on" : "off");
+		return;
+	}
+
+	if (!strncmp(cmd, "ignore_bast", 11) && strlen(cmd) == 11) {
+		ignore_bast = !ignore_bast;
+		printf("ignore_bast is %s\n", ignore_bast ? "on" : "off");
+		return;
+	}
+
 	if (!strncmp(cmd, "purge", 5) && strlen(cmd) == 5) {
 		purge(x, y);
 		return;
@@ -926,8 +1126,7 @@
 	}
 
 	if (!strncmp(cmd, "minhold", 7)) {
-		minhold = !minhold;
-		printf("minhold is %s\n", minhold ? "on" : "off");
+		minhold = x;
 		return;
 	}
 
@@ -954,6 +1153,11 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "settings", 8)) {
+		print_settings();
+		return;
+	}
+
 	printf("unknown command %s\n", cmd);
 }
 
@@ -973,7 +1177,7 @@
 	int optchar;
 
 	while (cont) {
-		optchar = getopt(argc, argv, "n:r:i:thV");
+		optchar = getopt(argc, argv, "n:r:i:thVo");
 
 		switch (optchar) {
 
@@ -993,6 +1197,10 @@
 			timewarn = 1;
 			break;
 
+		case 'o':
+			openclose_ls = 1;
+			break;
+
 		case 'h':
 			print_usage();
 			exit(EXIT_SUCCESS);
@@ -1029,6 +1237,7 @@
 
 int main(int argc, char *argv[])
 {
+	uint32_t major, minor, patch;
 	struct lk *lk;
 	int i, rv, maxi = 0, quit = 0;
 
@@ -1066,12 +1275,33 @@
 		lk++;
 	}
 
-	printf("Joining test lockspace...\n");
+	rv = dlm_kernel_version(&major, &minor, &patch);
+	if (rv < 0) {
+		printf("can't detect dlm in kernel %d\n", errno);
+		return -1;
+	}
+	printf("dlm kernel version: %u.%u.%u\n", major, minor, patch);
+	dlm_library_version(&major, &minor, &patch);
+	printf("dlm library version: %u.%u.%u\n", major, minor, patch);
+
+	if (openclose_ls) {
+		printf("dlm_open_lockspace...\n");
+
+		dh = dlm_open_lockspace("test");
+		if (!dh) {
+			printf("dlm_open_lockspace error %lu %d\n",
+				(unsigned long)dh, errno);
+			return -ENOTCONN;
+		}
+	} else {
+		printf("dlm_new_lockspace...\n");
 
-	dh = dlm_new_lockspace("test", 0600, timewarn ? DLM_LSFL_TIMEWARN : 0);
-	if (!dh) {
-		printf("dlm_new_lockspace error %d %d\n", (int) dh, errno);
-		return -ENOTCONN;
+		dh = dlm_new_lockspace("test", 0600, timewarn ? DLM_LSFL_TIMEWARN : 0);
+		if (!dh) {
+			printf("dlm_new_lockspace error %lu %d\n",
+				(unsigned long)dh, errno);
+			return -ENOTCONN;
+		}
 	}
 
 	rv = dlm_ls_get_fd(dh);
@@ -1116,11 +1346,19 @@
 			break;
 	}
 
-	printf("dlm_release_lockspace\n");
+	if (openclose_ls) {
+		printf("dlm_close_lockspace\n");
+
+		rv = dlm_close_lockspace(dh);
+		if (rv < 0)
+			printf("dlm_close_lockspace error %d %d\n", rv, errno);
+	} else {
+		printf("dlm_release_lockspace\n");
 
-	rv = dlm_release_lockspace("test", dh, 1);
-	if (rv < 0)
-		printf("dlm_release_lockspace error %d %d\n", rv, errno);
+		rv = dlm_release_lockspace("test", dh, 1);
+		if (rv < 0)
+			printf("dlm_release_lockspace error %d %d\n", rv, errno);
+	}
 
 	return 0;
 }



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2007-04-27 19:09 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2007-04-27 19:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-04-27 20:09:54

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	various changes

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.6&r2=1.7

--- cluster/dlm/tests/usertest/dlmtest2.c	2007/03/27 19:04:30	1.6
+++ cluster/dlm/tests/usertest/dlmtest2.c	2007/04/27 19:09:54	1.7
@@ -19,6 +19,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <time.h>
+#include <signal.h>
 #include <syslog.h>
 #include <asm/types.h>
 #include <sys/socket.h>
@@ -36,6 +37,8 @@
 
 static dlm_lshandle_t *dh;
 static int libdlm_fd;
+static int timewarn = 0;
+static uint64_t timeout = 0;
 static int noqueue = 1;
 static int persistent = 0;
 static int quiet = 1;
@@ -44,7 +47,9 @@
 static int maxn = MAX_LOCKS;
 static int maxr = MAX_RESOURCES;
 static int iterations;
+static int minhold = 0;
 static int stress_stop = 0;
+static uint64_t our_xid;
 
 #define log_print(fmt, args...) \
 do { \
@@ -82,7 +87,10 @@
 	int lastop;
 	int last_status;
 	int bast;
+	int minhold;
 	struct dlm_lksb lksb;
+	struct timeval begin;
+	struct timeval acquired;
 };
 
 struct lk *locks;
@@ -111,6 +119,8 @@
 		return "EAGAIN ";
 	case EBUSY:
 		return "EBUSY  ";
+	case ETIMEDOUT:
+		return "ETIMEDO";
 	default:
 		snprintf(sts_str, 8, "%8x", status);
 		return sts_str;
@@ -158,19 +168,23 @@
 
 void dump(void)
 {
+	struct timeval now;
 	struct lk *lk;
 	int i;
 
+	gettimeofday(&now, NULL);
+
 	for (i = 0; i < maxn; i++) {
 		lk = get_lock(i);
-		printf("x %2d lkid %08x gr %2d rq %2d wait_ast %d last op %s  \t%s\n",
+		printf("x %2d lkid %08x gr %2d rq %2d wait_ast %d last op %s  \t%s  %us\n",
 			i,
 			lk->lksb.sb_lkid,
 			lk->grmode,
 			lk->rqmode,
 			lk->wait_ast,
 			op_str(lk->lastop),
-			status_str(lk->last_status));
+			status_str(lk->last_status),
+			lk->wait_ast ? now.tv_sec - lk->begin.tv_sec : 0);
 	}
 }
 
@@ -197,7 +211,6 @@
 	else {
 		printf("    bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
 		unlockf(lk->id);
-		lk->lastop = Op_unlockf;
 	}
 	lk->bast = 0;
 }
@@ -253,6 +266,15 @@
 				lk->wait_ast = 0;
 		}
 
+	} else if (lk->lksb.sb_status == ETIMEDOUT) {
+		if (lk->grmode == -1) {
+			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+			lk->wait_ast = 0;
+		} else {
+			if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
+				lk->wait_ast = 0;
+		}
+
 	} else if (lk->lksb.sb_status == EAGAIN) {
 		if (lk->grmode == -1) {
 			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
@@ -272,12 +294,18 @@
 			lk->wait_ast = 0;
 
 		lk->grmode = lk->rqmode;
+
+		if (minhold) {
+			gettimeofday(&lk->acquired, NULL);
+			/* lk->minhold = rand_int(1, 30); */
+			lk->minhold = 10;
+		}
 	}
 
 	lk->rqmode = -1;
 }
 
-/* EBUSY from dlm_ls_lock() is expected sometimes, e.g. lock, cancel, lock;
+/* EBUSY from dlm_ls_lockx() is expected sometimes, e.g. lock, cancel, lock;
    the first lock is successful and the app gets the status back,
    and issues the second lock before the reply for the overlapping
    cancel (which did nothing) has been received in the dlm. */
@@ -288,6 +316,7 @@
 	struct lk *lk;
 	int flags = 0;
 	int rv;
+	uint64_t *timeout_arg = NULL;
 
 	lk = get_lock(i);
 	if (!lk)
@@ -297,6 +326,10 @@
 		flags |= LKF_NOQUEUE;
 	if (persistent)
 		flags |= LKF_PERSISTENT;
+	if (timeout) {
+		flags |= LKF_TIMEOUT;
+		timeout_arg = &timeout;
+	}
 
 	if (lk->lksb.sb_lkid)
 		flags |= LKF_CONVERT;
@@ -307,11 +340,12 @@
 	log_verbose("lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
 	            i, lk->grmode, mode, flags, lk->lksb.sb_lkid, name);
 
-	rv = dlm_ls_lock(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
-			 astfn, (void *) lk, bastfn, NULL);
+	rv = dlm_ls_lockx(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
+			  astfn, (void *) lk, bastfn, &our_xid, timeout_arg);
 	if (!rv) {
 		lk->wait_ast = 1;
 		lk->rqmode = mode;
+		gettimeofday(&lk->begin, NULL);
 	} else if (rv == -1 && errno == EBUSY) {
 		printf("        : lock    %3d\t%x: EBUSY gr %d rq %d wait_ast %d\n",
 			i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, lk->wait_ast);
@@ -411,6 +445,7 @@
 	rv = dlm_ls_unlock(dh, lkid, flags, &lk->lksb, lk);
 	if (!rv) {
 		lk->wait_ast = 1;
+		gettimeofday(&lk->begin, NULL);
 	} else if (rv == -1 && errno == EBUSY) {
 		printf("        : unlock  %3d\t%x: EBUSY flags %s gr %d rq %d wait_ast %d\n",
 			i, lk->lksb.sb_lkid, uflags(flags), lk->grmode, lk->rqmode, lk->wait_ast);
@@ -426,6 +461,22 @@
 void unlock(int i)
 {
 	struct lk *lk = get_lock(i);
+
+	if (minhold) {
+		struct timeval now;
+
+		if (lk->wait_ast)
+			return;
+
+		gettimeofday(&now, NULL);
+		if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
+			printf("        : unlock  %3d\t%x: gr %d rq %d held %u of %u s\n",
+				i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
+				now.tv_sec - lk->acquired.tv_sec, lk->minhold);
+			return;
+		}
+	}
+
 	_unlock(i, 0);
 	lk->rqmode = -1;
 	lk->lastop = Op_unlock;
@@ -434,6 +485,22 @@
 void unlockf(int i)
 {
 	struct lk *lk = get_lock(i);
+
+	if (minhold) {
+		struct timeval now;
+
+		if (lk->wait_ast)
+			return;
+
+		gettimeofday(&now, NULL);
+		if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
+			printf("        : unlockf %3d\t%x: gr %d rq %d held %u of %u s\n",
+				i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
+				now.tv_sec - lk->acquired.tv_sec, lk->minhold);
+			return;
+		}
+	}
+
 	_unlock(i, LKF_FORCEUNLOCK);
 	lk->rqmode = -1;
 	lk->lastop = Op_unlockf;
@@ -482,10 +549,57 @@
 	for (i = 0; i < maxn; i++) {
 		lk = get_lock(i);
 		unlock(i);
-		lk->lastop = Op_unlock;
 	}
 }
 
+void purge(int nodeid, int pid)
+{
+	struct lk *lk;
+	int i, rv;
+
+	rv = dlm_ls_purge(dh, nodeid, pid);
+	if (rv) {
+		printf("dlm_ls_purge %d %d error %d\n", nodeid, pid, rv);
+		return;
+	}
+
+	for (i = 0; i < maxn; i++) {
+		lk = get_lock(i);
+		memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+		lk->grmode = -1;
+		lk->wait_ast = 0;
+	}
+}
+
+void purgetest(int nodeid, int pid)
+{
+	struct lk *lk;
+	int i, mid = maxn / 2;
+
+	printf("lock %d to %d\n", 0, mid-1);
+	for (i = 0; i < mid; i++)
+		lock(i, 3);
+
+	while (1) {
+		process_libdlm();
+		for (i = 0; i < mid; i++) {
+			lk = get_lock(i);
+			if (!lk->wait_ast)
+				continue;
+			break;
+		}
+		if (i == mid)
+			break;
+	}
+
+	for (i = mid; i < maxn; i++)
+		lock(i, 3);
+	for (i = 0; i < mid; i++)
+		unlock(i);
+	/* usleep(10000); */
+	purge(nodeid, pid);
+}
+
 void stress(int num)
 {
 	int i, o, op, skip;
@@ -533,6 +647,7 @@
 			}
 
 			noqueue = !!o;
+			our_xid = n;
 
 			lock(i, rand_int(0, 5));
 			lock_ops++;
@@ -649,10 +764,13 @@
 	printf("pr x		 - equivalent to: lock x 3\n");
 	printf("hold		 - for x in 0 to max, lock x 3\n");
 	printf("release		 - for x in 0 to max, unlock x\n");
+	printf("purge nodeid pid - purge orphan locks of process\n");
 	printf("stress n	 - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
+	printf("timeout n	 - enable lock timeouts, set timeout to n seconds\n");
 	printf("dump		 - show info for all locks\n");
 	printf("noqueue		 - toggle NOQUEUE flag for all requests\n");
 	printf("persistent	 - toggle PERSISTENT flag for all requests\n");
+	printf("minhold		 - toggle minhold mode, lock will be held for random minimum time\n");
 	printf("quiet		 - toggle quiet flag\n");
 	printf("verbose		 - toggle verbose flag\n");
 
@@ -665,6 +783,7 @@
 	printf("lock-unlockf x mode msec      - lock; sleep; unlockf\n");
 	printf("lock-cancel-kill x mode msec  - lock; sleep; cancel; kill\n");
 	printf("lock-unlockf-kill x mode msec - lock; sleep; unlockf; kill\n");
+	printf("purgetest nodeid pid\n");
 }
 
 void process_command(int *quit)
@@ -784,6 +903,16 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "purge", 5) && strlen(cmd) == 5) {
+		purge(x, y);
+		return;
+	}
+
+	if (!strncmp(cmd, "purgetest", 9) && strlen(cmd) == 9) {
+		purgetest(x, y);
+		return;
+	}
+
 	if (!strncmp(cmd, "noqueue", 7)) {
 		noqueue = !noqueue;
 		printf("noqueue is %s\n", noqueue ? "on" : "off");
@@ -796,6 +925,18 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "minhold", 7)) {
+		minhold = !minhold;
+		printf("minhold is %s\n", minhold ? "on" : "off");
+		return;
+	}
+
+	if (!strncmp(cmd, "timeout", 7)) {
+		timeout = (uint64_t) 100 * x; /* dlm takes it in centiseconds */
+		printf("timeout is %d\n", x);
+		return;
+	}
+
 	if (!strncmp(cmd, "quiet", 5)) {
 		quiet = !quiet;
 		printf("quiet is %d\n", quiet);
@@ -820,8 +961,10 @@
 {
 	printf("Options:\n");
 	printf("\n");
-	printf("  -n           The number of resources to work with, default %d\n", MAX_LOCKS);
+	printf("  -n           The number of locks to work with, default %d\n", MAX_LOCKS);
+	printf("  -r           The number of resources to work with, default %d\n", MAX_RESOURCES);
 	printf("  -i           Iterations in looping stress test, default 0 is no limit\n");
+	printf("  -t           Enable timeout warnings\n");
 }
 
 static void decode_arguments(int argc, char **argv)
@@ -830,7 +973,7 @@
 	int optchar;
 
 	while (cont) {
-		optchar = getopt(argc, argv, "n:r:i:hV");
+		optchar = getopt(argc, argv, "n:r:i:thV");
 
 		switch (optchar) {
 
@@ -846,6 +989,10 @@
 			iterations = atoi(optarg);
 			break;
 
+		case 't':
+			timewarn = 1;
+			break;
+
 		case 'h':
 			print_usage();
 			exit(EXIT_SUCCESS);
@@ -875,6 +1022,11 @@
 	}
 }
 
+static void sigterm_handler(int sig)
+{
+	stress_stop = 1;
+}
+
 int main(int argc, char *argv[])
 {
 	struct lk *lk;
@@ -895,6 +1047,8 @@
 	printf("maxr = %d\n", maxr);
 	printf("locks per resource = %d\n", maxn / maxr);
 
+	signal(SIGTERM, sigterm_handler);
+
 	client_init();
 
 	locks = malloc(maxn * sizeof(struct lk));
@@ -914,9 +1068,9 @@
 
 	printf("Joining test lockspace...\n");
 
-	dh = dlm_create_lockspace("test", 0600);
+	dh = dlm_new_lockspace("test", 0600, timewarn ? DLM_LSFL_TIMEWARN : 0);
 	if (!dh) {
-		printf("dlm_create_lockspace error %d %d\n", (int) dh, errno);
+		printf("dlm_new_lockspace error %d %d\n", (int) dh, errno);
 		return -ENOTCONN;
 	}
 



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2007-03-27 19:04 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2007-03-27 19:04 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-03-27 20:04:31

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	latest version, "stress" test running correctly

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.5&r2=1.6

--- cluster/dlm/tests/usertest/dlmtest2.c	2007/02/27 18:55:52	1.5
+++ cluster/dlm/tests/usertest/dlmtest2.c	2007/03/27 19:04:30	1.6
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -32,14 +32,19 @@
 
 #define MAX_CLIENTS 4
 #define MAX_LOCKS 16
+#define MAX_RESOURCES 16
 
 static dlm_lshandle_t *dh;
 static int libdlm_fd;
 static int noqueue = 1;
+static int persistent = 0;
 static int quiet = 1;
 static int verbose = 0;
 static int bast_cb;
 static int maxn = MAX_LOCKS;
+static int maxr = MAX_RESOURCES;
+static int iterations;
+static int stress_stop = 0;
 
 #define log_print(fmt, args...) \
 do { \
@@ -158,7 +163,7 @@
 
 	for (i = 0; i < maxn; i++) {
 		lk = get_lock(i);
-		printf("x %2d lkid %06x gr %2d rq %2d wait_ast %d last op %s\t%s\n",
+		printf("x %2d lkid %08x gr %2d rq %2d wait_ast %d last op %s  \t%s\n",
 			i,
 			lk->lksb.sb_lkid,
 			lk->grmode,
@@ -272,6 +277,11 @@
 	lk->rqmode = -1;
 }
 
+/* EBUSY from dlm_ls_lock() is expected sometimes, e.g. lock, cancel, lock;
+   the first lock is successful and the app gets the status back,
+   and issues the second lock before the reply for the overlapping
+   cancel (which did nothing) has been received in the dlm. */
+
 void lock(int i, int mode)
 {
 	char name[DLM_RESNAME_MAXLEN];
@@ -285,12 +295,14 @@
 
 	if (noqueue)
 		flags |= LKF_NOQUEUE;
+	if (persistent)
+		flags |= LKF_PERSISTENT;
 
 	if (lk->lksb.sb_lkid)
 		flags |= LKF_CONVERT;
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, sizeof(name), "test%d", i);
+	snprintf(name, sizeof(name), "test%d", (i % maxr));
 
 	log_verbose("lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
 	            i, lk->grmode, mode, flags, lk->lksb.sb_lkid, name);
@@ -304,8 +316,9 @@
 		printf("        : lock    %3d\t%x: EBUSY gr %d rq %d wait_ast %d\n",
 			i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, lk->wait_ast);
 	} else {
-		printf("        : lock    %3d\t%x: errno %d gr %d rq %d wait_ast %d\n",
-			i, lk->lksb.sb_lkid, errno, lk->grmode, lk->rqmode, lk->wait_ast);
+		printf("        : lock    %3d\t%x: errno %d rv %d gr %d rq %d wait_ast %d\n",
+			i, lk->lksb.sb_lkid, errno, rv, lk->grmode, lk->rqmode, lk->wait_ast);
+		stress_stop = 1;
 	}
 
 	log_verbose("lock: %d rv %d sb_lkid %x sb_status %x\n",
@@ -327,12 +340,14 @@
 
 	if (noqueue)
 		flags |= LKF_NOQUEUE;
+	if (persistent)
+		flags |= LKF_PERSISTENT;
 
 	if (lk->lksb.sb_lkid)
 		flags |= LKF_CONVERT;
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, sizeof(name), "test%d", i);
+	snprintf(name, sizeof(name), "test%d", (i % maxr));
 
 	log_verbose("lock_sync: %d rqmode %d flags %x lkid %x %s\n",
 	            i, mode, flags, lk->lksb.sb_lkid, name);
@@ -364,6 +379,19 @@
 		lock(i, mode);
 }
 
+char *uflags(uint32_t flags)
+{
+	if (flags == LKF_FORCEUNLOCK)
+		return "FORCEUNLOCK";
+	if (flags == LKF_CANCEL)
+		return "CANCEL";
+	return "0";
+}
+
+/* ENOENT is expected from dlm_ls_unlock() sometimes because we'll
+   try to do an unlockf during an outstanding op that will free
+   the lock itself */
+
 void _unlock(int i, uint32_t flags)
 {
 	struct lk *lk;
@@ -384,21 +412,14 @@
 	if (!rv) {
 		lk->wait_ast = 1;
 	} else if (rv == -1 && errno == EBUSY) {
-		printf("unlock: EBUSY %d %x flags %x gr %d rq %d wait_ast %d\n",
-			i, lk->lksb.sb_lkid, flags, lk->grmode, lk->rqmode, lk->wait_ast);
+		printf("        : unlock  %3d\t%x: EBUSY flags %s gr %d rq %d wait_ast %d\n",
+			i, lk->lksb.sb_lkid, uflags(flags), lk->grmode, lk->rqmode, lk->wait_ast);
+	} else if (rv == -1 && errno == ENOENT) {
+		printf("        : unlock  %3d\t%x: ENOENT flags %s gr %d rq %d wait_ast %d\n",
+			i, lk->lksb.sb_lkid, uflags(flags), lk->grmode, lk->rqmode, lk->wait_ast);
 	} else {
-		printf("unlock: error %d %x flags %x rv %d errno %d gr %d rq %d wait_ast %d\n",
-		       i, lk->lksb.sb_lkid, flags, rv, errno, lk->grmode, lk->rqmode,
-		       lk->wait_ast);
-#if 0
-		char input[32];
-		printf("press X to exit, D to dispatch, other to continue\n");
-		fgets(input, 32, stdin);
-		if (input[0] == 'X')
-			exit(-1);
-		else if (input[0] == 'D')
-			dlm_dispatch(libdlm_fd);
-#endif
+		printf("        : unlock  %3d\t%x: errno %d flags %s rv %d gr %d rq %d wait_ast %d\n",
+			i, lk->lksb.sb_lkid, errno, uflags(flags), rv, lk->grmode, lk->rqmode, lk->wait_ast);
 	}
 }
 
@@ -473,7 +494,7 @@
 
 	n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
 
-	while (1) {
+	while (!stress_stop) {
 		process_libdlm();
 
 		if (++n == num)
@@ -515,7 +536,7 @@
 
 			lock(i, rand_int(0, 5));
 			lock_ops++;
-			printf("%8u: lock    %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			printf("%8x: lock    %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 
 		case Op_unlock:
@@ -534,7 +555,7 @@
 
 			unlock(i);
 			unlock_ops++;
-			printf("%8u: unlock  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			printf("%8x: unlock  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 
 		case Op_unlockf:
@@ -549,7 +570,7 @@
 
 			unlockf(i);
 			unlockf_ops++;
-			printf("%8u: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			printf("%8x: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 
 		case Op_cancel:
@@ -564,7 +585,7 @@
 
 			cancel(i);
 			cancel_ops++;
-			printf("%8u: cancel  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			printf("%8x: cancel  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
 			break;
 		}
 
@@ -611,6 +632,40 @@
 		client[i].fd = -1;
 }
 
+void print_commands(void)
+{
+	printf("Usage:\n");
+	printf("max locks (maxn) is %d (x of 0 to %d)\n", maxn, maxn-1);
+	printf("max resources (maxr) is %d, lock x used on resource (x % maxr)\n", maxr);
+	printf("EXIT		 - exit program after unlocking any held locks\n");
+	printf("kill		 - exit program without unlocking any locks\n");
+	printf("lock x mode	 - request/convert lock x\n");
+	printf("unlock x 	 - unlock lock x\n");
+	printf("unlockf x 	 - force unlock lock x\n");
+	printf("cancel x 	 - cancel lock x\n");
+	printf("lock_sync x mode - synchronous version of lock\n");
+	printf("unlock_sync x 	 - synchronous version of unlock\n");
+	printf("ex x		 - equivalent to: lock x 5\n");
+	printf("pr x		 - equivalent to: lock x 3\n");
+	printf("hold		 - for x in 0 to max, lock x 3\n");
+	printf("release		 - for x in 0 to max, unlock x\n");
+	printf("stress n	 - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
+	printf("dump		 - show info for all locks\n");
+	printf("noqueue		 - toggle NOQUEUE flag for all requests\n");
+	printf("persistent	 - toggle PERSISTENT flag for all requests\n");
+	printf("quiet		 - toggle quiet flag\n");
+	printf("verbose		 - toggle verbose flag\n");
+
+	printf("\ncombined operations\n");
+	printf("hold-kill                     - hold; kill\n");
+	printf("release-kill                  - release; kill\n");
+	printf("lock-kill x mode              - lock; kill\n");
+	printf("unlock-kill x                 - unlock; kill\n");
+	printf("lock-cancel x mode msec       - lock; sleep; cancel\n");
+	printf("lock-unlockf x mode msec      - lock; sleep; unlockf\n");
+	printf("lock-cancel-kill x mode msec  - lock; sleep; cancel; kill\n");
+	printf("lock-unlockf-kill x mode msec - lock; sleep; unlockf; kill\n");
+}
 
 void process_command(int *quit)
 {
@@ -735,6 +790,12 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "persistent", 10)) {
+		persistent = !persistent;
+		printf("persistent is %s\n", persistent ? "on" : "off");
+		return;
+	}
+
 	if (!strncmp(cmd, "quiet", 5)) {
 		quiet = !quiet;
 		printf("quiet is %d\n", quiet);
@@ -748,49 +809,91 @@
 	}
 
 	if (!strncmp(cmd, "help", 4)) {
-		printf("Usage:\n");
-		printf("max locks is %d (x of 0 to %d)\n", maxn, maxn-1);
-		printf("EXIT		 - exit program after unlocking any held locks\n");
-		printf("kill		 - exit program without unlocking any locks\n");
-		printf("lock x mode	 - request/convert lock on resource x\n");
-		printf("unlock x 	 - unlock lock on resource x\n");
-		printf("unlockf x 	 - force unlock lock on resource x\n");
-		printf("cancel x 	 - cancel lock on resource x\n");
-		printf("lock_sync x mode - synchronous version of lock\n");
-		printf("unlock_sync x 	 - synchronous version of unlock\n");
-		printf("ex x		 - equivalent to: lock x 5\n");
-		printf("pr x		 - equivalent to: lock x 3\n");
-		printf("hold		 - for x in 0 to max, lock x 3\n");
-		printf("release		 - for x in 0 to max, unlock x\n");
-		printf("stress n	 - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
-		printf("dump		 - show info for all resources\n");
-		printf("noqueue		 - toggle NOQUEUE flag for all requests\n");
-		printf("quiet		 - toggle quiet flag\n");
-		printf("verbose		 - toggle verbose flag\n");
-
-		printf("\ncombined operations\n");
-		printf("hold-kill                     - hold; kill\n");
-		printf("release-kill                  - release; kill\n");
-		printf("lock-kill x mode              - lock; kill\n");
-		printf("unlock-kill x                 - unlock; kill\n");
-		printf("lock-cancel x mode msec       - lock; sleep; cancel\n");
-		printf("lock-unlockf x mode msec      - lock; sleep; unlockf\n");
-		printf("lock-cancel-kill x mode msec  - lock; sleep; cancel; kill\n");
-		printf("lock-unlockf-kill x mode msec - lock; sleep; unlockf; kill\n");
+		print_commands();
 		return;
 	}
 
 	printf("unknown command %s\n", cmd);
 }
 
+void print_usage(void)
+{
+	printf("Options:\n");
+	printf("\n");
+	printf("  -n           The number of resources to work with, default %d\n", MAX_LOCKS);
+	printf("  -i           Iterations in looping stress test, default 0 is no limit\n");
+}
+
+static void decode_arguments(int argc, char **argv)
+{
+	int cont = 1;
+	int optchar;
+
+	while (cont) {
+		optchar = getopt(argc, argv, "n:r:i:hV");
+
+		switch (optchar) {
+
+		case 'n':
+			maxn = atoi(optarg);
+			break;
+
+		case 'r':
+			maxr = atoi(optarg);
+			break;
+
+		case 'i':
+			iterations = atoi(optarg);
+			break;
+
+		case 'h':
+			print_usage();
+			exit(EXIT_SUCCESS);
+			break;
+
+		case 'V':
+			printf("%s (built %s %s)\n", argv[0], __DATE__, __TIME__);
+			/* printf("%s\n", REDHAT_COPYRIGHT); */
+			exit(EXIT_SUCCESS);
+			break;
+
+		case ':':
+		case '?':
+			fprintf(stderr, "Please use '-h' for usage.\n");
+			exit(EXIT_FAILURE);
+			break;
+
+		case EOF:
+			cont = 0;
+			break;
+
+		default:
+			fprintf(stderr, "unknown option: %c\n", optchar);
+			exit(EXIT_FAILURE);
+			break;
+		};
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	struct lk *lk;
 	int i, rv, maxi = 0, quit = 0;
 
-	if (argc > 1)
-		maxn = atoi(argv[1]);
+	decode_arguments(argc, argv);
+
+	if (maxn < maxr) {
+		printf("number of resources must be >= number of locks\n");
+		return -1;
+	}
+	if (maxn % maxr) {
+		printf("number of locks must be multiple of number of resources\n");
+		return -1;
+	}
+
 	printf("maxn = %d\n", maxn);
+	printf("maxr = %d\n", maxr);
+	printf("locks per resource = %d\n", maxn / maxr);
 
 	client_init();
 
@@ -828,10 +931,15 @@
 	client_add(libdlm_fd, &maxi);
 	client_add(STDIN_FILENO, &maxi);
 
+	if (strstr(argv[0], "dlmstress"))
+		stress(iterations);
+
 	printf("Type EXIT to finish, help for usage\n");
 
 	while (1) {
 		rv = poll(pollfd, maxi + 1, -1);
+		if (rv < 0 && errno == EINTR)
+			continue;
 		if (rv < 0)
 			printf("poll error %d errno %d\n", rv, errno);
 



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2007-02-27 18:55 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2007-02-27 18:55 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-02-27 18:55:52

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	lots of changes, biggest is new "stress" test

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.4&r2=1.5

--- cluster/dlm/tests/usertest/dlmtest2.c	2007/01/04 20:34:18	1.4
+++ cluster/dlm/tests/usertest/dlmtest2.c	2007/02/27 18:55:52	1.5
@@ -30,12 +30,28 @@
 
 #include "libdlm.h"
 
+#define MAX_CLIENTS 4
+#define MAX_LOCKS 16
+
 static dlm_lshandle_t *dh;
 static int libdlm_fd;
 static int noqueue = 1;
-
-#define MAX_CLIENTS 4
-#define LOCKS 16
+static int quiet = 1;
+static int verbose = 0;
+static int bast_cb;
+static int maxn = MAX_LOCKS;
+
+#define log_print(fmt, args...) \
+do { \
+	if (!quiet) \
+		printf(fmt , ##args); \
+} while (0)
+
+#define log_verbose(fmt, args...) \
+do { \
+	if (verbose) \
+		printf(fmt , ##args); \
+} while (0)
 
 struct client {
 	int fd;
@@ -46,278 +62,256 @@
 static struct client client[MAX_CLIENTS];
 static struct pollfd pollfd[MAX_CLIENTS];
 
+enum {
+	Op_lock = 1,
+	Op_unlock,
+	Op_unlockf,
+	Op_cancel,
+};
+
 struct lk {
 	int id;
 	int rqmode;
 	int grmode;
 	int wait_ast;
+	int lastop;
+	int last_status;
+	int bast;
 	struct dlm_lksb lksb;
 };
 
-struct lk locks[LOCKS];
-struct lk *locks_flood;
-int locks_flood_n;
-int locks_flood_ast_done;
+struct lk *locks;
 
 void unlock(int i);
+void unlockf(int i);
 
-static int client_add(int fd, int *maxi)
-{
-	int i;
 
-	for (i = 0; i < client_size; i++) {
-		if (client[i].fd == -1) {
-			client[i].fd = fd;
-			pollfd[i].fd = fd;
-			pollfd[i].events = POLLIN;
-			if (i > *maxi)
-				*maxi = i;
-			printf("client %d fd %d added\n", i, fd);
-			return i;
-		}
-	}
-	printf("client add failed\n");
-	return -1;
+int rand_int(int a, int b)
+{
+	return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0)); 
 }
 
-static void client_dead(int ci)
+char *status_str(int status)
 {
-	printf("client %d fd %d dead\n", ci, client[ci].fd);
-	close(client[ci].fd);
-	client[ci].fd = -1;
-	pollfd[ci].fd = -1;
+	static char sts_str[8];
+
+	switch (status) {
+	case 0:
+		return "0      ";
+	case EUNLOCK:
+		return "EUNLOCK";
+	case ECANCEL:
+		return "ECANCEL";
+	case EAGAIN:
+		return "EAGAIN ";
+	case EBUSY:
+		return "EBUSY  ";
+	default:
+		snprintf(sts_str, 8, "%8x", status);
+		return sts_str;
+	}
 }
 
-static void client_init(void)
-{
-	int i;
+char *op_str(int op)
+{
+	switch (op) {
+	case Op_lock:
+		return "lock";
+	case Op_unlock:
+		return "unlock";
+	case Op_unlockf:
+		return "unlockf";
+	case Op_cancel:
+		return "cancel";
+	default:
+		return "unknown";
+	}
+}
 
-	for (i = 0; i < client_size; i++)
-		client[i].fd = -1;
+struct lk *get_lock(int i)
+{
+	if (i < 0)
+		return NULL;
+	if (i >= maxn)
+		return NULL;
+	return &locks[i];
 }
 
-void dump(void)
+int all_unlocks_done(void)
 {
+	struct lk *lk;
 	int i;
 
-	for (i = 0; i < LOCKS; i++) {
-		printf("x %d lkid %x grmode %d rqmode %d wait_ast %d\n", i,
-			locks[i].lksb.sb_lkid,
-			locks[i].grmode,
-			locks[i].rqmode,
-			locks[i].wait_ast);
+	for (i = 0; i < maxn; i++) {
+		lk = get_lock(i);
+		if (lk->grmode == -1 && !lk->wait_ast)
+			continue;
+		return 0;
 	}
+	return 1;
 }
 
-void dump_flood(void)
+void dump(void)
 {
 	struct lk *lk;
 	int i;
 
-	if (!locks_flood_n) {
-		printf("no current locks_flood\n");
-		return;
-	}
-
-	for (i = 0; i < locks_flood_n; i++) {
-		lk = &locks_flood[i];
-		printf("x %d lkid %x grmode %d rqmode %d wait_ast %d\n", i,
+	for (i = 0; i < maxn; i++) {
+		lk = get_lock(i);
+		printf("x %2d lkid %06x gr %2d rq %2d wait_ast %d last op %s\t%s\n",
+			i,
 			lk->lksb.sb_lkid,
 			lk->grmode,
 			lk->rqmode,
-			lk->wait_ast);
+			lk->wait_ast,
+			op_str(lk->lastop),
+			status_str(lk->last_status));
 	}
 }
 
 void bastfn(void *arg)
 {
 	struct lk *lk = arg;
-
-	printf("bast %d\n", lk->id);
-
-	unlock(lk->id);
+	lk->bast = 1;
+	bast_cb = 1;
 }
 
-void astfn(void *arg)
+void do_bast(struct lk *lk)
 {
-	struct lk *lk = arg;
-	int i = lk->id;
+	int skip = 0;
 
-	printf("ast %d sb_lkid %x sb_status %x\n", i, lk->lksb.sb_lkid,
-	       lk->lksb.sb_status);
-
-	if (!lk->wait_ast) {
-		printf("not waiting for ast\n");
-		exit(-1);
+	if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
+		skip = 1;
+	}
+	if (!lk->lksb.sb_lkid) {
+		skip = 1;
 	}
 
-	lk->wait_ast = 0;
+	if (skip)
+		printf("    bast: skip    %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
+	else {
+		printf("    bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
+		unlockf(lk->id);
+		lk->lastop = Op_unlockf;
+	}
+	lk->bast = 0;
+}
 
-	if (lk->lksb.sb_status == EUNLOCK) {
-		memset(&locks[i].lksb, 0, sizeof(struct dlm_lksb));
-		locks[i].grmode = -1;
-	} else if (lk->lksb.sb_status == EAGAIN) {
-		if (locks[i].grmode == -1)
-			memset(&locks[i].lksb, 0, sizeof(struct dlm_lksb));
-	} else {
-		if (lk->lksb.sb_status != 0) {
-			printf("unknown sb_status\n");
-			exit(-1);
-		}
+void do_bast_unlocks(void)
+{
+	struct lk *lk;
+	int i;
 
-		locks[i].grmode = locks[i].rqmode;
+	for (i = 0; i < maxn; i++) {
+		lk = get_lock(i);
+		if (lk->bast)
+			do_bast(lk);
 	}
-
-	locks[i].rqmode = -1;
+	bast_cb = 0;
 }
 
-void bastfn_flood(void *arg)
+void process_libdlm(void)
 {
-	struct lk *lk = arg;
-	printf("bastfn_flood %d\n", lk->id);
+	dlm_dispatch(libdlm_fd);
+	if (bast_cb)
+		do_bast_unlocks();
 }
 
-void astfn_flood(void *arg)
+void astfn(void *arg)
 {
 	struct lk *lk = arg;
-	int i = lk->id, unlock = 0;
+	int i = lk->id;
 
 	if (!lk->wait_ast) {
-		printf("lk %d not waiting for ast\n", lk->id);
-		exit(-1);
+		printf("     ast: %s %3d\t%x: !wait_ast gr %d rq %d last op %s %s\n",
+		       status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid,
+		       lk->grmode, lk->rqmode,
+		       op_str(lk->lastop), status_str(lk->last_status));
 	}
 
-	lk->wait_ast = 0;
+	log_print("     ast: %s %3d\t%x\n",
+		  status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid);
+
+	lk->last_status = lk->lksb.sb_status;
 
 	if (lk->lksb.sb_status == EUNLOCK) {
 		memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
 		lk->grmode = -1;
-		unlock = 1;
-	} else if (lk->lksb.sb_status == EAGAIN) {
-		if (lk->grmode == -1)
-			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
-	} else {
-		if (lk->lksb.sb_status != 0) {
-			printf("lk %d unknown sb_status %d\n", lk->id,
-				lk->lksb.sb_status);
-			exit(-1);
-		}
+		lk->wait_ast = 0;
 
-		lk->grmode = lk->rqmode;
-	}
-
-	lk->rqmode = -1;
-	locks_flood_ast_done++;
-
-	if (locks_flood_ast_done == locks_flood_n) {
-		printf("astfn_flood all %d done\n", locks_flood_n);
-		if (unlock) {
-			free(locks_flood);
-			locks_flood = NULL;
-			locks_flood_n = 0;
+	} else if (lk->lksb.sb_status == ECANCEL) {
+		if (lk->grmode == -1) {
+			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+			lk->wait_ast = 0;
+		} else {
+			if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
+				lk->wait_ast = 0;
 		}
-	}
-}
 
-void astfn_flood_unlock(void *arg)
-{
-	struct lk *lk = arg;
-	int i = lk->id, unlock = 0, rv;
-
-	if (!lk->wait_ast) {
-		printf("lk %d not waiting for ast\n", lk->id);
-		exit(-1);
-	}
-
-	lk->wait_ast = 0;
-
-	if (lk->lksb.sb_status == EUNLOCK) {
-		memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
-		lk->grmode = -1;
-		lk->rqmode = -1;
-		unlock = 1;
-		locks_flood_ast_done++;
 	} else if (lk->lksb.sb_status == EAGAIN) {
-		if (lk->grmode == -1)
+		if (lk->grmode == -1) {
 			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
-		lk->rqmode = -1;
+			lk->wait_ast = 0;
+		} else {
+			if (lk->lastop != Op_unlockf)
+				lk->wait_ast = 0;
+		}
+
 	} else {
 		if (lk->lksb.sb_status != 0) {
-			printf("lk %d unknown sb_status %d\n", lk->id,
-				lk->lksb.sb_status);
+			printf("unknown sb_status %x\n", lk->lksb.sb_status);
 			exit(-1);
 		}
 
-		/* lock completed, now unlock it immediately */
+		if (lk->lastop != Op_unlockf)
+			lk->wait_ast = 0;
 
 		lk->grmode = lk->rqmode;
-		lk->rqmode = -1;
-
-		rv = dlm_ls_unlock(dh, lk->lksb.sb_lkid, 0, &lk->lksb,
-				   (void *)lk);
-		if (!rv) {
-			lk->wait_ast = 1;
-			lk->rqmode = -1;
-		} else {
-			char input[32];
-			printf("astfn_flood_unlock: dlm_ls_unlock: %d rv %d "
-			       "errno %d\n", i, rv, errno);
-			printf("press X to exit, D to dispatch, "
-			       "other to continue\n");
-			fgets(input, 32, stdin);
-			if (input[0] == 'X')
-				exit(-1);
-			else if (input[0] == 'D')
-				dlm_dispatch(libdlm_fd);
-		}
 	}
 
-	if (locks_flood_ast_done == locks_flood_n) {
-		printf("astfn_flood_unlock all %d unlocked\n", locks_flood_n);
-		if (unlock) {
-			free(locks_flood);
-			locks_flood = NULL;
-			locks_flood_n = 0;
-		}
-	}
-}
-
-void process_libdlm(void)
-{
-	dlm_dispatch(libdlm_fd);
+	lk->rqmode = -1;
 }
 
 void lock(int i, int mode)
 {
 	char name[DLM_RESNAME_MAXLEN];
+	struct lk *lk;
 	int flags = 0;
 	int rv;
 
-	if (i < 0 || i >= LOCKS)
+	lk = get_lock(i);
+	if (!lk)
 		return;
 
 	if (noqueue)
 		flags |= LKF_NOQUEUE;
 
-	if (locks[i].lksb.sb_lkid)
+	if (lk->lksb.sb_lkid)
 		flags |= LKF_CONVERT;
 
 	memset(name, 0, sizeof(name));
 	snprintf(name, sizeof(name), "test%d", i);
 
-	printf("dlm_ls_lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
-	       i, locks[i].grmode, mode, flags, locks[i].lksb.sb_lkid, name);
+	log_verbose("lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
+	            i, lk->grmode, mode, flags, lk->lksb.sb_lkid, name);
 
-	rv = dlm_ls_lock(dh, mode, &locks[i].lksb, flags,
-			 name, strlen(name), 0, astfn, (void *) &locks[i],
-			 bastfn, NULL);
+	rv = dlm_ls_lock(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
+			 astfn, (void *) lk, bastfn, NULL);
 	if (!rv) {
-		locks[i].wait_ast = 1;
-		locks[i].rqmode = mode;
+		lk->wait_ast = 1;
+		lk->rqmode = mode;
+	} else if (rv == -1 && errno == EBUSY) {
+		printf("        : lock    %3d\t%x: EBUSY gr %d rq %d wait_ast %d\n",
+			i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, lk->wait_ast);
+	} else {
+		printf("        : lock    %3d\t%x: errno %d gr %d rq %d wait_ast %d\n",
+			i, lk->lksb.sb_lkid, errno, lk->grmode, lk->rqmode, lk->wait_ast);
 	}
 
-	printf("dlm_ls_lock: %d rv %d sb_lkid %x sb_status %x\n",
-	       i, rv, locks[i].lksb.sb_lkid, locks[i].lksb.sb_status);
+	log_verbose("lock: %d rv %d sb_lkid %x sb_status %x\n",
+	            i, rv, lk->lksb.sb_lkid, lk->lksb.sb_status);
+
+	lk->lastop = Op_lock;
 }
 
 void lock_sync(int i, int mode)
@@ -325,35 +319,37 @@
 	char name[DLM_RESNAME_MAXLEN];
 	int flags = 0;
 	int rv;
+	struct lk *lk;
 
-	if (i < 0 || i >= LOCKS)
+	lk = get_lock(i);
+	if (!lk)
 		return;
 
 	if (noqueue)
 		flags |= LKF_NOQUEUE;
 
-	if (locks[i].lksb.sb_lkid)
+	if (lk->lksb.sb_lkid)
 		flags |= LKF_CONVERT;
 
 	memset(name, 0, sizeof(name));
 	snprintf(name, sizeof(name), "test%d", i);
 
-	printf("dlm_ls_lock_wait: %d rqmode %d flags %x lkid %x %s\n",
-	       i, mode, flags, locks[i].lksb.sb_lkid, name);
+	log_verbose("lock_sync: %d rqmode %d flags %x lkid %x %s\n",
+	            i, mode, flags, lk->lksb.sb_lkid, name);
 
-	rv = dlm_ls_lock_wait(dh, mode, &locks[i].lksb, flags,
-			 name, strlen(name), 0, (void *) &locks[i],
+	rv = dlm_ls_lock_wait(dh, mode, &lk->lksb, flags,
+			 name, strlen(name), 0, (void *) lk,
 			 bastfn, NULL);
 
-	printf("dlm_ls_lock_wait: %d rv %d sb_lkid %x sb_status %x\n",
-	       i, rv, locks[i].lksb.sb_lkid, locks[i].lksb.sb_status);
+	log_verbose("lock_sync: %d rv %d sb_lkid %x sb_status %x\n",
+	            i, rv, lk->lksb.sb_lkid, lk->lksb.sb_status);
 
 	if (!rv) {
-		locks[i].grmode = mode;
-		locks[i].rqmode = -1;
+		lk->grmode = mode;
+		lk->rqmode = -1;
 	} else if (rv == EAGAIN) {
-		if (locks[i].grmode == -1)
-			memset(&locks[i].lksb, 0, sizeof(struct dlm_lksb));
+		if (lk->grmode == -1)
+			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
 	} else {
 		printf("unknown rv %d\n", rv);
 		exit(-1);
@@ -364,275 +360,271 @@
 {
 	int i;
 
-	for (i = 0; i < LOCKS; i++)
+	for (i = 0; i < maxn; i++)
 		lock(i, mode);
 }
 
-void lock_flood(int n, int mode)
+void _unlock(int i, uint32_t flags)
 {
 	struct lk *lk;
-	char name[DLM_RESNAME_MAXLEN];
-	int flags = 0, rv, i;
-
-	if (noqueue)
-		flags |= LKF_NOQUEUE;
-
-	if (locks_flood) {
-		printf("unlock_flood required before another lock_flood\n");
-		return;
-	}
-
-	locks_flood = malloc(n * sizeof(struct lk));
-	if (!locks_flood) {
-		printf("no mem for %d locks\n", n);
-		return;
-	}
-	locks_flood_n = n;
-	locks_flood_ast_done = 0;
-	memset(locks_flood, 0, sizeof(*locks_flood));
-
-	for (i = 0; i < n; i++) {
-		memset(name, 0, sizeof(name));
-		snprintf(name, sizeof(name), "testflood%d", i);
-		lk = &locks_flood[i];
-
-		rv = dlm_ls_lock(dh, mode, &lk->lksb, flags,
-			 name, strlen(name), 0, astfn_flood, (void *) lk,
-			 bastfn_flood, NULL);
-		if (!rv) {
-			lk->wait_ast = 1;
-			lk->rqmode = mode;
-		}
-	}
-}
-
-void unlock(int i)
-{
 	uint32_t lkid;
 	int rv;
 
-	if (i < 0 || i >= LOCKS)
+	lk = get_lock(i);
+	if (!lk)
 		return;
 
-	lkid = locks[i].lksb.sb_lkid;
-	if (!lkid) {
-		printf("unlock %d skip zero lkid\n", i);
+	lkid = lk->lksb.sb_lkid;
+	if (!lkid)
 		return;
-	}
 
-	printf("dlm_ls_unlock: %d lkid %x\n", i, lkid);
+	log_verbose("unlock: %d lkid %x flags %x\n", i, lkid, flags);
 
-	rv = dlm_ls_unlock(dh, lkid, 0, &locks[i].lksb, &locks[i]);
+	rv = dlm_ls_unlock(dh, lkid, flags, &lk->lksb, lk);
 	if (!rv) {
-		locks[i].wait_ast = 1;
-		locks[i].rqmode = -1;
-		printf("dlm_ls_unlock: %d\n", i);
+		lk->wait_ast = 1;
+	} else if (rv == -1 && errno == EBUSY) {
+		printf("unlock: EBUSY %d %x flags %x gr %d rq %d wait_ast %d\n",
+			i, lk->lksb.sb_lkid, flags, lk->grmode, lk->rqmode, lk->wait_ast);
 	} else {
+		printf("unlock: error %d %x flags %x rv %d errno %d gr %d rq %d wait_ast %d\n",
+		       i, lk->lksb.sb_lkid, flags, rv, errno, lk->grmode, lk->rqmode,
+		       lk->wait_ast);
+#if 0
 		char input[32];
-		printf("dlm_ls_unlock: %d rv %d errno %d\n", i, rv, errno);
-		dump();
 		printf("press X to exit, D to dispatch, other to continue\n");
 		fgets(input, 32, stdin);
 		if (input[0] == 'X')
 			exit(-1);
 		else if (input[0] == 'D')
 			dlm_dispatch(libdlm_fd);
+#endif
 	}
 }
 
+void unlock(int i)
+{
+	struct lk *lk = get_lock(i);
+	_unlock(i, 0);
+	lk->rqmode = -1;
+	lk->lastop = Op_unlock;
+}
+
+void unlockf(int i)
+{
+	struct lk *lk = get_lock(i);
+	_unlock(i, LKF_FORCEUNLOCK);
+	lk->rqmode = -1;
+	lk->lastop = Op_unlockf;
+}
+
+void cancel(int i)
+{
+	struct lk *lk = get_lock(i);
+	_unlock(i, LKF_CANCEL);
+	lk->lastop = Op_cancel;
+}
+
 void unlock_sync(int i)
 {
 	uint32_t lkid;
 	int rv;
+	struct lk *lk;
 
-	if (i < 0 || i >= LOCKS)
+	lk = get_lock(i);
+	if (!lk)
 		return;
 
-	lkid = locks[i].lksb.sb_lkid;
+	lkid = lk->lksb.sb_lkid;
 	if (!lkid) {
-		printf("unlock %d skip zero lkid\n", i);
+		log_print("unlock %d skip zero lkid\n", i);
 		return;
 	}
 
-	printf("dlm_ls_unlock_wait: %d lkid %x\n", i, lkid);
+	log_verbose("unlock_sync: %d lkid %x\n", i, lkid);
 
-	rv = dlm_ls_unlock_wait(dh, lkid, 0, &locks[i].lksb);
+	rv = dlm_ls_unlock_wait(dh, lkid, 0, &lk->lksb);
 
-	printf("dlm_ls_unlock_wait: %d rv %d sb_status %x\n", i, rv,
-	       locks[i].lksb.sb_status);
+	log_verbose("unlock_sync: %d rv %d sb_status %x\n", i, rv,
+	            lk->lksb.sb_status);
 
-	memset(&locks[i].lksb, 0, sizeof(struct dlm_lksb));
-	locks[i].grmode = -1;
-	locks[i].rqmode = -1;
+	memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+	lk->grmode = -1;
+	lk->rqmode = -1;
 }
 
 void unlock_all(void)
 {
+	struct lk *lk;
 	int i;
 
-	for (i = 0; i < LOCKS; i++)
+	for (i = 0; i < maxn; i++) {
+		lk = get_lock(i);
 		unlock(i);
+		lk->lastop = Op_unlock;
+	}
 }
 
-void unlock_flood(void)
+void stress(int num)
 {
+	int i, o, op, skip;
+	unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
 	struct lk *lk;
-	uint32_t lkid;
-	int rv, i;
 
-	if (!locks_flood)
-		return;
+	n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
 
-	if (locks_flood_ast_done != locks_flood_n)
-		printf("warning: locks_flood_ast_done %d locks_flood_n %d\n",
-			locks_flood_ast_done, locks_flood_n);
+	while (1) {
+		process_libdlm();
 
-	locks_flood_ast_done = 0;
+		if (++n == num)
+			break;
 
-	for (i = 0; i < locks_flood_n; i++) {
-		lk = &locks_flood[i];
-		lkid = lk->lksb.sb_lkid;
-		if (!lkid) {
-			printf("unlock_flood %d skip zero lkid\n", i);
+		i = rand_int(0, maxn-1);
+		lk = get_lock(i);
+		if (!lk)
 			continue;
-		}
 
-		rv = dlm_ls_unlock(dh, lkid, 0, &lk->lksb, (void *)lk);
-		if (!rv) {
-			lk->wait_ast = 1;
-			lk->rqmode = -1;
-		} else {
-			char input[32];
-			printf("flood: dlm_ls_unlock: %d rv %d errno %d\n",
-				i, rv, errno);
-			printf("press X to exit, D to dispatch, "
-			       "other to continue\n");
-			fgets(input, 32, stdin);
-			if (input[0] == 'X')
-				exit(-1);
-			else if (input[0] == 'D')
-				dlm_dispatch(libdlm_fd);
+		o = rand_int(0, 5);
+		switch (o) {
+		case 0:
+		case 1:
+		case 2:
+			op = Op_lock;
+			break;
+		case 3:
+			op = Op_unlock;
+			break;
+		case 4:
+			op = Op_unlockf;
+			break;
+		case 5:
+			op = Op_cancel;
+			break;
 		}
-	}
-}
 
-void flood(int n, int mode)
-{
-	struct lk *lk;
-	char name[DLM_RESNAME_MAXLEN];
-	int flags = 0, rv, i;
+		skip = 0;
 
-	if (noqueue)
-		flags |= LKF_NOQUEUE;
+		switch (op) {
+		case Op_lock:
+			if (lk->wait_ast) {
+				skip = 1;
+				break;
+			}
 
-	if (locks_flood) {
-		printf("unlock_flood required first\n");
-		return;
-	}
+			noqueue = !!o;
 
-	locks_flood = malloc(n * sizeof(struct lk));
-	if (!locks_flood) {
-		printf("no mem for %d locks\n", n);
-		return;
-	}
-	locks_flood_n = n;
-	locks_flood_ast_done = 0;
-	memset(locks_flood, 0, sizeof(*locks_flood));
+			lock(i, rand_int(0, 5));
+			lock_ops++;
+			printf("%8u: lock    %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			break;
 
-	for (i = 0; i < n; i++) {
-		memset(name, 0, sizeof(name));
-		snprintf(name, sizeof(name), "testflood%d", i);
-		lk = &locks_flood[i];
+		case Op_unlock:
+			if (lk->wait_ast) {
+				skip = 1;
+				break;
+			}
+			if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
+				skip = 1;
+				break;
+			}
+			if (!lk->lksb.sb_lkid) {
+				skip = 1;
+				break;
+			}
 
-		rv = dlm_ls_lock(dh, mode, &lk->lksb, flags,
-			 name, strlen(name), 0, astfn_flood_unlock, (void *) lk,
-			 bastfn_flood, NULL);
-		if (!rv) {
-			lk->wait_ast = 1;
-			lk->rqmode = mode;
-		}
-	}
-}
+			unlock(i);
+			unlock_ops++;
+			printf("%8u: unlock  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			break;
 
-void loop(int i, int num)
-{
-	int n;
+		case Op_unlockf:
+			if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
+				skip = 1;
+				break;
+			}
+			if (!lk->lksb.sb_lkid) {
+				skip = 1;
+				break;
+			}
 
-	for (n = 0; n < num; n++) {
-		lock(i, LKM_PRMODE);
-		dlm_dispatch(libdlm_fd);
-		unlock(i);
-		dlm_dispatch(libdlm_fd);
-		/*
-		lock_sync(i, LKM_PRMODE);
-		unlock_sync(i);
-		*/
-	}
-}
+			unlockf(i);
+			unlockf_ops++;
+			printf("%8u: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			break;
 
-int rand_int(int a, int b)
-{
-	return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0)); 
-}
+		case Op_cancel:
+			if (!lk->wait_ast) {
+				skip = 1;
+				break;
+			}
+			if (lk->lastop > Op_lock) {
+				skip = 1;
+				break;
+			}
 
-void hammer(int num)
-{
-	int n, i, busy = 0, lock_ops = 0, unlock_ops = 0;
+			cancel(i);
+			cancel_ops++;
+			printf("%8u: cancel  %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+			break;
+		}
 
-	while (1) {
-		dlm_dispatch(libdlm_fd);
+		if (skip)
+			skips++;
+	}
 
-		i = rand_int(0, LOCKS-1);
+	printf("skip %d lock %d unlock %d unlockf %d cancel %d\n",
+		skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
+}
 
-		if (locks[i].wait_ast) {
-			busy++;
-			continue;
-		}
+static int client_add(int fd, int *maxi)
+{
+	int i;
 
-		if (locks[i].grmode == -1) {
-			lock(i, rand_int(0, 5));
-			lock_ops++;
-		} else {
-			unlock(i);
-			unlock_ops++;
+	for (i = 0; i < client_size; i++) {
+		if (client[i].fd == -1) {
+			client[i].fd = fd;
+			pollfd[i].fd = fd;
+			pollfd[i].events = POLLIN;
+			if (i > *maxi)
+				*maxi = i;
+			printf("client %d fd %d added\n", i, fd);
+			return i;
 		}
-
-		if (++n == num)
-			break;
 	}
+	printf("client add failed\n");
+	return -1;
+}
 
-	printf("hammer: locks %d unlocks %d busy %d\n",
-		lock_ops, unlock_ops, busy);
-
-	unlock_all();;
+static void client_dead(int ci)
+{
+	printf("client %d fd %d dead\n", ci, client[ci].fd);
+	close(client[ci].fd);
+	client[ci].fd = -1;
+	pollfd[ci].fd = -1;
 }
 
-int all_unlocks_done(void)
+static void client_init(void)
 {
 	int i;
 
-	for (i = 0; i < LOCKS; i++) {
-		if (locks[i].grmode == -1 && !locks[i].wait_ast)
-			continue;
-		return 0;
-	}
-	return 1;
+	for (i = 0; i < client_size; i++)
+		client[i].fd = -1;
 }
 
+
 void process_command(int *quit)
 {
 	char inbuf[132];
 	char cmd[32];
-	int x = 0, y = 0;
+	int x = 0, y = 0, z = 0;
 
 	fgets(inbuf, sizeof(inbuf), stdin);
 
-	sscanf(inbuf, "%s %d %d", cmd, &x, &y);
+	sscanf(inbuf, "%s %d %d", cmd, &x, &y, &z);
 
 	if (!strncmp(cmd, "EXIT", 4)) {
 		*quit = 1;
 		unlock_all();
-		unlock_flood();
 		return;
 	}
 
@@ -651,6 +643,16 @@
 		return;
 	}
 
+	if (!strncmp(cmd, "unlockf", 7) && strlen(cmd) == 7) {
+		unlockf(x);
+		return;
+	}
+
+	if (!strncmp(cmd, "cancel", 6) && strlen(cmd) == 6) {
+		cancel(x);
+		return;
+	}
+
 	if (!strncmp(cmd, "lock_sync", 9) && strlen(cmd) == 9) {
 		lock_sync(x, y);
 		return;
@@ -673,22 +675,20 @@
 		exit(0);
 	}
 
-	if (!strncmp(cmd, "lock_flood", 10) && strlen(cmd) == 10) {
-		lock_flood(x, y);
+	if (!strncmp(cmd, "lock-cancel", 11) && strlen(cmd) == 11) {
+		lock(x, y);
+		/* usleep(1000 * z); */
+		cancel(x);
 		return;
 	}
 
-	if (!strncmp(cmd, "unlock_flood", 12) && strlen(cmd) == 12) {
-		unlock_flood();
+	if (!strncmp(cmd, "lock-unlockf", 12) && strlen(cmd) == 12) {
+		lock(x, y);
+		/* usleep(1000 * z); */
+		unlockf(x);
 		return;
 	}
 
-	if (!strncmp(cmd, "unlock_flood-kill", 17) && strlen(cmd) == 17) {
-		unlock_flood();
-		printf("process exiting\n");
-		exit(0);
-	}
-
 	if (!strncmp(cmd, "ex", 2)) {
 		lock(x, LKM_EXMODE);
 		return;
@@ -699,71 +699,84 @@
 		return;
 	}
 
-	if (!strncmp(cmd, "flood", 5)) {
-		flood(x, y);
+	if (!strncmp(cmd, "hold", 4) && strlen(cmd) == 4) {
+		lock_all(LKM_PRMODE);
 		return;
 	}
 
-	if (!strncmp(cmd, "hold", 4)) {
+	if (!strncmp(cmd, "hold-kill", 9) && strlen(cmd) == 9) {
 		lock_all(LKM_PRMODE);
-		return;
+		exit(0);
 	}
 
-	if (!strncmp(cmd, "release", 6)) {
+	if (!strncmp(cmd, "release", 7) && strlen(cmd) == 7) {
 		unlock_all();
 		return;
 	}
 
+	if (!strncmp(cmd, "release-kill", 12) && strlen(cmd) == 12) {
+		unlock_all();
+		exit(0);
+	}
+
 	if (!strncmp(cmd, "dump", 4) && strlen(cmd) == 4) {
 		dump();
 		return;
 	}
 
-	if (!strncmp(cmd, "dump_flood", 10) && strlen(cmd) == 10) {
-		dump_flood();
+	if (!strncmp(cmd, "stress", 6)) {
+		stress(x);
 		return;
 	}
 
-	if (!strncmp(cmd, "loop", 4)) {
-		loop(x, y);
+	if (!strncmp(cmd, "noqueue", 7)) {
+		noqueue = !noqueue;
+		printf("noqueue is %s\n", noqueue ? "on" : "off");
 		return;
 	}
 
-	if (!strncmp(cmd, "hammer", 6)) {
-		hammer(x);
+	if (!strncmp(cmd, "quiet", 5)) {
+		quiet = !quiet;
+		printf("quiet is %d\n", quiet);
 		return;
 	}
 
-	if (!strncmp(cmd, "noqueue", 7)) {
-		noqueue = !noqueue;
-		printf("noqueue is %s\n", noqueue ? "on" : "off");
+	if (!strncmp(cmd, "verbose", 7)) {
+		verbose = !verbose;
+		printf("verbose is %d\n", verbose);
 		return;
 	}
 
 	if (!strncmp(cmd, "help", 4)) {
 		printf("Usage:\n");
-		printf("MAX locks is %d (x of 0 to %d)\n", LOCKS, LOCKS-1);
+		printf("max locks is %d (x of 0 to %d)\n", maxn, maxn-1);
 		printf("EXIT		 - exit program after unlocking any held locks\n");
 		printf("kill		 - exit program without unlocking any locks\n");
 		printf("lock x mode	 - request/convert lock on resource x\n");
 		printf("unlock x 	 - unlock lock on resource x\n");
+		printf("unlockf x 	 - force unlock lock on resource x\n");
+		printf("cancel x 	 - cancel lock on resource x\n");
 		printf("lock_sync x mode - synchronous version of lock\n");
 		printf("unlock_sync x 	 - synchronous version of unlock\n");
-		printf("lock-kill x mode - request/convert lock on resource x, then exit\n");
-		printf("unlock-kill x	 - unlock lock on resource x, then exit\n");
-		printf("lock_flood n mode - request n locks (in flood namespace)\n");
-		printf("unlock_flood     - unlock all from lock_flood\n");
-		printf("unlock_flood-kill - unlock all from lock_flood and exit\n");
 		printf("ex x		 - equivalent to: lock x 5\n");
 		printf("pr x		 - equivalent to: lock x 3\n");
-		printf("flood n mode     - request n locks, unlock each as it completes\n");
-		printf("hold		 - for x in 0 to MAX, lock x 3\n");
-		printf("release		 - for x in 0 to MAX, unlock x\n");
+		printf("hold		 - for x in 0 to max, lock x 3\n");
+		printf("release		 - for x in 0 to max, unlock x\n");
+		printf("stress n	 - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
 		printf("dump		 - show info for all resources\n");
-		printf("dump_flood	 - show info for all flood resources\n");
-		printf("loop x n	 - lock_sync x PR / unlock_sync x, n times\n");
-		printf("hammer n	 - loop doing random lock/unlock on all locks, n times\n");
-		printf("noqueue		 - toggle NOQUEUE flag for all requests\n"); 
+		printf("noqueue		 - toggle NOQUEUE flag for all requests\n");
+		printf("quiet		 - toggle quiet flag\n");
+		printf("verbose		 - toggle verbose flag\n");
+
+		printf("\ncombined operations\n");
+		printf("hold-kill                     - hold; kill\n");
+		printf("release-kill                  - release; kill\n");
+		printf("lock-kill x mode              - lock; kill\n");
+		printf("unlock-kill x                 - unlock; kill\n");
+		printf("lock-cancel x mode msec       - lock; sleep; cancel\n");
+		printf("lock-unlockf x mode msec      - lock; sleep; unlockf\n");
+		printf("lock-cancel-kill x mode msec  - lock; sleep; cancel; kill\n");
+		printf("lock-unlockf-kill x mode msec - lock; sleep; unlockf; kill\n");
 		return;
 	}
 
@@ -772,15 +785,28 @@
 
 int main(int argc, char *argv[])
 {
+	struct lk *lk;
 	int i, rv, maxi = 0, quit = 0;
 
+	if (argc > 1)
+		maxn = atoi(argv[1]);
+	printf("maxn = %d\n", maxn);
+
 	client_init();
 
-	memset(&locks, 0, sizeof(locks));
-	for (i = 0; i < LOCKS; i++) {
-		locks[i].id = i;
-		locks[i].grmode = -1;
-		locks[i].rqmode = -1;
+	locks = malloc(maxn * sizeof(struct lk));
+	if (!locks) {
+		printf("no mem for %d locks\n", maxn);
+		return;
+	}
+	memset(locks, 0, sizeof(*locks));
+
+	lk = locks;
+	for (i = 0; i < maxn; i++) {
+		lk->id = i;
+		lk->grmode = -1;
+		lk->rqmode = -1;
+		lk++;
 	}
 
 	printf("Joining test lockspace...\n");



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2006-12-12 21:17 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2006-12-12 21:17 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2006-12-12 21:17:56

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	add lock_flood/unlock_flood/unlock_flood-exit commands to test doing
	large volumes of locks/unlocks

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.2&r2=1.3

--- cluster/dlm/tests/usertest/dlmtest2.c	2006/12/08 19:25:27	1.2
+++ cluster/dlm/tests/usertest/dlmtest2.c	2006/12/12 21:17:56	1.3
@@ -35,7 +35,7 @@
 static int noqueue = 1;
 
 #define MAX_CLIENTS 4
-#define LOCKS 4
+#define LOCKS 16
 
 struct client {
 	int fd;
@@ -55,6 +55,9 @@
 };
 
 struct lk locks[LOCKS];
+struct lk *locks_flood;
+int locks_flood_n;
+int locks_flood_ast_done;
 
 void unlock(int i);
 
@@ -106,6 +109,26 @@
 	}
 }
 
+void dump_flood(void)
+{
+	struct lk *lk;
+	int i;
+
+	if (!locks_flood_n) {
+		printf("no current locks_flood\n");
+		return;
+	}
+
+	for (i = 0; i < locks_flood_n; i++) {
+		lk = &locks_flood[i];
+		printf("x %d lkid %x grmode %d rqmode %d wait_ast %d\n", i,
+			lk->lksb.sb_lkid,
+			lk->grmode,
+			lk->rqmode,
+			lk->wait_ast);
+	}
+}
+
 void bastfn(void *arg)
 {
 	struct lk *lk = arg;
@@ -148,6 +171,54 @@
 	locks[i].rqmode = -1;
 }
 
+void bastfn_flood(void *arg)
+{
+	struct lk *lk = arg;
+	printf("bastfn_flood %d\n", lk->id);
+}
+
+void astfn_flood(void *arg)
+{
+	struct lk *lk = arg;
+	int i = lk->id, unlock = 0;
+
+	if (!lk->wait_ast) {
+		printf("lk %d not waiting for ast\n", lk->id);
+		exit(-1);
+	}
+
+	lk->wait_ast = 0;
+
+	if (lk->lksb.sb_status == EUNLOCK) {
+		memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+		lk->grmode = -1;
+		unlock = 1;
+	} else if (lk->lksb.sb_status == EAGAIN) {
+		if (lk->grmode == -1)
+			memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+	} else {
+		if (lk->lksb.sb_status != 0) {
+			printf("lk %d unknown sb_status %d\n", lk->id,
+				lk->lksb.sb_status);
+			exit(-1);
+		}
+
+		lk->grmode = lk->rqmode;
+	}
+
+	lk->rqmode = -1;
+	locks_flood_ast_done++;
+
+	if (locks_flood_ast_done == locks_flood_n) {
+		printf("astfn_flood all %d done\n", locks_flood_n);
+		if (unlock) {
+			free(locks_flood);
+			locks_flood = NULL;
+			locks_flood_n = 0;
+		}
+	}
+}
+
 void process_libdlm(void)
 {
 	dlm_dispatch(libdlm_fd);
@@ -234,6 +305,44 @@
 		lock(i, mode);
 }
 
+void lock_flood(int n, int mode)
+{
+	struct lk *lk;
+	char name[DLM_RESNAME_MAXLEN];
+	int flags = 0, rv, i;
+
+	if (noqueue)
+		flags |= LKF_NOQUEUE;
+
+	if (locks_flood) {
+		printf("unlock_flood required before another lock_flood\n");
+		return;
+	}
+
+	locks_flood = malloc(n * sizeof(struct lk));
+	if (!locks_flood) {
+		printf("no mem for %d locks\n", n);
+		return;
+	}
+	locks_flood_n = n;
+	locks_flood_ast_done = 0;
+	memset(locks_flood, 0, sizeof(*locks_flood));
+
+	for (i = 0; i < n; i++) {
+		memset(name, 0, sizeof(name));
+		snprintf(name, sizeof(name), "testflood%d", i);
+		lk = &locks_flood[i];
+
+		rv = dlm_ls_lock(dh, mode, &lk->lksb, flags,
+			 name, strlen(name), 0, astfn_flood, (void *) lk,
+			 bastfn_flood, NULL);
+		if (!rv) {
+			lk->wait_ast = 1;
+			lk->rqmode = mode;
+		}
+	}
+}
+
 void unlock(int i)
 {
 	uint32_t lkid;
@@ -302,19 +411,61 @@
 		unlock(i);
 }
 
+void unlock_flood(void)
+{
+	struct lk *lk;
+	uint32_t lkid;
+	int rv, i;
+
+	if (!locks_flood)
+		return;
+
+	if (locks_flood_ast_done != locks_flood_n)
+		printf("warning: locks_flood_ast_done %d locks_flood_n %d\n",
+			locks_flood_ast_done, locks_flood_n);
+
+	locks_flood_ast_done = 0;
+
+	for (i = 0; i < locks_flood_n; i++) {
+		lk = &locks_flood[i];
+		lkid = lk->lksb.sb_lkid;
+		if (!lkid) {
+			printf("unlock_flood %d skip zero lkid\n", i);
+			continue;
+		}
+
+		rv = dlm_ls_unlock(dh, lkid, 0, &lk->lksb, (void *)lk);
+		if (!rv) {
+			lk->wait_ast = 1;
+			lk->rqmode = -1;
+		} else {
+			char input[32];
+			printf("flood: dlm_ls_unlock: %d rv %d errno %d\n",
+				i, rv, errno);
+			printf("press X to exit, D to dispatch, "
+			       "other to continue\n");
+			fgets(input, 32, stdin);
+			if (input[0] == 'X')
+				exit(-1);
+			else if (input[0] == 'D')
+				dlm_dispatch(libdlm_fd);
+		}
+	}
+}
+
 void loop(int i, int num)
 {
 	int n;
 
 	for (n = 0; n < num; n++) {
-		/*
 		lock(i, LKM_PRMODE);
 		dlm_dispatch(libdlm_fd);
 		unlock(i);
 		dlm_dispatch(libdlm_fd);
-		*/
+		/*
 		lock_sync(i, LKM_PRMODE);
 		unlock_sync(i);
+		*/
 	}
 }
 
@@ -380,6 +531,7 @@
 	if (!strncmp(cmd, "EXIT", 4)) {
 		*quit = 1;
 		unlock_all();
+		unlock_flood();
 		return;
 	}
 
@@ -420,6 +572,22 @@
 		exit(0);
 	}
 
+	if (!strncmp(cmd, "lock_flood", 10) && strlen(cmd) == 10) {
+		lock_flood(x, y);
+		return;
+	}
+
+	if (!strncmp(cmd, "unlock_flood", 12) && strlen(cmd) == 12) {
+		unlock_flood();
+		return;
+	}
+
+	if (!strncmp(cmd, "unlock_flood-kill", 17) && strlen(cmd) == 17) {
+		unlock_flood();
+		printf("process exiting\n");
+		exit(0);
+	}
+
 	if (!strncmp(cmd, "ex", 2)) {
 		lock(x, LKM_EXMODE);
 		return;
@@ -440,11 +608,16 @@
 		return;
 	}
 
-	if (!strncmp(cmd, "dump", 4)) {
+	if (!strncmp(cmd, "dump", 4) && strlen(cmd) == 4) {
 		dump();
 		return;
 	}
 
+	if (!strncmp(cmd, "dump_flood", 10) && strlen(cmd) == 10) {
+		dump_flood();
+		return;
+	}
+
 	if (!strncmp(cmd, "loop", 4)) {
 		loop(x, y);
 		return;
@@ -472,11 +645,15 @@
 		printf("unlock_sync x 	 - synchronous version of unlock\n");
 		printf("lock-kill x mode - request/convert lock on resource x, then exit\n");
 		printf("unlock-kill x	 - unlock lock on resource x, then exit\n");
+		printf("lock_flood n mode - request n locks (in flood namespace)\n");
+		printf("unlock_flood     - unlock all from lock_flood\n");
+		printf("unlock_flood-kill - unlock all from lock_flood and exit\n");
 		printf("ex x		 - equivalent to: lock x 5\n");
 		printf("pr x		 - equivalent to: lock x 3\n");
 		printf("hold		 - for x in 0 to MAX, lock x 3\n");
 		printf("release		 - for x in 0 to MAX, unlock x\n");
 		printf("dump		 - show info for all resources\n");
+		printf("dump_flood	 - show info for all flood resources\n");
 		printf("loop x n	 - lock_sync x PR / unlock_sync x, n times\n");
 		printf("hammer n	 - loop doing random lock/unlock on all locks, n times\n");
 		printf("noqueue		 - toggle NOQUEUE flag for all requests\n"); 



^ permalink raw reply	[flat|nested] 11+ messages in thread
* [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
@ 2006-12-08 19:25 teigland
  0 siblings, 0 replies; 11+ messages in thread
From: teigland @ 2006-12-08 19:25 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2006-12-08 19:25:28

Modified files:
	dlm/tests/usertest: dlmtest2.c 

Log message:
	tidy up some prints

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.1&r2=1.2

--- cluster/dlm/tests/usertest/dlmtest2.c	2006/12/07 19:50:49	1.1
+++ cluster/dlm/tests/usertest/dlmtest2.c	2006/12/08 19:25:27	1.2
@@ -98,7 +98,7 @@
 	int i;
 
 	for (i = 0; i < LOCKS; i++) {
-		printf("i %d lkid %x grmode %d rqmode %d wait_ast %d\n", i,
+		printf("x %d lkid %x grmode %d rqmode %d wait_ast %d\n", i,
 			locks[i].lksb.sb_lkid,
 			locks[i].grmode,
 			locks[i].rqmode,
@@ -159,6 +159,9 @@
 	int flags = 0;
 	int rv;
 
+	if (i < 0 || i >= LOCKS)
+		return;
+
 	if (noqueue)
 		flags |= LKF_NOQUEUE;
 
@@ -189,6 +192,9 @@
 	int flags = 0;
 	int rv;
 
+	if (i < 0 || i >= LOCKS)
+		return;
+
 	if (noqueue)
 		flags |= LKF_NOQUEUE;
 
@@ -233,6 +239,9 @@
 	uint32_t lkid;
 	int rv;
 
+	if (i < 0 || i >= LOCKS)
+		return;
+
 	lkid = locks[i].lksb.sb_lkid;
 	if (!lkid) {
 		printf("unlock %d skip zero lkid\n", i);
@@ -264,6 +273,9 @@
 	uint32_t lkid;
 	int rv;
 
+	if (i < 0 || i >= LOCKS)
+		return;
+
 	lkid = locks[i].lksb.sb_lkid;
 	if (!lkid) {
 		printf("unlock %d skip zero lkid\n", i);
@@ -451,6 +463,7 @@
 
 	if (!strncmp(cmd, "help", 4)) {
 		printf("Usage:\n");
+		printf("MAX locks is %d (x of 0 to %d)\n", LOCKS, LOCKS-1);
 		printf("EXIT		 - exit program after unlocking any held locks\n");
 		printf("kill		 - exit program without unlocking any locks\n");
 		printf("lock x mode	 - request/convert lock on resource x\n");
@@ -465,7 +478,7 @@
 		printf("release		 - for x in 0 to MAX, unlock x\n");
 		printf("dump		 - show info for all resources\n");
 		printf("loop x n	 - lock_sync x PR / unlock_sync x, n times\n");
-		printf("hammer n	 - loop doing random lock/unlock on all locks, n times");
+		printf("hammer n	 - loop doing random lock/unlock on all locks, n times\n");
 		printf("noqueue		 - toggle NOQUEUE flag for all requests\n"); 
 		return;
 	}
@@ -486,6 +499,8 @@
 		locks[i].rqmode = -1;
 	}
 
+	printf("Joining test lockspace...\n");
+
 	dh = dlm_create_lockspace("test", 0600);
 	if (!dh) {
 		printf("dlm_create_lockspace error %d %d\n", (int) dh, errno);
@@ -503,7 +518,7 @@
 	client_add(libdlm_fd, &maxi);
 	client_add(STDIN_FILENO, &maxi);
 
-	printf("Type EXIT to finish\n");
+	printf("Type EXIT to finish, help for usage\n");
 
 	while (1) {
 		rv = poll(pollfd, maxi + 1, -1);



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-02-21 17:49 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-04 20:34 [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c teigland
  -- strict thread matches above, loose matches on Subject: below --
2008-02-21 17:49 teigland
2008-01-17 21:49 teigland
2007-08-23 19:13 teigland
2007-08-22 14:01 teigland
2007-05-30 19:31 teigland
2007-04-27 19:09 teigland
2007-03-27 19:04 teigland
2007-02-27 18:55 teigland
2006-12-12 21:17 teigland
2006-12-08 19:25 teigland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).