[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