This is the mail archive of the
cluster-cvs@sourceware.org
mailing list for the cluster.
cluster: STABLE3 - dlm_tool: lockdebug using new debugfs file
- From: David Teigland <teigland at fedoraproject dot org>
- To: cluster-cvs-relay at redhat dot com
- Date: Wed, 17 Dec 2008 17:36:03 +0000 (UTC)
- Subject: cluster: STABLE3 - dlm_tool: lockdebug using new debugfs file
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=a2ba1474b8ed32a6eb796da2c0630816f3d2087d
Commit: a2ba1474b8ed32a6eb796da2c0630816f3d2087d
Parent: 13d6d2cccdd70769c5681e8294a17bd021814a2b
Author: David Teigland <teigland@redhat.com>
AuthorDate: Wed Dec 17 11:12:29 2008 -0600
Committer: David Teigland <teigland@redhat.com>
CommitterDate: Wed Dec 17 11:33:14 2008 -0600
dlm_tool: lockdebug using new debugfs file
A new dlm patch adds a new debugfs file that shows more
info about rsb/lvb/lkb structs. dlm_tool lockdebug <name>
will use this new file, if available, and display the
new info in a format similar to the original format.
Signed-off-by: David Teigland <teigland@redhat.com>
---
dlm/tool/main.c | 346 ++++++++++++++++++++++++++++++++++++++++----
group/gfs_controld/plock.c | 2 +
2 files changed, 317 insertions(+), 31 deletions(-)
diff --git a/dlm/tool/main.c b/dlm/tool/main.c
index ac50d76..a31656b 100644
--- a/dlm/tool/main.c
+++ b/dlm/tool/main.c
@@ -39,13 +39,42 @@ static int opt_excl = 0;
static int opt_fs = 0;
static int dump_mstcpy = 0;
static mode_t create_mode = 0600;
+static int verbose;
+static int wide;
#define MAX_LS 128
#define MAX_NODES 128
+/* from linux/fs/dlm/dlm_internal.h */
+#define DLM_LKSTS_WAITING 1
+#define DLM_LKSTS_GRANTED 2
+#define DLM_LKSTS_CONVERT 3
+
struct dlmc_lockspace lss[MAX_LS];
struct dlmc_node nodes[MAX_NODES];
+static int rsb_nodeid, print_granted, print_convert, print_waiting, print_lookup;
+
+char *mode_str(int mode)
+{
+ switch (mode) {
+ case -1:
+ return "IV";
+ case LKM_NLMODE:
+ return "NL";
+ case LKM_CRMODE:
+ return "CR";
+ case LKM_CWMODE:
+ return "CW";
+ case LKM_PRMODE:
+ return "PR";
+ case LKM_PWMODE:
+ return "PW";
+ case LKM_EXMODE:
+ return "EX";
+ }
+ return "??";
+}
static void print_usage(void)
{
@@ -64,12 +93,14 @@ static void print_usage(void)
printf(" -m <mode> Permission mode for lockspace device (octal), default 0600\n");
printf(" -M Print MSTCPY locks in lockdump\n"
" (remote locks that are locally mastered)\n");
+ printf(" -v Verbose lockdebug output\n");
+ printf(" -w Wide lockdebug output\n");
printf(" -h Print this help, then exit\n");
printf(" -V Print program version information, then exit\n");
printf("\n");
}
-#define OPTION_STRING "MhVnd:m:e:f:"
+#define OPTION_STRING "MhVnd:m:e:f:vw"
static void decode_arguments(int argc, char **argv)
{
@@ -108,6 +139,14 @@ static void decode_arguments(int argc, char **argv)
ls_all_nodes = 1;
break;
+ case 'v':
+ verbose = 1;
+ break;
+
+ case 'w':
+ wide = 1;
+ break;
+
case 'h':
print_usage();
exit(EXIT_SUCCESS);
@@ -312,6 +351,246 @@ void do_leave(char *name)
printf("done\n");
}
+char *pr_master(int nodeid, uint32_t first_lkid)
+{
+ static char buf[64];
+
+ memset(buf, 0, sizeof(buf));
+
+ if (nodeid > 0)
+ sprintf(buf, "Local %d", nodeid);
+ else if (!nodeid)
+ sprintf(buf, "Master");
+ else if (nodeid == -1)
+ sprintf(buf, "Lookup lkid %08x", first_lkid);
+
+ return buf;
+}
+
+char *pr_recovery(uint32_t flags, int root_list, int recover_list,
+ int recover_locks_count)
+{
+ static char buf[128];
+
+ memset(buf, 0, sizeof(buf));
+
+ if (flags || root_list || recover_list || recover_locks_count)
+ sprintf(buf, "flags %08x root %d recover %d locks_count %d",
+ flags, root_list, recover_list, recover_locks_count);
+
+ return buf;
+}
+
+void print_rsb(char *line)
+{
+ char type[4], namefmt[4], *p;
+ int rv, nodeid, root_list, recover_list, recover_locks_count, namelen;
+ uint32_t first_lkid, flags;
+
+ rv = sscanf(line, "%s %d %u %u %d %d %u %u %s",
+ type,
+ &nodeid,
+ &first_lkid,
+ &flags,
+ &root_list,
+ &recover_list,
+ &recover_locks_count,
+ &namelen,
+ namefmt);
+
+ if (rv != 9)
+ goto fail;
+
+ /* used for lkb prints */
+ rsb_nodeid = nodeid;
+
+ p = strchr(line, '\n');
+ if (!p)
+ goto fail;
+ *p = '\0';
+
+ p = strstr(line, namefmt);
+ if (!p)
+ goto fail;
+ p += 4;
+
+ if (!strncmp(namefmt, "str", 3))
+ printf("Resource len %2d \"%s\"\n", namelen, p);
+ else if (!strncmp(namefmt, "hex", 3))
+ printf("Resource len %2d hex %s\n", namelen, p);
+ else
+ goto fail;
+
+ printf("%-16s %s\n",
+ pr_master(nodeid, first_lkid),
+ pr_recovery(flags, root_list, recover_list, recover_locks_count));
+
+ return;
+
+ fail:
+ fprintf(stderr, "print_rsb error rv %d line \"%s\"\n", rv, line);
+}
+
+void print_lvb(char *line)
+{
+ char lvb[1024];
+ char type[4];
+ int i, c, rv, lvblen;
+ uint32_t lvbseq;
+
+ memset(lvb, 0, 1024);
+
+ rv = sscanf(line, "%s %u %d %[0-9A-Fa-f ]", type, &lvbseq, &lvblen, lvb);
+
+ if (rv != 4) {
+ fprintf(stderr, "print_lvb error rv %d line \"%s\"\n", rv, line);
+ return;
+ }
+
+ printf("LVB len %d seq %u\n", lvblen, lvbseq);
+
+ for (c = 0, i = 0; ; i++) {
+ printf("%c", lvb[i]);
+ if (lvb[i] != ' ')
+ c++;
+ if (!wide && lvb[i] == ' ' && !(c % 32))
+ printf("\n");
+ if (c == (lvblen * 2))
+ break;
+ }
+ printf("\n");
+}
+
+struct lkb {
+ uint64_t xid, timestamp, time_bast;
+ uint32_t id, remid, exflags, flags, lvbseq;
+ int nodeid, ownpid, status, grmode, rqmode, highbast, rsb_lookup, wait_type;
+};
+
+char *pr_grmode(struct lkb *lkb)
+{
+ if (lkb->status == DLM_LKSTS_GRANTED || lkb->status == DLM_LKSTS_CONVERT)
+ return mode_str(lkb->grmode);
+ else if (lkb->status == DLM_LKSTS_WAITING || lkb->rsb_lookup)
+ return "--";
+ else
+ return "XX";
+}
+
+char *pr_rqmode(struct lkb *lkb)
+{
+ static char buf[5];
+
+ memset(buf, 0, sizeof(buf));
+
+ if (lkb->status == DLM_LKSTS_GRANTED) {
+ return " ";
+ } else if (lkb->status == DLM_LKSTS_CONVERT ||
+ lkb->status == DLM_LKSTS_WAITING ||
+ lkb->rsb_lookup) {
+ sprintf(buf, "(%s)", mode_str(lkb->rqmode));
+ return buf;
+ } else {
+ return "(XX)";
+ }
+}
+
+char *pr_remote(struct lkb *lkb)
+{
+ static char buf[64];
+
+ memset(buf, 0, sizeof(buf));
+
+ if (!lkb->nodeid) {
+ return " ";
+ } else if (lkb->nodeid != rsb_nodeid) {
+ sprintf(buf, "Remote: %3d %08x", lkb->nodeid, lkb->remid);
+ return buf;
+ } else {
+ sprintf(buf, "Master: %3d %08x", lkb->nodeid, lkb->remid);
+ return buf;
+ }
+}
+
+char *pr_wait(struct lkb *lkb)
+{
+ static char buf[16];
+
+ memset(buf, 0, sizeof(buf));
+
+ if (!lkb->wait_type) {
+ return " ";
+ } else {
+ sprintf(buf, " wait %02d", lkb->wait_type);
+ return buf;
+ }
+}
+
+char *pr_verbose(struct lkb *lkb)
+{
+ static char buf[128];
+
+ memset(buf, 0, sizeof(buf));
+
+ sprintf(buf, "time %016llu flags %08x %08x bast %d %llu",
+ (unsigned long long)lkb->timestamp,
+ lkb->exflags, lkb->flags, lkb->highbast,
+ (unsigned long long)lkb->time_bast);
+
+ return buf;
+}
+
+void print_lkb(char *line)
+{
+ struct lkb lkb;
+ char type[4];
+ int rv;
+
+ rv = sscanf(line, "%s %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu",
+ type,
+ &lkb.id,
+ &lkb.nodeid,
+ &lkb.remid,
+ &lkb.ownpid,
+ &lkb.xid,
+ &lkb.exflags,
+ &lkb.flags,
+ &lkb.status,
+ &lkb.grmode,
+ &lkb.rqmode,
+ &lkb.highbast,
+ &lkb.rsb_lookup,
+ &lkb.wait_type,
+ &lkb.lvbseq,
+ &lkb.timestamp,
+ &lkb.time_bast);
+
+ if ((lkb.status == DLM_LKSTS_GRANTED) && !print_granted) {
+ printf("Granted\n");
+ print_granted = 1;
+ }
+ if ((lkb.status == DLM_LKSTS_CONVERT) && !print_convert) {
+ printf("Convert\n");
+ print_convert = 1;
+ }
+ if ((lkb.status == DLM_LKSTS_WAITING) && !print_waiting) {
+ printf("Waiting\n");
+ print_waiting = 1;
+ }
+ if (lkb.rsb_lookup && !print_lookup) {
+ printf("Lookup\n");
+ print_lookup = 1;
+ }
+
+ printf("%08x %s %s %s %s %s\n",
+ lkb.id, pr_grmode(&lkb), pr_rqmode(&lkb),
+ pr_remote(&lkb), pr_wait(&lkb),
+ (verbose && wide) ? pr_verbose(&lkb) : "");
+
+ if (verbose && !wide)
+ printf("%s\n", pr_verbose(&lkb));
+}
+
#define LOCK_LINE_MAX 1024
void do_lockdebug(char *name)
@@ -319,48 +598,53 @@ void do_lockdebug(char *name)
FILE *file;
char path[PATH_MAX];
char line[LOCK_LINE_MAX];
+ int old = 0;
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s", name);
+ snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_all", name);
file = fopen(path, "r");
if (!file) {
- fprintf(stderr, "can't open %s: %s\n", path, strerror(errno));
- return;
+ snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s", name);
+ file = fopen(path, "r");
+ if (!file) {
+ fprintf(stderr, "can't open %s: %s\n", path, strerror(errno));
+ return;
+ }
+ old = 1;
}
while (fgets(line, LOCK_LINE_MAX, file)) {
- printf("%s", line);
- }
- fclose(file);
-}
+ if (old)
+ goto raw;
-char *mode_str(int mode)
-{
- switch (mode) {
- case -1:
- return "IV";
- case LKM_NLMODE:
- return "NL";
- case LKM_CRMODE:
- return "CR";
- case LKM_CWMODE:
- return "CW";
- case LKM_PRMODE:
- return "PR";
- case LKM_PWMODE:
- return "PW";
- case LKM_EXMODE:
- return "EX";
+ if (!strncmp(line, "version", 7))
+ continue;
+
+ if (!strncmp(line, "rsb", 3)) {
+ rsb_nodeid = -9;
+ print_granted = print_convert = print_waiting = print_lookup = 0;
+ printf("\n");
+ print_rsb(line);
+ continue;
+ }
+
+ if (!strncmp(line, "lvb", 3)) {
+ print_lvb(line);
+ continue;
+ }
+
+ if (!strncmp(line, "lkb", 3)) {
+ print_lkb(line);
+ continue;
+ }
+ raw:
+ printf("%s", line);
}
- return "??";
+ out:
+ fclose(file);
}
-/* from linux/fs/dlm/dlm_internal.h */
-#define DLM_LKSTS_WAITING 1
-#define DLM_LKSTS_GRANTED 2
-#define DLM_LKSTS_CONVERT 3
-
void parse_r_name(char *line, char *name)
{
char *p;
diff --git a/group/gfs_controld/plock.c b/group/gfs_controld/plock.c
index 0306979..ce17afe 100644
--- a/group/gfs_controld/plock.c
+++ b/group/gfs_controld/plock.c
@@ -2202,6 +2202,8 @@ int fill_plock_dump_buf(struct mountgroup *mg)
memset(plock_dump_buf, 0, sizeof(plock_dump_buf));
plock_dump_len = 0;
+ gettimeofday(&now, NULL);
+
list_for_each_entry(r, &mg->plock_resources, list) {
if (list_empty(&r->locks) &&