[Cluster-devel] cluster/dlm/tests/usertest dlmtest2.c
teigland at sourceware.org
teigland at sourceware.org
Wed May 30 19:31:28 UTC 2007
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: teigland at sourceware.org 2007-05-30 19:31:28
Modified files:
dlm/tests/usertest: dlmtest2.c
Log message:
bunch of stuff to test new features
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/dlm/tests/usertest/dlmtest2.c.diff?cvsroot=cluster&r1=1.7&r2=1.8
--- cluster/dlm/tests/usertest/dlmtest2.c 2007/04/27 19:09:54 1.7
+++ cluster/dlm/tests/usertest/dlmtest2.c 2007/05/30 19:31:28 1.8
@@ -41,6 +41,7 @@
static uint64_t timeout = 0;
static int noqueue = 1;
static int persistent = 0;
+static int ignore_bast = 0;
static int quiet = 1;
static int verbose = 0;
static int bast_cb;
@@ -49,8 +50,14 @@
static int iterations;
static int minhold = 0;
static int stress_stop = 0;
+static int stress_delay = 0;
+static int stress_lock_only = 0;
+static int openclose_ls = 0;
static uint64_t our_xid;
+static unsigned int sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain, sts_other, sts_zero;
+static unsigned int bast_unlock, bast_skip;
+
#define log_print(fmt, args...) \
do { \
if (!quiet) \
@@ -121,6 +128,8 @@
return "EBUSY ";
case ETIMEDOUT:
return "ETIMEDO";
+ case EDEADLK:
+ return "EDEADLK";
default:
snprintf(sts_str, 8, "%8x", status);
return sts_str;
@@ -206,9 +215,11 @@
skip = 1;
}
- if (skip)
+ if (skip) {
+ bast_skip++;
printf(" bast: skip %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
- else {
+ } else {
+ bast_unlock++;
printf(" bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
unlockf(lk->id);
}
@@ -231,7 +242,7 @@
void process_libdlm(void)
{
dlm_dispatch(libdlm_fd);
- if (bast_cb)
+ if (bast_cb && !ignore_bast)
do_bast_unlocks();
}
@@ -253,11 +264,13 @@
lk->last_status = lk->lksb.sb_status;
if (lk->lksb.sb_status == EUNLOCK) {
+ sts_eunlock++;
memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
lk->grmode = -1;
lk->wait_ast = 0;
} else if (lk->lksb.sb_status == ECANCEL) {
+ sts_ecancel++;
if (lk->grmode == -1) {
memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
lk->wait_ast = 0;
@@ -267,6 +280,17 @@
}
} else if (lk->lksb.sb_status == ETIMEDOUT) {
+ sts_etimedout++;
+ if (lk->grmode == -1) {
+ memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
+ lk->wait_ast = 0;
+ } else {
+ if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
+ lk->wait_ast = 0;
+ }
+
+ } else if (lk->lksb.sb_status == EDEADLK) {
+ sts_edeadlk++;
if (lk->grmode == -1) {
memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
lk->wait_ast = 0;
@@ -276,6 +300,7 @@
}
} else if (lk->lksb.sb_status == EAGAIN) {
+ sts_eagain++;
if (lk->grmode == -1) {
memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
lk->wait_ast = 0;
@@ -286,10 +311,17 @@
} else {
if (lk->lksb.sb_status != 0) {
- printf("unknown sb_status %x\n", lk->lksb.sb_status);
- exit(-1);
+ sts_other++;
+ printf("BAD ast: %d %3d\t%x: gr %d rq %d last op %s %s\n",
+ lk->lksb.sb_status, i, lk->lksb.sb_lkid,
+ lk->grmode, lk->rqmode, op_str(lk->lastop),
+ status_str(lk->last_status));
+ stress_stop = 1;
+ return;
}
+ sts_zero++;
+
if (lk->lastop != Op_unlockf)
lk->wait_ast = 0;
@@ -297,8 +329,7 @@
if (minhold) {
gettimeofday(&lk->acquired, NULL);
- /* lk->minhold = rand_int(1, 30); */
- lk->minhold = 10;
+ lk->minhold = minhold;
}
}
@@ -340,8 +371,13 @@
log_verbose("lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
i, lk->grmode, mode, flags, lk->lksb.sb_lkid, name);
+#if 0
+ rv = dlm_ls_lock(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
+ astfn, (void *) lk, bastfn, NULL);
+#else
rv = dlm_ls_lockx(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
astfn, (void *) lk, bastfn, &our_xid, timeout_arg);
+#endif
if (!rv) {
lk->wait_ast = 1;
lk->rqmode = mode;
@@ -513,6 +549,15 @@
lk->lastop = Op_cancel;
}
+void canceld(int i, uint32_t lkid)
+{
+ int rv;
+
+ rv = dlm_ls_deadlock_cancel(dh, lkid, 0);
+
+ printf("canceld %x: %d %d\n", lkid, rv, errno);
+}
+
void unlock_sync(int i)
{
uint32_t lkid;
@@ -600,15 +645,107 @@
purge(nodeid, pid);
}
+void tstress_unlocks(void)
+{
+ struct lk *lk;
+ struct timeval now;
+ int i;
+
+ for (i = 0; i < maxn; i++) {
+ lk = get_lock(i);
+ if (!lk)
+ continue;
+ if (lk->wait_ast)
+ continue;
+ if (lk->grmode < 0)
+ continue;
+
+ /* if we've held the lock for minhold seconds, then unlock */
+
+ gettimeofday(&now, NULL);
+
+ if (now.tv_sec >= lk->acquired.tv_sec + minhold) {
+ printf(" : unlock %3d\t%x: gr %d rq %d held %u of %u s\n",
+ i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
+ now.tv_sec - lk->acquired.tv_sec, minhold);
+
+ _unlock(i, 0);
+ lk->rqmode = -1;
+ lk->lastop = Op_unlock;
+ }
+
+ }
+}
+
+void tstress(int num)
+{
+ int i, o, op, max_op, skip;
+ unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
+ struct lk *lk;
+
+ n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
+ sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
+ bast_unlock = bast_skip = 0;
+
+ noqueue = 0;
+ ignore_bast = 1;
+ quiet = 0;
+
+ if (!timeout)
+ timeout = 4;
+ if (!minhold)
+ minhold = 5;
+
+ while (!stress_stop) {
+ if (stress_delay)
+ usleep(stress_delay);
+
+ process_libdlm();
+
+ tstress_unlocks();
+
+ if (++n == num) {
+ if (all_unlocks_done())
+ break;
+ else
+ continue;
+ }
+
+ i = rand_int(0, maxn-1);
+ lk = get_lock(i);
+ if (!lk)
+ continue;
+
+ if (lk->wait_ast || lk->grmode > -1)
+ continue;
+
+ lock(i, rand_int(0, 5));
+ lock_ops++;
+ printf("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
+ }
+
+ printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
+ skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
+ printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
+ printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
+ sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
+ printf("ast status: zero %d other %d\n", sts_zero, sts_other);
+}
+
void stress(int num)
{
- int i, o, op, skip;
+ int i, o, op, max_op, skip;
unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
struct lk *lk;
n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
+ sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
+ bast_unlock = bast_skip = 0;
while (!stress_stop) {
+ if (stress_delay)
+ usleep(stress_delay);
+
process_libdlm();
if (++n == num)
@@ -619,7 +756,11 @@
if (!lk)
continue;
- o = rand_int(0, 5);
+ max_op = 5;
+ if (stress_lock_only)
+ max_op = 2;
+
+ o = rand_int(0, max_op);
switch (o) {
case 0:
case 1:
@@ -708,8 +849,12 @@
skips++;
}
- printf("skip %d lock %d unlock %d unlockf %d cancel %d\n",
+ printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
+ printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
+ printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
+ sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
+ printf("ast status: zero %d other %d\n", sts_zero, sts_other);
}
static int client_add(int fd, int *maxi)
@@ -758,6 +903,7 @@
printf("unlock x - unlock lock x\n");
printf("unlockf x - force unlock lock x\n");
printf("cancel x - cancel lock x\n");
+ printf("canceld x lkid - cancel lock x, return EDEADLK as status\n");
printf("lock_sync x mode - synchronous version of lock\n");
printf("unlock_sync x - synchronous version of unlock\n");
printf("ex x - equivalent to: lock x 5\n");
@@ -766,11 +912,13 @@
printf("release - for x in 0 to max, unlock x\n");
printf("purge nodeid pid - purge orphan locks of process\n");
printf("stress n - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
+ printf("tstress n - stress timeouts\n");
printf("timeout n - enable lock timeouts, set timeout to n seconds\n");
printf("dump - show info for all locks\n");
+ printf("minhold - set minimum number of seconds locks will be held\n");
+ printf("ignore_bast - ignore all basts\n");
printf("noqueue - toggle NOQUEUE flag for all requests\n");
printf("persistent - toggle PERSISTENT flag for all requests\n");
- printf("minhold - toggle minhold mode, lock will be held for random minimum time\n");
printf("quiet - toggle quiet flag\n");
printf("verbose - toggle verbose flag\n");
@@ -786,6 +934,24 @@
printf("purgetest nodeid pid\n");
}
+void print_settings(void)
+{
+ printf("timewarn %d\n", timewarn);
+ printf("timeout %llu\n", (unsigned long long) timeout);
+ printf("noqueue %d\n", noqueue);
+ printf("persistent %d\n", persistent);
+ printf("ignore_bast %d\n", ignore_bast);
+ printf("quiet %d\n", quiet);
+ printf("verbose %d\n", verbose);
+ printf("maxn %d\n", maxn);
+ printf("maxr %d\n", maxr);
+ printf("iterations %d\n", iterations);
+ printf("minhold %d\n", minhold);
+ printf("stress_stop %d\n", stress_stop);
+ printf("stress_delay %d\n", stress_delay);
+ printf("stress_lock_only %d\n", stress_lock_only);
+}
+
void process_command(int *quit)
{
char inbuf[132];
@@ -802,6 +968,13 @@
return;
}
+ if (!strncmp(cmd, "CLOSE", 5)) {
+ *quit = 1;
+ openclose_ls = 1;
+ unlock_all();
+ return;
+ }
+
if (!strncmp(cmd, "kill", 4)) {
printf("process exiting\n");
exit(0);
@@ -827,6 +1000,11 @@
return;
}
+ if (!strncmp(cmd, "canceld", 7) && strlen(cmd) == 7) {
+ canceld(x, y);
+ return;
+ }
+
if (!strncmp(cmd, "lock_sync", 9) && strlen(cmd) == 9) {
lock_sync(x, y);
return;
@@ -898,11 +1076,33 @@
return;
}
- if (!strncmp(cmd, "stress", 6)) {
+ if (!strncmp(cmd, "stress", 6) && strlen(cmd) == 6) {
stress(x);
return;
}
+ if (!strncmp(cmd, "tstress", 7) && strlen(cmd) == 7) {
+ tstress(x);
+ return;
+ }
+
+ if (!strncmp(cmd, "stress_delay", 12) && strlen(cmd) == 12) {
+ stress_delay = x;
+ return;
+ }
+
+ if (!strncmp(cmd, "stress_lock_only", 16) && strlen(cmd) == 16) {
+ stress_lock_only = !stress_lock_only;
+ printf("stress_lock_only is %s\n", stress_lock_only ? "on" : "off");
+ return;
+ }
+
+ if (!strncmp(cmd, "ignore_bast", 11) && strlen(cmd) == 11) {
+ ignore_bast = !ignore_bast;
+ printf("ignore_bast is %s\n", ignore_bast ? "on" : "off");
+ return;
+ }
+
if (!strncmp(cmd, "purge", 5) && strlen(cmd) == 5) {
purge(x, y);
return;
@@ -926,8 +1126,7 @@
}
if (!strncmp(cmd, "minhold", 7)) {
- minhold = !minhold;
- printf("minhold is %s\n", minhold ? "on" : "off");
+ minhold = x;
return;
}
@@ -954,6 +1153,11 @@
return;
}
+ if (!strncmp(cmd, "settings", 8)) {
+ print_settings();
+ return;
+ }
+
printf("unknown command %s\n", cmd);
}
@@ -973,7 +1177,7 @@
int optchar;
while (cont) {
- optchar = getopt(argc, argv, "n:r:i:thV");
+ optchar = getopt(argc, argv, "n:r:i:thVo");
switch (optchar) {
@@ -993,6 +1197,10 @@
timewarn = 1;
break;
+ case 'o':
+ openclose_ls = 1;
+ break;
+
case 'h':
print_usage();
exit(EXIT_SUCCESS);
@@ -1029,6 +1237,7 @@
int main(int argc, char *argv[])
{
+ uint32_t major, minor, patch;
struct lk *lk;
int i, rv, maxi = 0, quit = 0;
@@ -1066,12 +1275,33 @@
lk++;
}
- printf("Joining test lockspace...\n");
+ rv = dlm_kernel_version(&major, &minor, &patch);
+ if (rv < 0) {
+ printf("can't detect dlm in kernel %d\n", errno);
+ return -1;
+ }
+ printf("dlm kernel version: %u.%u.%u\n", major, minor, patch);
+ dlm_library_version(&major, &minor, &patch);
+ printf("dlm library version: %u.%u.%u\n", major, minor, patch);
+
+ if (openclose_ls) {
+ printf("dlm_open_lockspace...\n");
+
+ dh = dlm_open_lockspace("test");
+ if (!dh) {
+ printf("dlm_open_lockspace error %lu %d\n",
+ (unsigned long)dh, errno);
+ return -ENOTCONN;
+ }
+ } else {
+ printf("dlm_new_lockspace...\n");
- dh = dlm_new_lockspace("test", 0600, timewarn ? DLM_LSFL_TIMEWARN : 0);
- if (!dh) {
- printf("dlm_new_lockspace error %d %d\n", (int) dh, errno);
- return -ENOTCONN;
+ dh = dlm_new_lockspace("test", 0600, timewarn ? DLM_LSFL_TIMEWARN : 0);
+ if (!dh) {
+ printf("dlm_new_lockspace error %lu %d\n",
+ (unsigned long)dh, errno);
+ return -ENOTCONN;
+ }
}
rv = dlm_ls_get_fd(dh);
@@ -1116,11 +1346,19 @@
break;
}
- printf("dlm_release_lockspace\n");
+ if (openclose_ls) {
+ printf("dlm_close_lockspace\n");
+
+ rv = dlm_close_lockspace(dh);
+ if (rv < 0)
+ printf("dlm_close_lockspace error %d %d\n", rv, errno);
+ } else {
+ 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);
+ rv = dlm_release_lockspace("test", dh, 1);
+ if (rv < 0)
+ printf("dlm_release_lockspace error %d %d\n", rv, errno);
+ }
return 0;
}
More information about the Cluster-devel
mailing list