From 969249340a4c6146ae182ca2b969b77fbab31fe2 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Wed, 16 Nov 2011 15:24:11 -0600 Subject: dlm_load: user command input Signed-off-by: David Teigland --- dlm/dlm_load.c | 456 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 300 insertions(+), 156 deletions(-) diff --git a/dlm/dlm_load.c b/dlm/dlm_load.c index 52bcbea..07a9f57 100644 --- a/dlm/dlm_load.c +++ b/dlm/dlm_load.c @@ -1,15 +1,9 @@ /* - * Copyright (c) 2010 David Teigland - * All Rights Reserved. + * Copyright 2010-2011 David Teigland * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License V2 * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include @@ -37,8 +31,8 @@ #define LKM_IVMODE -1 #define MAX_CLIENTS 4 -#define MAX_LOCKS 32 -#define MAX_RESOURCES 32 +#define DEFAULT_LOCKS 16 +#define DEFAULT_RESOURCES 16 #define DEFAULT_SLEEP_ITER 10 #define DEFAULT_SLEEP_TIME 200000 /* usecs */ @@ -46,10 +40,13 @@ static dlm_lshandle_t *dh; static int libdlm_fd; static uint32_t iterations = 0; -static int maxn = MAX_LOCKS; -static int maxr = MAX_RESOURCES; +static int maxn = DEFAULT_LOCKS; +static int maxr = DEFAULT_RESOURCES; static int openclose = 0; static int quiet = 0; +static int do_log_pre = 1; +static int exit_on_error = 1; +static int user_sh = 0; static int sleep_iter = DEFAULT_SLEEP_ITER; static int sleep_time = DEFAULT_SLEEP_TIME; static int timewarn = 0; @@ -73,7 +70,7 @@ enum { }; struct lk { - int id; + int num; int locked_stable; int unlocked_stable; int wait_request; @@ -98,10 +95,17 @@ do { \ printf(fmt "\n", ##args); \ } while (0) +#define log_pre(fmt, args...) \ +do { \ + if (!quiet && do_log_pre) \ + printf(fmt "\n", ##args); \ +} while (0) + #define log_error(fmt, args...) \ do { \ printf("ERROR " fmt "\n", ##args); \ - exit(-1); \ + if (exit_on_error) \ + exit(-1); \ } while (0) static int rand_int(int a, int b) @@ -117,7 +121,7 @@ static const char *status_str(int status) case 0: return "0 "; case EUNLOCK: - return "EUNLOCK"; + return "U "; case ECANCEL: return "ECANCEL"; case EAGAIN: @@ -142,14 +146,25 @@ static const char *op_str(int op) case Op_convert: return "convert"; case Op_unlock: - return "unlock"; + return "unlock "; case Op_cancel: - return "cancel"; + return "cancel "; default: return "unknown"; } } +static const char *num_str(int num) +{ + static char num_str[8]; + + if (num == -1) + return "-"; + + snprintf(num_str, 8, "%d", num); + return num_str; +} + static struct lk *get_lock(int i) { if (i < 0) @@ -159,24 +174,37 @@ static struct lk *get_lock(int i) return &locks[i]; } -static void dump(void) +static void dump_lk(int num) { - struct lk *lk; - int i; + struct lk *lk = get_lock(num); - for (i = 0; i < maxn; i++) { - lk = get_lock(i); - log_debug("lk %03u id %08x wait r%d c%d u%d c%d lastop %s gr %d rq %d\n", - i, - lk->lksb.sb_lkid, + if (!lk) + return; + + printf("lk %03u id %08x gr %s rq %s op %s ", + num, lk->lksb.sb_lkid, num_str(lk->grmode), num_str(lk->rqmode), + op_str(lk->lastop)); + + if (lk->wait_request || lk->wait_convert || + lk->wait_unlock || lk->wait_cancel) { + printf("wait r%d c%d u%d c%d\n", lk->wait_request, lk->wait_convert, lk->wait_unlock, - lk->wait_cancel, - op_str(lk->lastop), - lk->grmode, - lk->rqmode); + lk->wait_cancel); + } else { + printf("done\n"); } + + fflush(stdout); +} + +static void dump(void) +{ + int i; + + for (i = 0; i < maxn; i++) + dump_lk(i); } static void bastfn(void *arg) @@ -186,27 +214,18 @@ static void bastfn(void *arg) ast_count++; - log_debug("lk %03u bast %04u", lk->id, ast_count); + printf("lk %03u bast\n", lk->num); + fflush(stdout); } static void astfn(void *arg) { struct lk *lk = arg; int status = lk->lksb.sb_status; - int i = lk->id; + int num = lk->num; ast_count++; - log_debug("lk %03u cast %04u %s %08x " - "wait r%d c%d u%d c%d " - "gr %2d rq %2d last %s", - i, ast_count, status_str(status), - lk->lksb.sb_lkid, - lk->wait_request, lk->wait_convert, - lk->wait_unlock, lk->wait_cancel, - lk->grmode, lk->rqmode, - op_str(lk->lastop)); - switch (status) { case 0: case EAGAIN: @@ -233,7 +252,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 1", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -250,7 +269,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 2", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -273,7 +292,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 3", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -286,7 +305,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 4", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -313,7 +332,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 5", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -331,7 +350,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 6", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -342,7 +361,7 @@ static void astfn(void *arg) case ETIMEDOUT: log_error("lk %03u cast %04u %s %08x not using timeouts", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid); break; @@ -359,7 +378,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 7", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -372,7 +391,7 @@ static void astfn(void *arg) log_error("lk %03u cast %04u %s %08x " "wait r%d c%d u%d c%d " "gr %2d rq %2d last %s wait state error 8", - i, ast_count, status_str(status), + num, ast_count, status_str(status), lk->lksb.sb_lkid, lk->wait_request, lk->wait_convert, lk->wait_unlock, lk->wait_cancel, @@ -384,8 +403,14 @@ static void astfn(void *arg) default: log_error("lk %03u cast %04u %d %08x error unexpected status", - i, ast_count, status, lk->lksb.sb_lkid); + num, ast_count, status, lk->lksb.sb_lkid); }; + + printf("lk %03u id %08x gr %s rq %s op %s cast %s\n", + num, lk->lksb.sb_lkid, num_str(lk->grmode), num_str(lk->rqmode), + op_str(lk->lastop), status_str(status)); + fflush(stdout); + } /* FIXME: ran two dlm_load's on four nodes over the weekend, and one instance @@ -400,48 +425,67 @@ static void astfn(void *arg) ERROR lk 007 request errno 22 wait r0 c0 u0 c0 lastop request */ -static int do_request(struct lk *lk, int mode, int noqueue) +static int do_request(int num, int mode, int noqueue) { + struct lk *lk; char name[DLM_RESNAME_MAXLEN]; uint64_t *timeout_arg = NULL; uint32_t flags = 0; - int i = lk->id; int rv; + lk = get_lock(num); + if (!lk) { + printf("unknown lk %d\n", num); + return; + } + if (noqueue) flags |= LKF_NOQUEUE; memset(name, 0, sizeof(name)); - snprintf(name, sizeof(name), "test%d", (i % maxr)); + snprintf(name, sizeof(name), "test%d", (num % maxr)); - log_debug("lk %03u request mode %d noqueue %d", i, mode, noqueue); + log_pre("lk %03u request mode %d noqueue %d", num, mode, noqueue); rv = dlm_ls_lockx(dh, mode, &lk->lksb, flags, name, strlen(name), 0, astfn, (void *)lk, bastfn, &our_xid, timeout_arg); if (rv) { - log_error("lk %03u request errno %d wait r%d c%d u%d c%d lastop %s", - i, errno, lk->wait_request, lk->wait_convert, - lk->wait_unlock, lk->wait_cancel, op_str(lk->lastop)); + log_error("lk %03u request errno %d mode %d noqueue %d", + num, errno, mode, noqueue); + dump_lk(num); + } else { + lk->lastop = Op_request; + lk->rqmode = mode; + lk->wait_start = time(NULL); + lk->wait_request = 1; + lk->locked_stable = 0; + lk->unlocked_stable = 0; } return rv; } -static int do_convert(struct lk *lk, int mode, int noqueue) +static int do_convert(int num, int mode, int noqueue) { + struct lk *lk; char name[DLM_RESNAME_MAXLEN]; uint64_t *timeout_arg = NULL; uint32_t flags = LKF_CONVERT; - int i = lk->id; int rv; + lk = get_lock(num); + if (!lk) { + printf("unknown lk %d\n", num); + return; + } + if (noqueue) flags |= LKF_NOQUEUE; memset(name, 0, sizeof(name)); - snprintf(name, sizeof(name), "test%d", (i % maxr)); + snprintf(name, sizeof(name), "test%d", (num % maxr)); - log_debug("lk %03u convert mode %d noqueue %d", i, mode, noqueue); + log_pre("lk %03u convert mode %d noqueue %d", num, mode, noqueue); rv = dlm_ls_lockx(dh, mode, &lk->lksb, flags, name, strlen(name), 0, astfn, (void *)lk, bastfn, &our_xid, timeout_arg); @@ -460,24 +504,37 @@ static int do_convert(struct lk *lk, int mode, int noqueue) } if (rv) { - log_error("lk %03u convert errno %d wait r%d c%d u%d c%d lastop %s", - i, errno, lk->wait_request, lk->wait_convert, - lk->wait_unlock, lk->wait_cancel, op_str(lk->lastop)); + log_error("lk %03u convert errno %d mode %d noqueue %d", + num, errno, mode, noqueue); + dump_lk(num); + } else { + lk->lastop = Op_convert; + lk->rqmode = mode; + lk->bast = 0; + lk->wait_start = time(NULL); + lk->wait_convert = 1; + lk->locked_stable = 0; + lk->unlocked_stable = 0; } out: return rv; } -static int do_unlock(struct lk *lk) +static int do_unlock(int num) { - uint32_t lkid = lk->lksb.sb_lkid; + struct lk *lk; uint32_t flags = 0; - int i = lk->id; int rv; - log_debug("lk %03u unlock", i); + lk = get_lock(num); + if (!lk) { + printf("unknown lk %d\n", num); + return; + } + + log_pre("lk %03u unlock", num); - rv = dlm_ls_unlock(dh, lkid, flags, &lk->lksb, lk); + rv = dlm_ls_unlock(dh, lk->lksb.sb_lkid, flags, &lk->lksb, lk); /* See comment above. */ @@ -490,9 +547,15 @@ static int do_unlock(struct lk *lk) } if (rv) { - log_error("lk %03u unlock errno %d wait r%d c%d u%d c%d lastop %s", - i, errno, lk->wait_request, lk->wait_convert, - lk->wait_unlock, lk->wait_cancel, op_str(lk->lastop)); + log_error("lk %03u unlock errno %d", num, errno); + dump_lk(num); + } else { + lk->lastop = Op_unlock; + lk->rqmode = LKM_IVMODE; + lk->bast = 0; + lk->wait_unlock = 1; + lk->locked_stable = 0; + lk->unlocked_stable = 0; } out: return rv; @@ -512,135 +575,100 @@ static int do_unlock(struct lk *lk) ERROR lk 025 convert errno 16 wait r0 c0 u0 c0 lastop cancel */ -static int do_cancel(struct lk *lk) +static int do_cancel(int num) { - uint32_t lkid = lk->lksb.sb_lkid; + struct lk *lk; uint32_t flags = LKF_CANCEL; - int i = lk->id; int rv; - log_debug("lk %03u cancel", i); + lk = get_lock(num); + if (!lk) { + printf("unknown lk %d\n", num); + return; + } + + log_pre("lk %03u cancel", num); - rv = dlm_ls_unlock(dh, lkid, flags, &lk->lksb, lk); + rv = dlm_ls_unlock(dh, lk->lksb.sb_lkid, flags, &lk->lksb, lk); if (rv) { - log_error("lk %03u cancel errno %d wait r%d c%d u%d c%d lastop %s", - i, errno, lk->wait_request, lk->wait_convert, - lk->wait_unlock, lk->wait_cancel, op_str(lk->lastop)); + log_error("lk %03u cancel errno %d", num, errno); + dump_lk(num); + } else { + lk->lastop = Op_cancel; + lk->wait_cancel = 1; + lk->locked_stable = 0; + lk->unlocked_stable = 0; } return rv; } -static void loop(void) +static void rand_loop(int iter) { struct lk *lk; uint32_t n = 0; - int locknum, noqueue, rqmode, rv; + int num, noqueue, rqmode, rv; while (1) { dlm_dispatch(libdlm_fd); n++; - if (iterations && n == iterations) + if (iter && n == iter+1) break; if (sleep_iter && !(n % sleep_iter)) usleep(sleep_time); - locknum = rand_int(0, maxn - 1); + num = rand_int(0, maxn - 1); noqueue = rand_int(0, 1); rqmode = rand_int(0, LKM_EXMODE); - lk = get_lock(locknum); + lk = get_lock(num); if (!lk) continue; if (lk->unlocked_stable) { - rv = do_request(lk, rqmode, noqueue); - if (!rv) { - lk->lastop = Op_request; - lk->rqmode = rqmode; - lk->wait_start = time(NULL); - - lk->wait_request = 1; - lk->locked_stable = 0; - lk->unlocked_stable = 0; - } + rv = do_request(num, rqmode, noqueue); continue; } if (lk->locked_stable && lk->bast) { if (rand_int(0, 1)) { - rv = do_convert(lk, LKM_NLMODE, 0); - if (!rv) { - lk->lastop = Op_convert; - lk->rqmode = LKM_NLMODE; - lk->bast = 0; - lk->wait_start = time(NULL); - - lk->wait_convert = 1; - lk->locked_stable = 0; - lk->unlocked_stable = 0; - } + rv = do_convert(num, LKM_NLMODE, 0); } else { - rv = do_unlock(lk); - if (!rv) { - lk->lastop = Op_unlock; - lk->rqmode = LKM_IVMODE; - lk->bast = 0; - - lk->wait_unlock = 1; - lk->locked_stable = 0; - lk->unlocked_stable = 0; - } + rv = do_unlock(num); } continue; } if (lk->locked_stable) { if (rand_int(0, 1)) { - rv = do_convert(lk, rqmode, noqueue); - if (!rv) { - lk->lastop = Op_convert; - lk->rqmode = rqmode; - lk->wait_start = time(NULL); - - lk->wait_convert = 1; - lk->locked_stable = 0; - lk->unlocked_stable = 0; - } + rv = do_convert(num, rqmode, noqueue); } else { - rv = do_unlock(lk); - if (!rv) { - lk->lastop = Op_unlock; - lk->rqmode = LKM_IVMODE; - - lk->wait_unlock = 1; - lk->locked_stable = 0; - lk->unlocked_stable = 0; - } + rv = do_unlock(num); } continue; } if ((lk->wait_request || lk->wait_convert) && !lk->wait_cancel) { if (time(NULL) - lk->wait_start > 2) { - rv = do_cancel(lk); - if (!rv) { - lk->lastop = Op_cancel; - - lk->wait_cancel = 1; - lk->locked_stable = 0; - lk->unlocked_stable = 0; - } + rv = do_cancel(num); } } - log_debug("lk %03u busy locked %d unlocked %d " - "wait r%d c%d u%d c%d", - lk->id, lk->locked_stable, lk->unlocked_stable, - lk->wait_request, lk->wait_convert, - lk->wait_unlock, lk->wait_cancel); + log_debug("lk %03u id %08x gr %s rq %s op %s skip " + "ls %d us %d wait r%d c%d u%d c%d", + num, + lk->lksb.sb_lkid, + num_str(lk->grmode), + num_str(lk->rqmode), + op_str(lk->lastop), + lk->locked_stable, + lk->unlocked_stable, + lk->wait_request, + lk->wait_convert, + lk->wait_unlock, + lk->wait_cancel); } } @@ -679,17 +707,128 @@ static void client_init(void) client[i].fd = -1; } +static void print_help(void) +{ + printf("quit\n"); + printf("help\n"); + printf("rand num - run num random ops on random lks\n"); + printf("ls [lk] - list one or all locks\n"); + printf("lock lk mode noqueue\n"); + printf("convert lk mode noqueue\n"); + printf("unlock lk\n"); + printf("cancel lk\n"); +} + +static void user_cmd(int *quit) +{ + char inbuf[132]; + char cmd[132]; + int rv, num = 0, x = 0, y = 0; + + memset(inbuf, 0, sizeof(inbuf)); + memset(cmd, 0, sizeof(cmd)); + + fgets(inbuf, sizeof(inbuf), stdin); + rv = sscanf(inbuf, "%s %d %d %d", cmd, &num, &x, &y); + + if (!rv || !strcmp(cmd, "help")) { + print_help(); + return; + } + + if (!strcmp(cmd, "quit")) { + *quit = 1; + return; + } + + if (!strcmp(cmd, "ls") && rv == 1) { + dump(); + return; + } + + else if (!strcmp(cmd, "lock")) { + do_request(num, x, y); + } + + else if (!strcmp(cmd, "convert")) { + do_convert(num, x, y); + } + + else if (!strcmp(cmd, "unlock")) { + do_unlock(num); + } + + else if (!strcmp(cmd, "cancel")) { + do_cancel(num); + } + + else if (!strcmp(cmd, "rand")) { + rand_loop(num); + } + + else if (!strcmp(cmd, "ls")) { + dump_lk(num); + } + + else if (strlen(cmd) > 0) { + printf("unknown cmd %s\n", cmd); + print_help(); + } + + else { + print_help(); + } +} + +static void user_loop(void) +{ + int quit = 0; + int maxi = 0; + int rv, i; + + exit_on_error = 0; + do_log_pre = 0; + + client_add(libdlm_fd, &maxi); + client_add(STDIN_FILENO, &maxi); + + printf("Type exit to quit, help for usage\n"); + + while (!quit) { + rv = poll(pollfd, maxi + 1, -1); + if (rv < 0 && errno == EINTR) + continue; + + for (i = 0; i <= maxi; i++) { + if (client[i].fd < 0) + continue; + + if (pollfd[i].revents & POLLIN) { + if (pollfd[i].fd == libdlm_fd) + dlm_dispatch(libdlm_fd); + else if (pollfd[i].fd == STDIN_FILENO) { + user_cmd(&quit); + } + } + + if (pollfd[i].revents & (POLLHUP | POLLERR | POLLNVAL)) + client_dead(i); + } + } +} + static void print_usage(void) { printf("Options:\n"); printf("\n"); - printf(" -n The number of locks to work with, default %d\n", MAX_LOCKS); - printf(" -r The number of resources to work with, default %d\n", MAX_RESOURCES); + printf(" -n The number of locks to work with, default %d\n", DEFAULT_LOCKS); + printf(" -r The number of resources to work with, default %d\n", DEFAULT_RESOURCES); printf(" -i Iterations in looping stress test, default 0 is no limit\n"); printf(" -S sleep every iterations, default %d\n", DEFAULT_SLEEP_ITER); printf(" -s sleep usecs, default %d\n", DEFAULT_SLEEP_TIME); printf(" -o Open/close existing lockspace\n"); printf(" -q Quiet output, only print errors\n"); + printf(" -u User command input\n"); } static void decode_arguments(int argc, char **argv) @@ -698,7 +837,7 @@ static void decode_arguments(int argc, char **argv) int optchar; while (cont) { - optchar = getopt(argc, argv, "n:r:i:s:S:qoh"); + optchar = getopt(argc, argv, "n:r:i:s:S:uqoh"); switch (optchar) { @@ -730,6 +869,10 @@ static void decode_arguments(int argc, char **argv) sleep_iter = atoi(optarg); break; + case 'u': + user_sh = 1; + break; + case 'h': print_usage(); exit(EXIT_SUCCESS); @@ -762,7 +905,7 @@ int main(int argc, char *argv[]) { uint32_t major, minor, patch; struct lk *lk; - int i, rv, maxi = 0, quit = 0; + int i, rv, quit = 0; srandom(time(NULL)); @@ -792,7 +935,7 @@ int main(int argc, char *argv[]) lk = locks; for (i = 0; i < maxn; i++) { - lk->id = i; + lk->num = i; lk->grmode = -1; lk->rqmode = -1; lk->unlocked_stable = 1; @@ -837,9 +980,10 @@ int main(int argc, char *argv[]) } libdlm_fd = rv; - client_add(libdlm_fd, &maxi); - - loop(); + if (user_sh) + user_loop(); + else + rand_loop(iterations); if (openclose) { log_debug("dlm_close_lockspace"); -- cgit