All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] cluster/dlm/tests/usertest Makefile dlmtest2.c
@ 2006-12-07 19:50 teigland
  0 siblings, 0 replies; only message in thread
From: teigland @ 2006-12-07 19:50 UTC (permalink / raw)
  To: cluster-devel.redhat.com

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
 



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-12-07 19:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-07 19:50 [Cluster-devel] cluster/dlm/tests/usertest Makefile dlmtest2.c teigland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.