From mboxrd@z Thu Jan 1 00:00:00 1970 From: teigland@sourceware.org Date: 12 Dec 2006 21:17:56 -0000 Subject: [Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c Message-ID: <20061212211756.1251.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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");