[Ocfs2-tools-devel] [PATCH 1/3] debugfs: Add dlm_locks command to debugfs.ocfs2 tool
Tao Ma
tao.ma at oracle.com
Fri May 9 00:03:09 PDT 2008
Signed-off-by: Tao Ma <tao.ma at oracle.com>
Just small comment. When using git apply, find some trailing whitespace
and one space before tab in indent.
git apply ~/patches/review/dlm_locks/\[Ocfs2-tools-devel\]\ \[PATCH\
1_3\]\ debugfs\:\ Add\ dlm_locks\ command\ to\ debugfs.ocfs2\ tool.eml
/home/taoma/patches/review/dlm_locks/[Ocfs2-tools-devel] [PATCH 1_3]
debugfs: Add dlm_locks command to debugfs.ocfs2 tool.eml:217:
trailing whitespace.
*
/home/taoma/patches/review/dlm_locks/[Ocfs2-tools-devel] [PATCH 1_3]
debugfs: Add dlm_locks command to debugfs.ocfs2 tool.eml:222:
trailing whitespace.
*
/home/taoma/patches/review/dlm_locks/[Ocfs2-tools-devel] [PATCH 1_3]
debugfs: Add dlm_locks command to debugfs.ocfs2 tool.eml:361:
space before tab in indent.
numlocks, lists->str);
/home/taoma/patches/review/dlm_locks/[Ocfs2-tools-devel] [PATCH 1_3]
debugfs: Add dlm_locks command to debugfs.ocfs2 tool.eml:750:
trailing whitespace.
*
/home/taoma/patches/review/dlm_locks/[Ocfs2-tools-devel] [PATCH 1_3]
debugfs: Add dlm_locks command to debugfs.ocfs2 tool.eml:755:
trailing whitespace.
*
Sunil Mushran wrote:
> 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__ */
More information about the Ocfs2-tools-devel
mailing list