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

teigland at sourceware.org teigland at sourceware.org
Thu Dec 7 19:50:50 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2006-12-07 19:50:49

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

Log message:
	very useful testing program I wrote a long time ago

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

/cvs/cluster/cluster/dlm/tests/usertest/dlmtest2.c,v  -->  standard output
revision 1.1
--- cluster/dlm/tests/usertest/dlmtest2.c
+++ -	2006-12-07 19:50:49.854286000 +0000
@@ -0,0 +1,540 @@
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) 2006 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
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <time.h>
+#include <syslog.h>
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+
+#include "libdlm.h"
+
+static dlm_lshandle_t *dh;
+static int libdlm_fd;
+static int noqueue = 1;
+
+#define MAX_CLIENTS 4
+#define LOCKS 4
+
+struct client {
+	int fd;
+	char type[32];
+};
+
+static int client_size = MAX_CLIENTS;
+static struct client client[MAX_CLIENTS];
+static struct pollfd pollfd[MAX_CLIENTS];
+
+struct lk {
+	int id;
+	int rqmode;
+	int grmode;
+	int wait_ast;
+	struct dlm_lksb lksb;
+};
+
+struct lk locks[LOCKS];
+
+void unlock(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;
+}
+
+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;
+}
+
+static void client_init(void)
+{
+	int i;
+
+	for (i = 0; i < client_size; i++)
+		client[i].fd = -1;
+}
+
+void dump(void)
+{
+	int i;
+
+	for (i = 0; i < LOCKS; i++) {
+		printf("i %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);
+	}
+}
+
+void bastfn(void *arg)
+{
+	struct lk *lk = arg;
+
+	printf("bast %d\n", lk->id);
+
+	unlock(lk->id);
+}
+
+void astfn(void *arg)
+{
+	struct lk *lk = arg;
+	int i = lk->id;
+
+	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);
+	}
+
+	lk->wait_ast = 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);
+		}
+
+		locks[i].grmode = locks[i].rqmode;
+	}
+
+	locks[i].rqmode = -1;
+}
+
+void process_libdlm(void)
+{
+	dlm_dispatch(libdlm_fd);
+}
+
+void lock(int i, int mode)
+{
+	char name[DLM_RESNAME_MAXLEN];
+	int flags = 0;
+	int rv;
+
+	if (noqueue)
+		flags |= LKF_NOQUEUE;
+
+	if (locks[i].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);
+
+	rv = dlm_ls_lock(dh, mode, &locks[i].lksb, flags,
+			 name, strlen(name), 0, astfn, (void *) &locks[i],
+			 bastfn, NULL);
+	if (!rv) {
+		locks[i].wait_ast = 1;
+		locks[i].rqmode = mode;
+	}
+
+	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);
+}
+
+void lock_sync(int i, int mode)
+{
+	char name[DLM_RESNAME_MAXLEN];
+	int flags = 0;
+	int rv;
+
+	if (noqueue)
+		flags |= LKF_NOQUEUE;
+
+	if (locks[i].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);
+
+	rv = dlm_ls_lock_wait(dh, mode, &locks[i].lksb, flags,
+			 name, strlen(name), 0, (void *) &locks[i],
+			 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);
+
+	if (!rv) {
+		locks[i].grmode = mode;
+		locks[i].rqmode = -1;
+	} else if (rv == EAGAIN) {
+		if (locks[i].grmode == -1)
+			memset(&locks[i].lksb, 0, sizeof(struct dlm_lksb));
+	} else {
+		printf("unknown rv %d\n", rv);
+		exit(-1);
+	}
+}
+
+void lock_all(int mode)
+{
+	int i;
+
+	for (i = 0; i < LOCKS; i++)
+		lock(i, mode);
+}
+
+void unlock(int i)
+{
+	uint32_t lkid;
+	int rv;
+
+	lkid = locks[i].lksb.sb_lkid;
+	if (!lkid) {
+		printf("unlock %d skip zero lkid\n", i);
+		return;
+	}
+
+	printf("dlm_ls_unlock: %d lkid %x\n", i, lkid);
+
+	rv = dlm_ls_unlock(dh, lkid, 0, &locks[i].lksb, &locks[i]);
+	if (!rv) {
+		locks[i].wait_ast = 1;
+		locks[i].rqmode = -1;
+		printf("dlm_ls_unlock: %d\n", i);
+	} else {
+		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);
+	}
+}
+
+void unlock_sync(int i)
+{
+	uint32_t lkid;
+	int rv;
+
+	lkid = locks[i].lksb.sb_lkid;
+	if (!lkid) {
+		printf("unlock %d skip zero lkid\n", i);
+		return;
+	}
+
+	printf("dlm_ls_unlock_wait: %d lkid %x\n", i, lkid);
+
+	rv = dlm_ls_unlock_wait(dh, lkid, 0, &locks[i].lksb);
+
+	printf("dlm_ls_unlock_wait: %d rv %d sb_status %x\n", i, rv,
+	       locks[i].lksb.sb_status);
+
+	memset(&locks[i].lksb, 0, sizeof(struct dlm_lksb));
+	locks[i].grmode = -1;
+	locks[i].rqmode = -1;
+}
+
+void unlock_all(void)
+{
+	int i;
+
+	for (i = 0; i < LOCKS; i++)
+		unlock(i);
+}
+
+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);
+	}
+}
+
+int rand_int(int a, int b)
+{
+	return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0)); 
+}
+
+void hammer(int num)
+{
+	int n, i, busy = 0, lock_ops = 0, unlock_ops = 0;
+
+	while (1) {
+		dlm_dispatch(libdlm_fd);
+
+		i = rand_int(0, LOCKS-1);
+
+		if (locks[i].wait_ast) {
+			busy++;
+			continue;
+		}
+
+		if (locks[i].grmode == -1) {
+			lock(i, rand_int(0, 5));
+			lock_ops++;
+		} else {
+			unlock(i);
+			unlock_ops++;
+		}
+
+		if (++n == num)
+			break;
+	}
+
+	printf("hammer: locks %d unlocks %d busy %d\n",
+		lock_ops, unlock_ops, busy);
+
+	unlock_all();;
+}
+
+int all_unlocks_done(void)
+{
+	int i;
+
+	for (i = 0; i < LOCKS; i++) {
+		if (locks[i].grmode == -1 && !locks[i].wait_ast)
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+void process_command(int *quit)
+{
+	char inbuf[132];
+	char cmd[32];
+	int x = 0, y = 0;
+
+	fgets(inbuf, sizeof(inbuf), stdin);
+
+	sscanf(inbuf, "%s %d %d", cmd, &x, &y);
+
+	if (!strncmp(cmd, "EXIT", 4)) {
+		*quit = 1;
+		unlock_all();
+		return;
+	}
+
+	if (!strncmp(cmd, "kill", 4)) {
+		printf("process exiting\n");
+		exit(0);
+	}
+
+	if (!strncmp(cmd, "lock", 4) && strlen(cmd) == 4) {
+		lock(x, y);
+		return;
+	}
+
+	if (!strncmp(cmd, "unlock", 6) && strlen(cmd) == 6) {
+		unlock(x);
+		return;
+	}
+
+	if (!strncmp(cmd, "lock_sync", 9) && strlen(cmd) == 9) {
+		lock_sync(x, y);
+		return;
+	}
+
+	if (!strncmp(cmd, "unlock_sync", 11) && strlen(cmd) == 11) {
+		unlock_sync(x);
+		return;
+	}
+
+	if (!strncmp(cmd, "lock-kill", 9) && strlen(cmd) == 9) {
+		lock(x, y);
+		printf("process exiting\n");
+		exit(0);
+	}
+
+	if (!strncmp(cmd, "unlock-kill", 11) && strlen(cmd) == 11) {
+		unlock(x);
+		printf("process exiting\n");
+		exit(0);
+	}
+
+	if (!strncmp(cmd, "ex", 2)) {
+		lock(x, LKM_EXMODE);
+		return;
+	}
+
+	if (!strncmp(cmd, "pr", 2)) {
+		lock(x, LKM_PRMODE);
+		return;
+	}
+
+	if (!strncmp(cmd, "hold", 4)) {
+		lock_all(LKM_PRMODE);
+		return;
+	}
+
+	if (!strncmp(cmd, "release", 6)) {
+		unlock_all();
+		return;
+	}
+
+	if (!strncmp(cmd, "dump", 4)) {
+		dump();
+		return;
+	}
+
+	if (!strncmp(cmd, "loop", 4)) {
+		loop(x, y);
+		return;
+	}
+
+	if (!strncmp(cmd, "hammer", 6)) {
+		hammer(x);
+		return;
+	}
+
+	if (!strncmp(cmd, "noqueue", 7)) {
+		noqueue = !noqueue;
+		printf("noqueue is %s\n", noqueue ? "on" : "off");
+		return;
+	}
+
+	if (!strncmp(cmd, "help", 4)) {
+		printf("Usage:\n");
+		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("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("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("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("noqueue		 - toggle NOQUEUE flag for all requests\n"); 
+		return;
+	}
+
+	printf("unknown command %s\n", cmd);
+}
+
+int main(int argc, char *argv[])
+{
+	int i, rv, maxi = 0, quit = 0;
+
+	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;
+	}
+
+	dh = dlm_create_lockspace("test", 0600);
+	if (!dh) {
+		printf("dlm_create_lockspace error %d %d\n", (int) dh, errno);
+		return -ENOTCONN;
+	}
+
+	rv = dlm_ls_get_fd(dh);
+	if (rv < 0) {
+		printf("dlm_ls_get_fd error %d %d\n", rv, errno);
+		dlm_release_lockspace("test", dh, 1);
+		return rv;
+	}
+	libdlm_fd = rv;
+
+	client_add(libdlm_fd, &maxi);
+	client_add(STDIN_FILENO, &maxi);
+
+	printf("Type EXIT to finish\n");
+
+	while (1) {
+		rv = poll(pollfd, maxi + 1, -1);
+		if (rv < 0)
+			printf("poll error %d errno %d\n", rv, errno);
+
+		for (i = 0; i <= maxi; i++) {
+			if (client[i].fd < 0)
+				continue;
+
+			if (pollfd[i].revents & POLLIN) {
+				if (pollfd[i].fd == libdlm_fd)
+					process_libdlm();
+				else if (pollfd[i].fd == STDIN_FILENO)
+					process_command(&quit);
+			}
+
+			if (pollfd[i].revents & POLLHUP)
+				client_dead(i);
+		}
+
+		if (quit && all_unlocks_done())
+			break;
+	}
+
+	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);
+
+	return 0;
+}
+
--- cluster/dlm/tests/usertest/Makefile	2006/08/11 15:18:06	1.5
+++ cluster/dlm/tests/usertest/Makefile	2006/12/07 19:50:49	1.6
@@ -12,7 +12,7 @@
 top_srcdir = ../../..
 UNINSTALL=${top_srcdir}/scripts/uninstall.pl
 
-BINARIES=dlmtest asttest lstest pingtest lvb
+BINARIES=dlmtest asttest lstest pingtest lvb dlmtest2
 
 all: $(BINARIES)
 
@@ -29,6 +29,9 @@
 dlmtest: dlmtest.c
 	$(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread
 
+dlmtest2: dlmtest2.c
+	$(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread
+
 asttest: asttest.c
 	$(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread
 




More information about the Cluster-devel mailing list