[Ocfs2-tools-devel] [PATCH 1/3] debugfs: Add dlm_locks command to debugfs.ocfs2 tool
Sunil Mushran
sunil.mushran at oracle.com
Mon May 5 12:41:48 PDT 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.3.6
More information about the Ocfs2-tools-devel
mailing list