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

Sunil Mushran Sunil.Mushran at oracle.com
Fri May 9 11:50:46 PDT 2008


Thanks. I fixed those and other issues reported by checkpatch.

Tao Ma wrote:
> 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