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

teigland at sourceware.org teigland at sourceware.org
Wed May 30 19:31:28 UTC 2007


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;
 }




More information about the Cluster-devel mailing list