[Ocfs2-tools-devel] [PATCH 1/3] debugfs: Add dlm_locks command to debugfs.ocfs2 tool

Sunil Mushran sunil.mushran at ORACLE.COM
Mon Feb 25 12:27:03 PST 2008


This patch adds the ability to debugfs.ocfs2 to read the dlm locking
state file, lockres, and dump the lock information in a readable manner.

Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
 debugfs.ocfs2/Makefile                 |    6 +-
 debugfs.ocfs2/commands.c               |   54 ++++-
 debugfs.ocfs2/dump_dlm_locks.c         |  528 ++++++++++++++++++++++++++++++++
 debugfs.ocfs2/include/dump_dlm_locks.h |   85 +++++
 debugfs.ocfs2/include/main.h           |    5 +-
 5 files changed, 672 insertions(+), 6 deletions(-)
 create mode 100644 debugfs.ocfs2/dump_dlm_locks.c
 create mode 100644 debugfs.ocfs2/include/dump_dlm_locks.h

diff --git a/debugfs.ocfs2/Makefile b/debugfs.ocfs2/Makefile
index b17886d..bb70e76 100644
--- a/debugfs.ocfs2/Makefile
+++ b/debugfs.ocfs2/Makefile
@@ -11,7 +11,8 @@ DEFINES += -DVERSION=\"$(VERSION)\"
 INCLUDES = -I$(TOPDIR)/include -Iinclude
 INCLUDES += $(GLIB_CFLAGS)
 
-CFILES = main.c commands.c dump.c utils.c journal.c find_block_inode.c find_inode_paths.c dump_fs_locks.c
+CFILES = main.c commands.c dump.c utils.c journal.c find_block_inode.c \
+	find_inode_paths.c dump_fs_locks.c dump_dlm_locks.c
 
 HFILES =			\
 	include/main.h			\
@@ -22,7 +23,8 @@ HFILES =			\
 	include/find_block_inode.h	\
 	include/find_inode_paths.h	\
 	include/ocfs2_internals.h	\
-	include/dump_fs_locks.h
+	include/dump_fs_locks.h		\
+	include/dump_dlm_locks.h
 
 OBJS = $(subst .c,.o,$(CFILES))
 
diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
index ed93759..cdab387 100644
--- a/debugfs.ocfs2/commands.c
+++ b/debugfs.ocfs2/commands.c
@@ -3,7 +3,7 @@
  *
  * handles debugfs commands
  *
- * Copyright (C) 2004 Oracle.  All rights reserved.
+ * Copyright (C) 2004, 2008 Oracle.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -20,7 +20,6 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 021110-1307, USA.
  *
- * Authors: Sunil Mushran, Manish Singh
  */
 
 #include "main.h"
@@ -69,6 +68,7 @@ static void do_locate (char **args);
 static void do_fs_locks (char **args);
 static void do_bmap (char **args);
 static void do_icheck (char **args);
+static void do_dlm_locks (char **args);
 
 dbgfs_gbls gbls;
 
@@ -79,6 +79,7 @@ static Command commands[] = {
 	{ "chroot",	do_chroot },
 	{ "close",	do_close },
 	{ "curdev",	do_curdev },
+	{ "dlm_locks",	do_dlm_locks },
 	{ "dump",	do_dump },
 	{ "extent",	do_extent },
 	{ "fs_locks",	do_fs_locks },
@@ -795,6 +796,7 @@ static void do_help (char **args)
 	printf ("close\t\t\t\t\tClose a device\n");
 	printf ("curdev\t\t\t\t\tShow current device\n");
 	printf ("decode <lockname#> ...\t\t\tDecode block#(s) from the lockname(s)\n");
+	printf ("dlm_locks [-l] lockname\t\t\tShow live dlm locking state\n");
 	printf ("dump [-p] <filespec> <outfile>\t\tDumps file to outfile on a mounted fs\n");
 	printf ("encode <filespec>\t\t\tShow lock name\n");
 	printf ("extent <block#>\t\t\t\tShow extent block\n");
@@ -1412,6 +1414,54 @@ static void do_locate(char **args)
 }
 
 /*
+ * do_dlm_locks()
+ *
+ */
+static void do_dlm_locks(char **args)
+{
+	FILE *out;
+	int dump_lvbs = 0;
+	int i;
+	struct locknames *lock;
+	struct list_head locklist;
+	struct list_head *iter, *iter2;
+
+	if (check_device_open())
+		return;
+
+	INIT_LIST_HEAD(&locklist);
+
+	i = 1;
+	if (args[i] && strlen(args[i])) {
+		if (!strcmp("-l", args[i])) {
+			dump_lvbs = 1;
+			i++;
+		}
+
+		for ( ; args[i] && strlen(args[i]); ++i) {
+			lock = calloc(1, sizeof(struct locknames));
+			if (lock) {
+				INIT_LIST_HEAD(&lock->list);
+				strncpy(lock->name, args[i], sizeof(lock->name));
+				list_add_tail(&lock->list, &locklist);
+			}
+		}
+	}
+
+	out = open_pager(gbls.interactive);
+	dump_dlm_locks(gbls.fs->uuid_str, out, dump_lvbs, &locklist);
+	close_pager(out);
+
+	if (!list_empty(&locklist)) {
+		list_for_each_safe(iter, iter2, &locklist) {
+			lock = list_entry(iter, struct locknames, list);
+			list_del(iter);
+			free(lock);
+		}
+	}
+}
+
+/*
  * do_dump_fs_locks()
  *
  */
