[Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c

teigland at sourceware.org teigland at sourceware.org
Tue Dec 12 21:17:56 UTC 2006


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"); 




More information about the Cluster-devel mailing list