diff --git a/debugfs.ocfs2/dump_dlm_locks.c b/debugfs.ocfs2/dump_dlm_locks.c
new file mode 100644
index 0000000..c7b964a
--- /dev/null
+++ b/debugfs.ocfs2/dump_dlm_locks.c
@@ -0,0 +1,528 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dump_dlm_locks.c
+ *
+ * Interface with the kernel and dump current dlm locking state
+ *
+ * Copyright (C) 2008 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, version 2,  as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will 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.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#define _XOPEN_SOURCE 600  /* Triggers XOPEN2K in features.h */
+#define _LARGEFILE64_SOURCE
+
+#include "main.h"
+#include "ocfs2/byteorder.h"
+#include "ocfs2_internals.h"
+
+static void dump_raw_lvb(const char *lvb, FILE *out)
+{
+	int i, j;
+
+	fprintf(out, "Raw LVB:\t");
+
+	for(i = 0, j = 0; i < DLM_LVB_LEN; i++, j += 2) {
+		fprintf(out, "%c%c ", lvb[j], lvb[j+1]);
+		if (!((i+1) % 16) && i != (DLM_LVB_LEN-1))
+			fprintf(out, "\n\t\t");
+	}
+	fprintf(out, "\n");
+}
+
+static void dump_lock(struct lock *lock, char *queue, FILE *out)
+{
+	GString *action = NULL;
+	char *ast, *bast, *level;
+
+	action = g_string_new(NULL);
+
+	if (lock->type == 0)
+		level = "NL";
+	else if (lock->type == 3)
+		level = "PR";
+	else if (lock->type == 5)
+		level = "EX";
+	else
+		level = "??";
+
+	ast = (lock->ast_list) ? "Yes" : "No";
+	bast = (lock->bast_list) ? "Yes" : "No";
+
+	if (lock->ast_pending)
+		g_string_append(action, "Ast ");
+	if (lock->bast_pending)
+		g_string_append(action, "Bast ");
+	if (lock->convert_pending)
+		g_string_append(action, "Convert ");
+	if (lock->lock_pending)
+		g_string_append(action, "Lock ");
+	if (lock->cancel_pending)
+		g_string_append(action, "Cancel ");
+	if (lock->unlock_pending)
+		g_string_append(action, "Unlock ");
+	if (!action->len)
+		g_string_append(action, "None");
+
+	fprintf(out, " %-10s  %-4d  %-5s  %-4d  %-15s  %-4d  %-3s  %-4s  %s\n",
+		queue, lock->node, level, lock->convert_type, lock->cookie,
+		lock->refs, ast, bast, action->str);
+
+	g_string_free(action, 1);
+}
+
+static void get_lockres_state(__u16 state, GString *str)
+{
+	if (state && DLM_LOCK_RES_UNINITED)
+		g_string_append(str, "Uninitialized");
+	if (state && DLM_LOCK_RES_RECOVERING)
+		g_string_append(str, "Recovering");
+	if (state && DLM_LOCK_RES_READY)
+		g_string_append(str, "Ready");
+	if (state && DLM_LOCK_RES_DIRTY)
+		g_string_append(str, "Dirty");
+	if (state && DLM_LOCK_RES_IN_PROGRESS)
+		g_string_append(str, "InProgress");
+	if (state && DLM_LOCK_RES_MIGRATING)
+		g_string_append(str, "Migrating");
+	if (state && DLM_LOCK_RES_DROPPING_REF)
+		g_string_append(str, "DroppingRef");
+	if (state && DLM_LOCK_RES_BLOCK_DIRTY)
+		g_string_append(str, "BlockDirty");
+	if (state && DLM_LOCK_RES_SETREF_INPROG)
+		g_string_append(str, "SetRefInProg");
+	if (!str->len)
+		g_string_append(str, "");
+}
+
+static void dump_lockres(char *name, struct lockres *res, FILE *out)
+{
+	struct lock *lock;
+	struct list_head *iter;
+	GString *lists = NULL;
+	GString *state = NULL;
+	int numlocks = 0;
+
+	state = g_string_new(NULL);
+	lists = g_string_new(NULL);
+
+	if (res->purge)
+		g_string_append(lists, "Purge ");
+	if (res->dirty)
+		g_string_append(lists, "Dirty ");
+	if (res->recovering)
+		g_string_append(lists, "Recovering ");
+	if (!lists->len)
+		g_string_append(lists, "None");
+
+	get_lockres_state(res->state, state);
+
+	if (!list_empty(&res->granted))
+		list_for_each(iter, &res->granted)
+			++numlocks;
+
+	if (!list_empty(&res->converting))
+		list_for_each(iter, &res->converting)
+			++numlocks;
+
+	if (!list_empty(&res->blocked))
+		list_for_each(iter, &res->blocked)
+			++numlocks;
+
+	/* Lockres: xx  Owner: xx  State: 0x1 xxx */
+	fprintf(out, "Lockres: %-32s  Owner: %-3d  State: 0x%X %s\n",
+		name, res->owner, res->state, state->str);
+
+	/* Last Used: x  ASTs Reserved: x  Inflight: x  Migration Pending: x */
+	fprintf(out, "Last Used: %-5d  ASTs Reserved: %-3d  Inflight: %-3d  "
+		"Migration Pending: %s\n", res->last_used, res->asts_reserved,
+		res->inflight_locks, (res->migration_pending ? "Yes" : "No"));
+
+	/* Refs: xx  Locks: xx  On Lists: xx */
+	fprintf(out, "Refs: %-3d  Locks: %-3d  On Lists: %s\n", res->refs,
+	       	numlocks, lists->str);
+
+	/* Reference Map: xx, xx, xx, xx, xx */
+	fprintf(out, "Reference Map: ");
+	if (res->refmap)
+		fprintf(out, "%s", res->refmap);
+	fprintf(out, "\n");
+
+	/* Raw LVB: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */
+	if (res->lvb)
+		dump_raw_lvb(res->lvb, out);
+
+	/* Lock-Queue  Node  Level  Conv  Cookie  Refs  AST  BAST  Pendi... */
+	fprintf(out, " %-10s  %-4s  %-5s  %-4s  %-15s  %-4s  %-3s  %-4s  %s\n",
+		"Lock-Queue", "Node", "Level", "Conv", "Cookie", "Refs", "AST",
+		"BAST", "Pending-Action");
+
+	/* Granted Queue: */
+	if (!list_empty(&res->granted)) {
+		list_for_each(iter, &res->granted) {
+			lock = list_entry(iter, struct lock, list);
+			dump_lock(lock, "Granted", out);
+		}
+	}
+
+	/* Converting Queue: */
+	if (!list_empty(&res->converting)) {
+		list_for_each(iter, &res->converting) {
+			lock = list_entry(iter, struct lock, list);
+			dump_lock(lock, "Converting", out);
+		}
+	}
+
+	/* Blocked Queue: */
+	if (!list_empty(&res->blocked)) {
+		list_for_each(iter, &res->blocked) {
+			lock = list_entry(iter, struct lock, list);
+			dump_lock(lock, "Blocked", out);
+		}
+	}
+
+	fprintf(out, "\n");
+
+	g_string_free(state, 1);
+	g_string_free(lists, 1);
+}
+
+static int read_lvbx(char *line, struct lockres *res)
+{
+	if (!(res->lvb = strdup(line)))
+		return 0;
+	return 1;
+}
+
+static int read_rmap(char *line, struct lockres *res)
+{
+	int i;
+
+	if (!(res->refmap = strdup(line)))
+		return 0;
+	i = strlen(res->refmap);
+	if (i)
+		res->refmap[i - 1] = '\0';
+	return 1;
+}
+
+#define CURRENT_LOCK_PROTO	1
+static int read_lock(char *line, struct lockres *res)
+{
+	char data[512];
+	int version;
+	struct lock *lock = NULL;
+	__u8 queue;
+	int ret;
+	__u32 ck1, ck2;
+
+	lock = calloc(1, sizeof(struct lock));
+	if (!lock)
+		goto bail;
+
+	INIT_LIST_HEAD(&lock->list);
+
+	/* read version */
+	ret = sscanf(line, "%d,%s\n", &version, data);
+	if (ret != 2)
+		goto bail;
+
+	if (version > CURRENT_LOCK_PROTO) {
+		fprintf(stdout, "Lock string proto %u found, but %u is the "
+			"highest I understand.\n", version, CURRENT_LOCK_PROTO);
+		goto bail;
+	}
+
+	/* Version 1 */
+	if (version == 1) {
+		ret = sscanf(data, "%hhu,%hhd,%hhd,%hhu,%u:%u,%hhu,%hhu,%hhu,"
+			     "%hhu,%hhu,%hhu,%hhu,%hhu,%u", &queue, &lock->type,
+			     &lock->convert_type, &lock->node, &ck1, &ck2,
+			     &lock->ast_list, &lock->bast_list,
+			     &lock->ast_pending, &lock->bast_pending,
+			     &lock->convert_pending, &lock->lock_pending,
+			     &lock->cancel_pending, &lock->unlock_pending,
+			     &lock->refs);
+		if (ret != 15)
+			goto bail;
+
+		snprintf(lock->cookie, sizeof(lock->cookie) - 1, "%u:%u",
+			 ck1, ck2);
+	}
+
+	switch (queue) {
+	case GRANTED: list_add_tail(&lock->list, &res->granted);
+		      break;
+	case CONVERTING:
+		      list_add_tail(&lock->list, &res->converting);
+		      break;
+	case BLOCKED:
+		      list_add_tail(&lock->list, &res->blocked);
+		      break;
+	default:
+		      free(lock);
+		      return 0;
+	}
+
+	return 1;
+
+bail:
+	if (lock)
+		free(lock);
+	return 0;
+}
+
+#define CURRENT_LRES_PROTO	1
+static int read_lres(char *line, struct lockres *res)
+{
+	char data[512];
+	int version;
+	int ret;
+
+	/* read version */
+	ret = sscanf(line, "%d,%s\n", &version, data);
+	if (ret != 2)
+		return 0;
+
+	if (version > CURRENT_LRES_PROTO) {
+		fprintf(stdout, "Lockres string proto %u found, but %u is the "
+			"highest I understand.\n", version,
+			CURRENT_LRES_PROTO);
+		return 0;
+	}
+
+	/* Version 1 */
+	if (version == 1) {
+		ret = sscanf(data, "%hhu,%hu,%u,%hhu,%hhu,%hhu,%u,%hhu,%u,%u",
+			     &res->owner, &res->state, &res->last_used,
+			     &res->purge, &res->dirty, &res->recovering,
+			     &res->inflight_locks, &res->migration_pending,
+			     &res->asts_reserved, &res->refs);
+		if (ret != 10)
+			return 0;
+	}
+
+	return 1;
+}
+
+static void init_lockres(struct lockres *res)
+{
+	memset(res, 0, sizeof(struct lockres));
+	INIT_LIST_HEAD(&res->granted);
+	INIT_LIST_HEAD(&res->converting);
+	INIT_LIST_HEAD(&res->blocked);
+}
+
+static void clean_lockres(struct lockres *res)
+{
+	struct list_head *iter, *iter2;
+	struct lock *lock;
+
+	if (res->lvb)
+		free(res->lvb);
+	if (res->refmap)
+		free(res->refmap);
+
+	if (!list_empty(&res->granted)) {
+		list_for_each_safe(iter, iter2, &res->granted) {
+			lock = list_entry(iter, struct lock, list);
+			list_del(iter);
+			free(lock);
+		}
+	}
+
+	if (!list_empty(&res->converting)) {
+		list_for_each_safe(iter, iter2, &res->converting) {
+			lock = list_entry(iter, struct lock, list);
+			list_del(iter);
+			free(lock);
+		}
+	}
+
+	if (!list_empty(&res->blocked)) {
+		list_for_each_safe(iter, iter2, &res->blocked) {
+			lock = list_entry(iter, struct lock, list);
+			list_del(iter);
+			free(lock);
+		}
+	}
+
+	init_lockres(res);
+}
+
+static void read_lockres(FILE *file, struct lockres *res, int lvb)
+{
+	char line[512];
+
+	while (fgets(line, sizeof(line), file)) {
+		if (line[0] == '\n')
+			break;
+		if (!strncmp(line, "LRES:", 5))
+			read_lres(line + 5, res);
+		else if (!strncmp(line, "RMAP:", 5))
+			read_rmap(line + 5, res);
+		else if (!strncmp(line, "LOCK:", 5))
+			read_lock(line + 5, res);
+		else if (!strncmp(line, "LVBX:", 5)) {
+			if (lvb)
+				read_lvbx(line + 5, res);
+		}
+	}
+}
+
+static int lockname_in_list(char *name, struct list_head *locklist)
+{
+	struct locknames *l;
+	struct list_head *iter, *iter2;
+
+	if (!list_empty(locklist)) {
+		list_for_each_safe(iter, iter2, locklist) {
+			l = list_entry(iter, struct locknames, list);
+			if (!strncmp(name, l->name, sizeof(l->name))) {
+				list_del(iter);
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int get_next_dlm_lockname(FILE *file, char *name, int len)
+{
+	char line[512];
+
+	while (fgets(line, sizeof(line), file)) {
+		if (strncmp(line, "NAME:", 5))
+			continue;
+		sscanf(line + 5, "%s\n", name);
+		return 1;
+	}
+
+	return 0;
+}
+
+#define DEBUGFS_MAGIC   0x64626720
+static errcode_t try_debugfs_path(const char *path)
+{
+	errcode_t ret;
+	struct stat64 stat_buf;
+	struct statfs64 statfs_buf;
+
+	ret = stat64(path, &stat_buf);
+	if (ret || !S_ISDIR(stat_buf.st_mode))
+		return O2CB_ET_SERVICE_UNAVAILABLE;
+	ret = statfs64(path, &statfs_buf);
+	if (ret || (statfs_buf.f_type != DEBUGFS_MAGIC))
+		return O2CB_ET_SERVICE_UNAVAILABLE;
+
+	return 0;
+}
+
+#define DLM_LOCKING_STATE_FORMAT_PATH "%s/o2dlm/%s/locking_state"
+static errcode_t open_dlm_locking_state(const char *debugfs_path,
+					const char *uuid_str,
+					FILE **state_file)
+{
+	errcode_t ret = 0;
+	char path[PATH_MAX];
+
+	ret = snprintf(path, PATH_MAX - 1, DLM_LOCKING_STATE_FORMAT_PATH,
+		       debugfs_path, uuid_str);
+	if ((ret <= 0) || (ret == (PATH_MAX - 1)))
+		return O2CB_ET_INTERNAL_FAILURE;
+
+	*state_file = fopen(path, "r");
+	if (!*state_file) {
+		switch (errno) {
+			default:
+				ret = O2CB_ET_INTERNAL_FAILURE;
+				break;
+
+			case ENOTDIR:
+			case ENOENT:
+			case EISDIR:
+				ret = O2CB_ET_SERVICE_UNAVAILABLE;
+				break;
+
+			case EACCES:
+			case EPERM:
+			case EROFS:
+				ret = O2CB_ET_PERMISSION_DENIED;
+				break;
+		}
+		goto out;
+	}
+
+	ret = 0;
+out:
+	return ret;
+}
+
+#define SYSFS_BASE		"/sys/kernel/"
+#define DEBUGFS_PATH		SYSFS_BASE "debug"
+#define DEBUGFS_ALTERNATE_PATH	"/debug"
+
+void dump_dlm_locks(char *uuid, FILE *out, int dump_lvbs,
+		    struct list_head *locklist)
+{
+	errcode_t ret;
+	int err;
+	const char *debugfs_path = DEBUGFS_PATH;
+	struct stat64 stat_buf;
+	FILE *file;
+	char name[OCFS2_LOCK_ID_MAX_LEN];
+	struct lockres res;
+	int show_all_locks = 0;
+
+	err = stat64(SYSFS_BASE, &stat_buf);
+	if (err)
+		debugfs_path = DEBUGFS_ALTERNATE_PATH;
+
+	ret = try_debugfs_path(debugfs_path);
+	if (ret) {
+		fprintf(stderr, "Could not locate debugfs file system. "
+			"Perhaps it is not mounted?\n");
+		return;
+	}
+
+	ret = open_dlm_locking_state(debugfs_path, uuid, &file);
+	if (ret) {
+		fprintf(stderr, "Could not open debug state for \"%s\".\n"
+			"Perhaps that OCFS2 file system is not mounted?\n",
+			uuid);
+		return;
+	}
+
+	show_all_locks = list_empty(locklist);
+	init_lockres(&res);
+
+	while (get_next_dlm_lockname(file, name, sizeof(name))) {
+		if (show_all_locks || lockname_in_list(name, locklist)) {
+			read_lockres(file, &res, dump_lvbs);
+
+			dump_lockres(name, &res, out);
+
+			clean_lockres(&res);
+		}
+
+		if (!show_all_locks && list_empty(locklist))
+			break;
+	}
+
+	fclose(file);
+}
diff --git a/debugfs.ocfs2/include/dump_dlm_locks.h b/debugfs.ocfs2/include/dump_dlm_locks.h
new file mode 100644
index 0000000..cf43318
--- /dev/null
+++ b/debugfs.ocfs2/include/dump_dlm_locks.h
@@ -0,0 +1,85 @@
+/*
+ * dump_dlm_locks.h
+ *
+ * Function prototypes, macros, etc. for related 'C' files
+ *
+ * Copyright (C) 2008 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will 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.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef _DUMP_DLM_LOCKS_H_
+#define _DUMP_DLM_LOCKS_H_
+
+#define DLM_LOCK_RES_UNINITED             0x00000001
+#define DLM_LOCK_RES_RECOVERING           0x00000002
+#define DLM_LOCK_RES_READY                0x00000004
+#define DLM_LOCK_RES_DIRTY                0x00000008
+#define DLM_LOCK_RES_IN_PROGRESS          0x00000010
+#define DLM_LOCK_RES_MIGRATING            0x00000020
+#define DLM_LOCK_RES_DROPPING_REF         0x00000040
+#define DLM_LOCK_RES_BLOCK_DIRTY          0x00001000
+#define DLM_LOCK_RES_SETREF_INPROG        0x00002000
+
+#define GRANTED		0
+#define CONVERTING	1
+#define BLOCKED		2
+
+struct lockres {
+	__u8 owner;
+	__u16 state;
+	__u32 last_used;
+	__u32 inflight_locks;
+	__u32 asts_reserved;
+	__u32 refs;
+	__u8 purge;
+	__u8 dirty;
+	__u8 recovering;
+	__u8 migration_pending;
+	char *refmap;
+	char *lvb;
+	struct list_head granted;
+	struct list_head converting;
+	struct list_head blocked;
+};
+
+struct lock {
+	__s8 type;
+	__s8 convert_type;
+	__u8 node;
+	__u8 ast_list;
+	__u8 bast_list;
+	__u8 ast_pending;
+	__u8 bast_pending;
+	__u8 convert_pending;
+	__u8 lock_pending;
+	__u8 cancel_pending;
+	__u8 unlock_pending;
+	__u32 refs;
+	char cookie[32];
+	struct list_head list;
+};
+
+struct locknames {
+	char name[OCFS2_LOCK_ID_MAX_LEN];
+	struct list_head list;
+};
+
+void dump_dlm_locks(char *uuid, FILE *out, int dump_lvbs,
+		    struct list_head *all_locks);
+
+#endif		/* _DUMP_DLM_LOCKS_H_ */
diff --git a/debugfs.ocfs2/include/main.h b/debugfs.ocfs2/include/main.h
index f0e0c2b..942a1e4 100644
--- a/debugfs.ocfs2/include/main.h
+++ b/debugfs.ocfs2/include/main.h
@@ -3,7 +3,7 @@
  *
  * Function prototypes, macros, etc. for related 'C' files
  *
- * Copyright (C) 2004 Oracle.  All rights reserved.
+ * Copyright (C) 2004, 2008 Oracle.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -20,7 +20,6 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 021110-1307, USA.
  *
- * Authors: Sunil Mushran
  */
 
 #ifndef __MAIN_H__
@@ -34,6 +33,7 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/statfs.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <pwd.h>
@@ -161,6 +161,7 @@ typedef struct _dbgfs_opts {
 #include <find_block_inode.h>
 #include <find_inode_paths.h>
 #include <dump_fs_locks.h>
+#include <dump_dlm_locks.h>
 #include <dump.h>
 
 #endif		/* __MAIN_H__ */
-- 
1.5.2.5




More information about the Ocfs2-tools-devel mailing list