1328970deSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2fa60ce2cSMasahiro Yamada /*
36714d8e8SKurt Hackel * dlmdebug.c
46714d8e8SKurt Hackel *
56714d8e8SKurt Hackel * debug functionality for the dlm
66714d8e8SKurt Hackel *
7c834cdb1SSunil Mushran * Copyright (C) 2004, 2008 Oracle. All rights reserved.
86714d8e8SKurt Hackel */
96714d8e8SKurt Hackel
106714d8e8SKurt Hackel #include <linux/types.h>
116714d8e8SKurt Hackel #include <linux/slab.h>
126714d8e8SKurt Hackel #include <linux/highmem.h>
136714d8e8SKurt Hackel #include <linux/sysctl.h>
146714d8e8SKurt Hackel #include <linux/spinlock.h>
156325b4a2SSunil Mushran #include <linux/debugfs.h>
16afeacc8cSPaul Gortmaker #include <linux/export.h>
176714d8e8SKurt Hackel
18ca322fb6SMasahiro Yamada #include "../cluster/heartbeat.h"
19ca322fb6SMasahiro Yamada #include "../cluster/nodemanager.h"
20ca322fb6SMasahiro Yamada #include "../cluster/tcp.h"
216714d8e8SKurt Hackel
226714d8e8SKurt Hackel #include "dlmapi.h"
236714d8e8SKurt Hackel #include "dlmcommon.h"
246714d8e8SKurt Hackel #include "dlmdomain.h"
256325b4a2SSunil Mushran #include "dlmdebug.h"
266714d8e8SKurt Hackel
276714d8e8SKurt Hackel #define MLOG_MASK_PREFIX ML_DLM
28ca322fb6SMasahiro Yamada #include "../cluster/masklog.h"
296714d8e8SKurt Hackel
3095642e56SAdrian Bunk static int stringify_lockname(const char *lockname, int locklen, char *buf,
3195642e56SAdrian Bunk int len);
32c834cdb1SSunil Mushran
dlm_print_one_lock_resource(struct dlm_lock_resource * res)336714d8e8SKurt Hackel void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
346714d8e8SKurt Hackel {
356714d8e8SKurt Hackel spin_lock(&res->spinlock);
366714d8e8SKurt Hackel __dlm_print_one_lock_resource(res);
376714d8e8SKurt Hackel spin_unlock(&res->spinlock);
386714d8e8SKurt Hackel }
396714d8e8SKurt Hackel
dlm_print_lockres_refmap(struct dlm_lock_resource * res)40ba2bf218SKurt Hackel static void dlm_print_lockres_refmap(struct dlm_lock_resource *res)
41ba2bf218SKurt Hackel {
42ba2bf218SKurt Hackel int bit;
43ba2bf218SKurt Hackel assert_spin_locked(&res->spinlock);
44ba2bf218SKurt Hackel
458f50eb97SSunil Mushran printk(" refmap nodes: [ ");
46ba2bf218SKurt Hackel bit = 0;
47ba2bf218SKurt Hackel while (1) {
48ba2bf218SKurt Hackel bit = find_next_bit(res->refmap, O2NM_MAX_NODES, bit);
49ba2bf218SKurt Hackel if (bit >= O2NM_MAX_NODES)
50ba2bf218SKurt Hackel break;
518f50eb97SSunil Mushran printk("%u ", bit);
52ba2bf218SKurt Hackel bit++;
53ba2bf218SKurt Hackel }
548f50eb97SSunil Mushran printk("], inflight=%u\n", res->inflight_locks);
55c834cdb1SSunil Mushran }
56c834cdb1SSunil Mushran
__dlm_print_lock(struct dlm_lock * lock)57c834cdb1SSunil Mushran static void __dlm_print_lock(struct dlm_lock *lock)
58c834cdb1SSunil Mushran {
59c834cdb1SSunil Mushran spin_lock(&lock->spinlock);
60c834cdb1SSunil Mushran
618f50eb97SSunil Mushran printk(" type=%d, conv=%d, node=%u, cookie=%u:%llu, "
62c834cdb1SSunil Mushran "ref=%u, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c), "
63c834cdb1SSunil Mushran "pending=(conv=%c,lock=%c,cancel=%c,unlock=%c)\n",
64c834cdb1SSunil Mushran lock->ml.type, lock->ml.convert_type, lock->ml.node,
65c834cdb1SSunil Mushran dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
66c834cdb1SSunil Mushran dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
672c935bc5SPeter Zijlstra kref_read(&lock->lock_refs),
68c834cdb1SSunil Mushran (list_empty(&lock->ast_list) ? 'y' : 'n'),
69c834cdb1SSunil Mushran (lock->ast_pending ? 'y' : 'n'),
70c834cdb1SSunil Mushran (list_empty(&lock->bast_list) ? 'y' : 'n'),
71c834cdb1SSunil Mushran (lock->bast_pending ? 'y' : 'n'),
72c834cdb1SSunil Mushran (lock->convert_pending ? 'y' : 'n'),
73c834cdb1SSunil Mushran (lock->lock_pending ? 'y' : 'n'),
74c834cdb1SSunil Mushran (lock->cancel_pending ? 'y' : 'n'),
75c834cdb1SSunil Mushran (lock->unlock_pending ? 'y' : 'n'));
76c834cdb1SSunil Mushran
77c834cdb1SSunil Mushran spin_unlock(&lock->spinlock);
78ba2bf218SKurt Hackel }
79ba2bf218SKurt Hackel
__dlm_print_one_lock_resource(struct dlm_lock_resource * res)806714d8e8SKurt Hackel void __dlm_print_one_lock_resource(struct dlm_lock_resource *res)
816714d8e8SKurt Hackel {
826714d8e8SKurt Hackel struct dlm_lock *lock;
83c834cdb1SSunil Mushran char buf[DLM_LOCKID_NAME_MAX];
846714d8e8SKurt Hackel
856714d8e8SKurt Hackel assert_spin_locked(&res->spinlock);
866714d8e8SKurt Hackel
87c834cdb1SSunil Mushran stringify_lockname(res->lockname.name, res->lockname.len,
8886a06abaSSunil Mushran buf, sizeof(buf));
898f50eb97SSunil Mushran printk("lockres: %s, owner=%u, state=%u\n",
90c834cdb1SSunil Mushran buf, res->owner, res->state);
918f50eb97SSunil Mushran printk(" last used: %lu, refcnt: %u, on purge list: %s\n",
922c935bc5SPeter Zijlstra res->last_used, kref_read(&res->refs),
93c834cdb1SSunil Mushran list_empty(&res->purge) ? "no" : "yes");
948f50eb97SSunil Mushran printk(" on dirty list: %s, on reco list: %s, "
95c834cdb1SSunil Mushran "migrating pending: %s\n",
96c834cdb1SSunil Mushran list_empty(&res->dirty) ? "no" : "yes",
97c834cdb1SSunil Mushran list_empty(&res->recovering) ? "no" : "yes",
98c834cdb1SSunil Mushran res->migration_pending ? "yes" : "no");
998f50eb97SSunil Mushran printk(" inflight locks: %d, asts reserved: %d\n",
100c834cdb1SSunil Mushran res->inflight_locks, atomic_read(&res->asts_reserved));
101ba2bf218SKurt Hackel dlm_print_lockres_refmap(res);
1028f50eb97SSunil Mushran printk(" granted queue:\n");
103df53cd3bSDong Fang list_for_each_entry(lock, &res->granted, list) {
104c834cdb1SSunil Mushran __dlm_print_lock(lock);
1056714d8e8SKurt Hackel }
1068f50eb97SSunil Mushran printk(" converting queue:\n");
107df53cd3bSDong Fang list_for_each_entry(lock, &res->converting, list) {
108c834cdb1SSunil Mushran __dlm_print_lock(lock);
1096714d8e8SKurt Hackel }
1108f50eb97SSunil Mushran printk(" blocked queue:\n");
111df53cd3bSDong Fang list_for_each_entry(lock, &res->blocked, list) {
112c834cdb1SSunil Mushran __dlm_print_lock(lock);
1136714d8e8SKurt Hackel }
1146714d8e8SKurt Hackel }
1156714d8e8SKurt Hackel
dlm_print_one_lock(struct dlm_lock * lockid)1166714d8e8SKurt Hackel void dlm_print_one_lock(struct dlm_lock *lockid)
1176714d8e8SKurt Hackel {
1186714d8e8SKurt Hackel dlm_print_one_lock_resource(lockid->lockres);
1196714d8e8SKurt Hackel }
1206714d8e8SKurt Hackel EXPORT_SYMBOL_GPL(dlm_print_one_lock);
1216714d8e8SKurt Hackel
1226714d8e8SKurt Hackel static const char *dlm_errnames[] = {
1236714d8e8SKurt Hackel [DLM_NORMAL] = "DLM_NORMAL",
1246714d8e8SKurt Hackel [DLM_GRANTED] = "DLM_GRANTED",
1256714d8e8SKurt Hackel [DLM_DENIED] = "DLM_DENIED",
1266714d8e8SKurt Hackel [DLM_DENIED_NOLOCKS] = "DLM_DENIED_NOLOCKS",
1276714d8e8SKurt Hackel [DLM_WORKING] = "DLM_WORKING",
1286714d8e8SKurt Hackel [DLM_BLOCKED] = "DLM_BLOCKED",
1296714d8e8SKurt Hackel [DLM_BLOCKED_ORPHAN] = "DLM_BLOCKED_ORPHAN",
1306714d8e8SKurt Hackel [DLM_DENIED_GRACE_PERIOD] = "DLM_DENIED_GRACE_PERIOD",
1316714d8e8SKurt Hackel [DLM_SYSERR] = "DLM_SYSERR",
1326714d8e8SKurt Hackel [DLM_NOSUPPORT] = "DLM_NOSUPPORT",
1336714d8e8SKurt Hackel [DLM_CANCELGRANT] = "DLM_CANCELGRANT",
1346714d8e8SKurt Hackel [DLM_IVLOCKID] = "DLM_IVLOCKID",
1356714d8e8SKurt Hackel [DLM_SYNC] = "DLM_SYNC",
1366714d8e8SKurt Hackel [DLM_BADTYPE] = "DLM_BADTYPE",
1376714d8e8SKurt Hackel [DLM_BADRESOURCE] = "DLM_BADRESOURCE",
1386714d8e8SKurt Hackel [DLM_MAXHANDLES] = "DLM_MAXHANDLES",
1396714d8e8SKurt Hackel [DLM_NOCLINFO] = "DLM_NOCLINFO",
1406714d8e8SKurt Hackel [DLM_NOLOCKMGR] = "DLM_NOLOCKMGR",
1416714d8e8SKurt Hackel [DLM_NOPURGED] = "DLM_NOPURGED",
1426714d8e8SKurt Hackel [DLM_BADARGS] = "DLM_BADARGS",
1436714d8e8SKurt Hackel [DLM_VOID] = "DLM_VOID",
1446714d8e8SKurt Hackel [DLM_NOTQUEUED] = "DLM_NOTQUEUED",
1456714d8e8SKurt Hackel [DLM_IVBUFLEN] = "DLM_IVBUFLEN",
1466714d8e8SKurt Hackel [DLM_CVTUNGRANT] = "DLM_CVTUNGRANT",
1476714d8e8SKurt Hackel [DLM_BADPARAM] = "DLM_BADPARAM",
1486714d8e8SKurt Hackel [DLM_VALNOTVALID] = "DLM_VALNOTVALID",
1496714d8e8SKurt Hackel [DLM_REJECTED] = "DLM_REJECTED",
1506714d8e8SKurt Hackel [DLM_ABORT] = "DLM_ABORT",
1516714d8e8SKurt Hackel [DLM_CANCEL] = "DLM_CANCEL",
1526714d8e8SKurt Hackel [DLM_IVRESHANDLE] = "DLM_IVRESHANDLE",
1536714d8e8SKurt Hackel [DLM_DEADLOCK] = "DLM_DEADLOCK",
1546714d8e8SKurt Hackel [DLM_DENIED_NOASTS] = "DLM_DENIED_NOASTS",
1556714d8e8SKurt Hackel [DLM_FORWARD] = "DLM_FORWARD",
1566714d8e8SKurt Hackel [DLM_TIMEOUT] = "DLM_TIMEOUT",
1576714d8e8SKurt Hackel [DLM_IVGROUPID] = "DLM_IVGROUPID",
1586714d8e8SKurt Hackel [DLM_VERS_CONFLICT] = "DLM_VERS_CONFLICT",
1596714d8e8SKurt Hackel [DLM_BAD_DEVICE_PATH] = "DLM_BAD_DEVICE_PATH",
1606714d8e8SKurt Hackel [DLM_NO_DEVICE_PERMISSION] = "DLM_NO_DEVICE_PERMISSION",
1616714d8e8SKurt Hackel [DLM_NO_CONTROL_DEVICE ] = "DLM_NO_CONTROL_DEVICE ",
1626714d8e8SKurt Hackel [DLM_RECOVERING] = "DLM_RECOVERING",
1636714d8e8SKurt Hackel [DLM_MIGRATING] = "DLM_MIGRATING",
1646714d8e8SKurt Hackel [DLM_MAXSTATS] = "DLM_MAXSTATS",
1656714d8e8SKurt Hackel };
1666714d8e8SKurt Hackel
1676714d8e8SKurt Hackel static const char *dlm_errmsgs[] = {
1686714d8e8SKurt Hackel [DLM_NORMAL] = "request in progress",
1696714d8e8SKurt Hackel [DLM_GRANTED] = "request granted",
1706714d8e8SKurt Hackel [DLM_DENIED] = "request denied",
1716714d8e8SKurt Hackel [DLM_DENIED_NOLOCKS] = "request denied, out of system resources",
1726714d8e8SKurt Hackel [DLM_WORKING] = "async request in progress",
1736714d8e8SKurt Hackel [DLM_BLOCKED] = "lock request blocked",
1746714d8e8SKurt Hackel [DLM_BLOCKED_ORPHAN] = "lock request blocked by a orphan lock",
1756714d8e8SKurt Hackel [DLM_DENIED_GRACE_PERIOD] = "topological change in progress",
1766714d8e8SKurt Hackel [DLM_SYSERR] = "system error",
1776714d8e8SKurt Hackel [DLM_NOSUPPORT] = "unsupported",
1786714d8e8SKurt Hackel [DLM_CANCELGRANT] = "can't cancel convert: already granted",
1796714d8e8SKurt Hackel [DLM_IVLOCKID] = "bad lockid",
1806714d8e8SKurt Hackel [DLM_SYNC] = "synchronous request granted",
1816714d8e8SKurt Hackel [DLM_BADTYPE] = "bad resource type",
1826714d8e8SKurt Hackel [DLM_BADRESOURCE] = "bad resource handle",
1836714d8e8SKurt Hackel [DLM_MAXHANDLES] = "no more resource handles",
1846714d8e8SKurt Hackel [DLM_NOCLINFO] = "can't contact cluster manager",
1856714d8e8SKurt Hackel [DLM_NOLOCKMGR] = "can't contact lock manager",
1866714d8e8SKurt Hackel [DLM_NOPURGED] = "can't contact purge daemon",
1876714d8e8SKurt Hackel [DLM_BADARGS] = "bad api args",
1886714d8e8SKurt Hackel [DLM_VOID] = "no status",
1896714d8e8SKurt Hackel [DLM_NOTQUEUED] = "NOQUEUE was specified and request failed",
1906714d8e8SKurt Hackel [DLM_IVBUFLEN] = "invalid resource name length",
1916714d8e8SKurt Hackel [DLM_CVTUNGRANT] = "attempted to convert ungranted lock",
1926714d8e8SKurt Hackel [DLM_BADPARAM] = "invalid lock mode specified",
1936714d8e8SKurt Hackel [DLM_VALNOTVALID] = "value block has been invalidated",
1946714d8e8SKurt Hackel [DLM_REJECTED] = "request rejected, unrecognized client",
1956714d8e8SKurt Hackel [DLM_ABORT] = "blocked lock request cancelled",
1966714d8e8SKurt Hackel [DLM_CANCEL] = "conversion request cancelled",
1976714d8e8SKurt Hackel [DLM_IVRESHANDLE] = "invalid resource handle",
1986714d8e8SKurt Hackel [DLM_DEADLOCK] = "deadlock recovery refused this request",
1996714d8e8SKurt Hackel [DLM_DENIED_NOASTS] = "failed to allocate AST",
2006714d8e8SKurt Hackel [DLM_FORWARD] = "request must wait for primary's response",
2016714d8e8SKurt Hackel [DLM_TIMEOUT] = "timeout value for lock has expired",
2026714d8e8SKurt Hackel [DLM_IVGROUPID] = "invalid group specification",
2036714d8e8SKurt Hackel [DLM_VERS_CONFLICT] = "version conflicts prevent request handling",
2046714d8e8SKurt Hackel [DLM_BAD_DEVICE_PATH] = "Locks device does not exist or path wrong",
2056714d8e8SKurt Hackel [DLM_NO_DEVICE_PERMISSION] = "Client has insufficient perms for device",
2066714d8e8SKurt Hackel [DLM_NO_CONTROL_DEVICE] = "Cannot set options on opened device ",
2076714d8e8SKurt Hackel [DLM_RECOVERING] = "lock resource being recovered",
2086714d8e8SKurt Hackel [DLM_MIGRATING] = "lock resource being migrated",
2096714d8e8SKurt Hackel [DLM_MAXSTATS] = "invalid error number",
2106714d8e8SKurt Hackel };
2116714d8e8SKurt Hackel
dlm_errmsg(enum dlm_status err)2126714d8e8SKurt Hackel const char *dlm_errmsg(enum dlm_status err)
2136714d8e8SKurt Hackel {
2146714d8e8SKurt Hackel if (err >= DLM_MAXSTATS || err < 0)
2156714d8e8SKurt Hackel return dlm_errmsgs[DLM_MAXSTATS];
2166714d8e8SKurt Hackel return dlm_errmsgs[err];
2176714d8e8SKurt Hackel }
2186714d8e8SKurt Hackel EXPORT_SYMBOL_GPL(dlm_errmsg);
2196714d8e8SKurt Hackel
dlm_errname(enum dlm_status err)2206714d8e8SKurt Hackel const char *dlm_errname(enum dlm_status err)
2216714d8e8SKurt Hackel {
2226714d8e8SKurt Hackel if (err >= DLM_MAXSTATS || err < 0)
2236714d8e8SKurt Hackel return dlm_errnames[DLM_MAXSTATS];
2246714d8e8SKurt Hackel return dlm_errnames[err];
2256714d8e8SKurt Hackel }
2266714d8e8SKurt Hackel EXPORT_SYMBOL_GPL(dlm_errname);
2276325b4a2SSunil Mushran
2284e3d24edSSunil Mushran /* NOTE: This function converts a lockname into a string. It uses knowledge
2294e3d24edSSunil Mushran * of the format of the lockname that should be outside the purview of the dlm.
2304e3d24edSSunil Mushran * We are adding only to make dlm debugging slightly easier.
2314e3d24edSSunil Mushran *
2324e3d24edSSunil Mushran * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h.
2334e3d24edSSunil Mushran */
stringify_lockname(const char * lockname,int locklen,char * buf,int len)23495642e56SAdrian Bunk static int stringify_lockname(const char *lockname, int locklen, char *buf,
23595642e56SAdrian Bunk int len)
2364e3d24edSSunil Mushran {
2374e3d24edSSunil Mushran int out = 0;
2384e3d24edSSunil Mushran __be64 inode_blkno_be;
2394e3d24edSSunil Mushran
2404e3d24edSSunil Mushran #define OCFS2_DENTRY_LOCK_INO_START 18
2414e3d24edSSunil Mushran if (*lockname == 'N') {
2424e3d24edSSunil Mushran memcpy((__be64 *)&inode_blkno_be,
2434e3d24edSSunil Mushran (char *)&lockname[OCFS2_DENTRY_LOCK_INO_START],
2444e3d24edSSunil Mushran sizeof(__be64));
245d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "%.*s%08x",
2464e3d24edSSunil Mushran OCFS2_DENTRY_LOCK_INO_START - 1, lockname,
2474e3d24edSSunil Mushran (unsigned int)be64_to_cpu(inode_blkno_be));
2484e3d24edSSunil Mushran } else
249d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "%.*s",
2504e3d24edSSunil Mushran locklen, lockname);
2514e3d24edSSunil Mushran return out;
2524e3d24edSSunil Mushran }
2534e3d24edSSunil Mushran
stringify_nodemap(unsigned long * nodemap,int maxnodes,char * buf,int len)254e5a0334cSSunil Mushran static int stringify_nodemap(unsigned long *nodemap, int maxnodes,
255e5a0334cSSunil Mushran char *buf, int len)
256e5a0334cSSunil Mushran {
257e5a0334cSSunil Mushran int out = 0;
258e5a0334cSSunil Mushran int i = -1;
259e5a0334cSSunil Mushran
260e5a0334cSSunil Mushran while ((i = find_next_bit(nodemap, maxnodes, i + 1)) < maxnodes)
261d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "%d ", i);
262e5a0334cSSunil Mushran
263e5a0334cSSunil Mushran return out;
264e5a0334cSSunil Mushran }
265e5a0334cSSunil Mushran
dump_mle(struct dlm_master_list_entry * mle,char * buf,int len)266e5a0334cSSunil Mushran static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
267e5a0334cSSunil Mushran {
268e5a0334cSSunil Mushran int out = 0;
269e5a0334cSSunil Mushran char *mle_type;
270e5a0334cSSunil Mushran
271e5a0334cSSunil Mushran if (mle->type == DLM_MLE_BLOCK)
272e5a0334cSSunil Mushran mle_type = "BLK";
273e5a0334cSSunil Mushran else if (mle->type == DLM_MLE_MASTER)
274e5a0334cSSunil Mushran mle_type = "MAS";
275e5a0334cSSunil Mushran else
276e5a0334cSSunil Mushran mle_type = "MIG";
277e5a0334cSSunil Mushran
2787141514bSSunil Mushran out += stringify_lockname(mle->mname, mle->mnamelen, buf + out, len - out);
279d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
280e5a0334cSSunil Mushran "\t%3s\tmas=%3u\tnew=%3u\tevt=%1d\tuse=%1d\tref=%3d\n",
281e5a0334cSSunil Mushran mle_type, mle->master, mle->new_master,
282e5a0334cSSunil Mushran !list_empty(&mle->hb_events),
283e5a0334cSSunil Mushran !!mle->inuse,
2842c935bc5SPeter Zijlstra kref_read(&mle->mle_refs));
285e5a0334cSSunil Mushran
286d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Maybe=");
287e5a0334cSSunil Mushran out += stringify_nodemap(mle->maybe_map, O2NM_MAX_NODES,
288e5a0334cSSunil Mushran buf + out, len - out);
289d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
290e5a0334cSSunil Mushran
291d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Vote=");
292e5a0334cSSunil Mushran out += stringify_nodemap(mle->vote_map, O2NM_MAX_NODES,
293e5a0334cSSunil Mushran buf + out, len - out);
294d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
295e5a0334cSSunil Mushran
296d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Response=");
297e5a0334cSSunil Mushran out += stringify_nodemap(mle->response_map, O2NM_MAX_NODES,
298e5a0334cSSunil Mushran buf + out, len - out);
299d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
300e5a0334cSSunil Mushran
301d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Node=");
302e5a0334cSSunil Mushran out += stringify_nodemap(mle->node_map, O2NM_MAX_NODES,
303e5a0334cSSunil Mushran buf + out, len - out);
304d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
305e5a0334cSSunil Mushran
306d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
307e5a0334cSSunil Mushran
308e5a0334cSSunil Mushran return out;
309e5a0334cSSunil Mushran }
310e5a0334cSSunil Mushran
dlm_print_one_mle(struct dlm_master_list_entry * mle)311e5a0334cSSunil Mushran void dlm_print_one_mle(struct dlm_master_list_entry *mle)
312e5a0334cSSunil Mushran {
313e5a0334cSSunil Mushran char *buf;
314e5a0334cSSunil Mushran
31599986576SJia-Ju Bai buf = (char *) get_zeroed_page(GFP_ATOMIC);
316e5a0334cSSunil Mushran if (buf) {
317e5a0334cSSunil Mushran dump_mle(mle, buf, PAGE_SIZE - 1);
318e5a0334cSSunil Mushran free_page((unsigned long)buf);
319e5a0334cSSunil Mushran }
320e5a0334cSSunil Mushran }
321e5a0334cSSunil Mushran
322e5a0334cSSunil Mushran #ifdef CONFIG_DEBUG_FS
323e5a0334cSSunil Mushran
3241a5c4e2aSFabian Frederick static struct dentry *dlm_debugfs_root;
325e5a0334cSSunil Mushran
3266325b4a2SSunil Mushran #define DLM_DEBUGFS_DIR "o2dlm"
327007dce53SSunil Mushran #define DLM_DEBUGFS_DLM_STATE "dlm_state"
3284e3d24edSSunil Mushran #define DLM_DEBUGFS_LOCKING_STATE "locking_state"
329d0129aceSSunil Mushran #define DLM_DEBUGFS_MLE_STATE "mle_state"
3307209300aSSunil Mushran #define DLM_DEBUGFS_PURGE_LIST "purge_list"
331007dce53SSunil Mushran
332007dce53SSunil Mushran /* begin - utils funcs */
debug_release(struct inode * inode,struct file * file)33302bd9c39SSunil Mushran static int debug_release(struct inode *inode, struct file *file)
334007dce53SSunil Mushran {
33502bd9c39SSunil Mushran free_page((unsigned long)file->private_data);
33602bd9c39SSunil Mushran return 0;
337007dce53SSunil Mushran }
338007dce53SSunil Mushran
debug_read(struct file * file,char __user * buf,size_t nbytes,loff_t * ppos)33902bd9c39SSunil Mushran static ssize_t debug_read(struct file *file, char __user *buf,
340007dce53SSunil Mushran size_t nbytes, loff_t *ppos)
341007dce53SSunil Mushran {
34202bd9c39SSunil Mushran return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
34302bd9c39SSunil Mushran i_size_read(file->f_mapping->host));
344007dce53SSunil Mushran }
345007dce53SSunil Mushran /* end - util funcs */
346007dce53SSunil Mushran
3477209300aSSunil Mushran /* begin - purge list funcs */
debug_purgelist_print(struct dlm_ctxt * dlm,char * buf,int len)34802bd9c39SSunil Mushran static int debug_purgelist_print(struct dlm_ctxt *dlm, char *buf, int len)
3497209300aSSunil Mushran {
3507209300aSSunil Mushran struct dlm_lock_resource *res;
3517209300aSSunil Mushran int out = 0;
3527209300aSSunil Mushran unsigned long total = 0;
3537209300aSSunil Mushran
354d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
3557209300aSSunil Mushran "Dumping Purgelist for Domain: %s\n", dlm->name);
3567209300aSSunil Mushran
3577209300aSSunil Mushran spin_lock(&dlm->spinlock);
3587209300aSSunil Mushran list_for_each_entry(res, &dlm->purge_list, purge) {
3597209300aSSunil Mushran ++total;
36002bd9c39SSunil Mushran if (len - out < 100)
3617209300aSSunil Mushran continue;
3627209300aSSunil Mushran spin_lock(&res->spinlock);
3637209300aSSunil Mushran out += stringify_lockname(res->lockname.name,
3647209300aSSunil Mushran res->lockname.len,
36502bd9c39SSunil Mushran buf + out, len - out);
366d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\t%ld\n",
3677209300aSSunil Mushran (jiffies - res->last_used)/HZ);
3687209300aSSunil Mushran spin_unlock(&res->spinlock);
3697209300aSSunil Mushran }
3707209300aSSunil Mushran spin_unlock(&dlm->spinlock);
3717209300aSSunil Mushran
372d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Total on list: %lu\n", total);
3737209300aSSunil Mushran
3747209300aSSunil Mushran return out;
3757209300aSSunil Mushran }
3767209300aSSunil Mushran
debug_purgelist_open(struct inode * inode,struct file * file)3777209300aSSunil Mushran static int debug_purgelist_open(struct inode *inode, struct file *file)
3787209300aSSunil Mushran {
3797209300aSSunil Mushran struct dlm_ctxt *dlm = inode->i_private;
38002bd9c39SSunil Mushran char *buf = NULL;
3817209300aSSunil Mushran
38202bd9c39SSunil Mushran buf = (char *) get_zeroed_page(GFP_NOFS);
38302bd9c39SSunil Mushran if (!buf)
3847209300aSSunil Mushran goto bail;
3857209300aSSunil Mushran
38602bd9c39SSunil Mushran i_size_write(inode, debug_purgelist_print(dlm, buf, PAGE_SIZE - 1));
3877209300aSSunil Mushran
38802bd9c39SSunil Mushran file->private_data = buf;
3897209300aSSunil Mushran
3907209300aSSunil Mushran return 0;
3917209300aSSunil Mushran bail:
3927209300aSSunil Mushran return -ENOMEM;
3937209300aSSunil Mushran }
3947209300aSSunil Mushran
395828c0950SAlexey Dobriyan static const struct file_operations debug_purgelist_fops = {
3967209300aSSunil Mushran .open = debug_purgelist_open,
39702bd9c39SSunil Mushran .release = debug_release,
39802bd9c39SSunil Mushran .read = debug_read,
39902bd9c39SSunil Mushran .llseek = generic_file_llseek,
4007209300aSSunil Mushran };
4017209300aSSunil Mushran /* end - purge list funcs */
4027209300aSSunil Mushran
403d0129aceSSunil Mushran /* begin - debug mle funcs */
debug_mle_print(struct dlm_ctxt * dlm,char * buf,int len)40402bd9c39SSunil Mushran static int debug_mle_print(struct dlm_ctxt *dlm, char *buf, int len)
405d0129aceSSunil Mushran {
406d0129aceSSunil Mushran struct dlm_master_list_entry *mle;
4072ed6c750SSunil Mushran struct hlist_head *bucket;
4082ed6c750SSunil Mushran int i, out = 0;
40993f3b86fSJoel Becker unsigned long total = 0, longest = 0, bucket_count = 0;
410d0129aceSSunil Mushran
411d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
412d0129aceSSunil Mushran "Dumping MLEs for Domain: %s\n", dlm->name);
413d0129aceSSunil Mushran
414d0129aceSSunil Mushran spin_lock(&dlm->master_lock);
4152ed6c750SSunil Mushran for (i = 0; i < DLM_HASH_BUCKETS; i++) {
4162ed6c750SSunil Mushran bucket = dlm_master_hash(dlm, i);
417df53cd3bSDong Fang hlist_for_each_entry(mle, bucket, master_hash_node) {
418d0129aceSSunil Mushran ++total;
41993f3b86fSJoel Becker ++bucket_count;
42002bd9c39SSunil Mushran if (len - out < 200)
421d0129aceSSunil Mushran continue;
42202bd9c39SSunil Mushran out += dump_mle(mle, buf + out, len - out);
423d0129aceSSunil Mushran }
42493f3b86fSJoel Becker longest = max(longest, bucket_count);
42593f3b86fSJoel Becker bucket_count = 0;
4262ed6c750SSunil Mushran }
427d0129aceSSunil Mushran spin_unlock(&dlm->master_lock);
428d0129aceSSunil Mushran
429d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
43079c83ea1Salex chen "Total: %lu, Longest: %lu\n", total, longest);
431d0129aceSSunil Mushran return out;
432d0129aceSSunil Mushran }
433d0129aceSSunil Mushran
debug_mle_open(struct inode * inode,struct file * file)434d0129aceSSunil Mushran static int debug_mle_open(struct inode *inode, struct file *file)
435d0129aceSSunil Mushran {
436d0129aceSSunil Mushran struct dlm_ctxt *dlm = inode->i_private;
43702bd9c39SSunil Mushran char *buf = NULL;
438d0129aceSSunil Mushran
43902bd9c39SSunil Mushran buf = (char *) get_zeroed_page(GFP_NOFS);
44002bd9c39SSunil Mushran if (!buf)
441d0129aceSSunil Mushran goto bail;
442d0129aceSSunil Mushran
44302bd9c39SSunil Mushran i_size_write(inode, debug_mle_print(dlm, buf, PAGE_SIZE - 1));
444d0129aceSSunil Mushran
44502bd9c39SSunil Mushran file->private_data = buf;
446d0129aceSSunil Mushran
447d0129aceSSunil Mushran return 0;
448d0129aceSSunil Mushran bail:
449d0129aceSSunil Mushran return -ENOMEM;
450d0129aceSSunil Mushran }
451d0129aceSSunil Mushran
452828c0950SAlexey Dobriyan static const struct file_operations debug_mle_fops = {
453d0129aceSSunil Mushran .open = debug_mle_open,
45402bd9c39SSunil Mushran .release = debug_release,
45502bd9c39SSunil Mushran .read = debug_read,
45602bd9c39SSunil Mushran .llseek = generic_file_llseek,
457d0129aceSSunil Mushran };
458d0129aceSSunil Mushran
459d0129aceSSunil Mushran /* end - debug mle funcs */
460d0129aceSSunil Mushran
4614e3d24edSSunil Mushran /* begin - debug lockres funcs */
dump_lock(struct dlm_lock * lock,int list_type,char * buf,int len)4624e3d24edSSunil Mushran static int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len)
4634e3d24edSSunil Mushran {
4644e3d24edSSunil Mushran int out;
4654e3d24edSSunil Mushran
4664e3d24edSSunil Mushran #define DEBUG_LOCK_VERSION 1
4674e3d24edSSunil Mushran spin_lock(&lock->spinlock);
468d293d3afSTakashi Iwai out = scnprintf(buf, len, "LOCK:%d,%d,%d,%d,%d,%d:%lld,%d,%d,%d,%d,%d,"
4694e3d24edSSunil Mushran "%d,%d,%d,%d\n",
4704e3d24edSSunil Mushran DEBUG_LOCK_VERSION,
4714e3d24edSSunil Mushran list_type, lock->ml.type, lock->ml.convert_type,
4724e3d24edSSunil Mushran lock->ml.node,
4734e3d24edSSunil Mushran dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
4744e3d24edSSunil Mushran dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
4754e3d24edSSunil Mushran !list_empty(&lock->ast_list),
4764e3d24edSSunil Mushran !list_empty(&lock->bast_list),
4774e3d24edSSunil Mushran lock->ast_pending, lock->bast_pending,
4784e3d24edSSunil Mushran lock->convert_pending, lock->lock_pending,
4794e3d24edSSunil Mushran lock->cancel_pending, lock->unlock_pending,
4802c935bc5SPeter Zijlstra kref_read(&lock->lock_refs));
4814e3d24edSSunil Mushran spin_unlock(&lock->spinlock);
4824e3d24edSSunil Mushran
4834e3d24edSSunil Mushran return out;
4844e3d24edSSunil Mushran }
4854e3d24edSSunil Mushran
dump_lockres(struct dlm_lock_resource * res,char * buf,int len)4864e3d24edSSunil Mushran static int dump_lockres(struct dlm_lock_resource *res, char *buf, int len)
4874e3d24edSSunil Mushran {
4884e3d24edSSunil Mushran struct dlm_lock *lock;
4894e3d24edSSunil Mushran int i;
4904e3d24edSSunil Mushran int out = 0;
4914e3d24edSSunil Mushran
492d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "NAME:");
4934e3d24edSSunil Mushran out += stringify_lockname(res->lockname.name, res->lockname.len,
4944e3d24edSSunil Mushran buf + out, len - out);
495d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
4964e3d24edSSunil Mushran
4974e3d24edSSunil Mushran #define DEBUG_LRES_VERSION 1
498d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
4994e3d24edSSunil Mushran "LRES:%d,%d,%d,%ld,%d,%d,%d,%d,%d,%d,%d\n",
5004e3d24edSSunil Mushran DEBUG_LRES_VERSION,
5014e3d24edSSunil Mushran res->owner, res->state, res->last_used,
5024e3d24edSSunil Mushran !list_empty(&res->purge),
5034e3d24edSSunil Mushran !list_empty(&res->dirty),
5044e3d24edSSunil Mushran !list_empty(&res->recovering),
5054e3d24edSSunil Mushran res->inflight_locks, res->migration_pending,
5064e3d24edSSunil Mushran atomic_read(&res->asts_reserved),
5072c935bc5SPeter Zijlstra kref_read(&res->refs));
5084e3d24edSSunil Mushran
5094e3d24edSSunil Mushran /* refmap */
510d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "RMAP:");
5114e3d24edSSunil Mushran out += stringify_nodemap(res->refmap, O2NM_MAX_NODES,
5124e3d24edSSunil Mushran buf + out, len - out);
513d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
5144e3d24edSSunil Mushran
5154e3d24edSSunil Mushran /* lvb */
516d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "LVBX:");
5174e3d24edSSunil Mushran for (i = 0; i < DLM_LVB_LEN; i++)
518d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
5194e3d24edSSunil Mushran "%02x", (unsigned char)res->lvb[i]);
520d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
5214e3d24edSSunil Mushran
5224e3d24edSSunil Mushran /* granted */
5234e3d24edSSunil Mushran list_for_each_entry(lock, &res->granted, list)
5244e3d24edSSunil Mushran out += dump_lock(lock, 0, buf + out, len - out);
5254e3d24edSSunil Mushran
5264e3d24edSSunil Mushran /* converting */
5274e3d24edSSunil Mushran list_for_each_entry(lock, &res->converting, list)
5284e3d24edSSunil Mushran out += dump_lock(lock, 1, buf + out, len - out);
5294e3d24edSSunil Mushran
5304e3d24edSSunil Mushran /* blocked */
5314e3d24edSSunil Mushran list_for_each_entry(lock, &res->blocked, list)
5324e3d24edSSunil Mushran out += dump_lock(lock, 2, buf + out, len - out);
5334e3d24edSSunil Mushran
534d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
5354e3d24edSSunil Mushran
5364e3d24edSSunil Mushran return out;
5374e3d24edSSunil Mushran }
5384e3d24edSSunil Mushran
lockres_seq_start(struct seq_file * m,loff_t * pos)5394e3d24edSSunil Mushran static void *lockres_seq_start(struct seq_file *m, loff_t *pos)
5404e3d24edSSunil Mushran {
5414e3d24edSSunil Mushran struct debug_lockres *dl = m->private;
5424e3d24edSSunil Mushran struct dlm_ctxt *dlm = dl->dl_ctxt;
543b0d4f817SSunil Mushran struct dlm_lock_resource *oldres = dl->dl_res;
544*b02da32bSJakob Koschel struct dlm_lock_resource *res = NULL, *iter;
545b0d4f817SSunil Mushran struct list_head *track_list;
5464e3d24edSSunil Mushran
547b0d4f817SSunil Mushran spin_lock(&dlm->track_lock);
548b0d4f817SSunil Mushran if (oldres)
549b0d4f817SSunil Mushran track_list = &oldres->tracking;
550228ac635STristan Ye else {
551b0d4f817SSunil Mushran track_list = &dlm->tracking_list;
552228ac635STristan Ye if (list_empty(track_list)) {
553228ac635STristan Ye dl = NULL;
554228ac635STristan Ye spin_unlock(&dlm->track_lock);
555228ac635STristan Ye goto bail;
556228ac635STristan Ye }
557228ac635STristan Ye }
5584e3d24edSSunil Mushran
559*b02da32bSJakob Koschel list_for_each_entry(iter, track_list, tracking) {
560*b02da32bSJakob Koschel if (&iter->tracking != &dlm->tracking_list) {
561*b02da32bSJakob Koschel dlm_lockres_get(iter);
562*b02da32bSJakob Koschel res = iter;
563*b02da32bSJakob Koschel }
5644e3d24edSSunil Mushran break;
5654e3d24edSSunil Mushran }
566b0d4f817SSunil Mushran spin_unlock(&dlm->track_lock);
567b0d4f817SSunil Mushran
568b0d4f817SSunil Mushran if (oldres)
569b0d4f817SSunil Mushran dlm_lockres_put(oldres);
570b0d4f817SSunil Mushran
5714e3d24edSSunil Mushran dl->dl_res = res;
572b0d4f817SSunil Mushran
573b0d4f817SSunil Mushran if (res) {
574b0d4f817SSunil Mushran spin_lock(&res->spinlock);
575b0d4f817SSunil Mushran dump_lockres(res, dl->dl_buf, dl->dl_len - 1);
576b0d4f817SSunil Mushran spin_unlock(&res->spinlock);
5774e3d24edSSunil Mushran } else
5784e3d24edSSunil Mushran dl = NULL;
5794e3d24edSSunil Mushran
580228ac635STristan Ye bail:
581b0d4f817SSunil Mushran /* passed to seq_show */
5824e3d24edSSunil Mushran return dl;
5834e3d24edSSunil Mushran }
5844e3d24edSSunil Mushran
lockres_seq_stop(struct seq_file * m,void * v)5854e3d24edSSunil Mushran static void lockres_seq_stop(struct seq_file *m, void *v)
5864e3d24edSSunil Mushran {
5874e3d24edSSunil Mushran }
5884e3d24edSSunil Mushran
lockres_seq_next(struct seq_file * m,void * v,loff_t * pos)5894e3d24edSSunil Mushran static void *lockres_seq_next(struct seq_file *m, void *v, loff_t *pos)
5904e3d24edSSunil Mushran {
5914e3d24edSSunil Mushran return NULL;
5924e3d24edSSunil Mushran }
5934e3d24edSSunil Mushran
lockres_seq_show(struct seq_file * s,void * v)5944e3d24edSSunil Mushran static int lockres_seq_show(struct seq_file *s, void *v)
5954e3d24edSSunil Mushran {
5964e3d24edSSunil Mushran struct debug_lockres *dl = (struct debug_lockres *)v;
5974e3d24edSSunil Mushran
5984e3d24edSSunil Mushran seq_printf(s, "%s", dl->dl_buf);
5994e3d24edSSunil Mushran
6004e3d24edSSunil Mushran return 0;
6014e3d24edSSunil Mushran }
6024e3d24edSSunil Mushran
60388e9d34cSJames Morris static const struct seq_operations debug_lockres_ops = {
6044e3d24edSSunil Mushran .start = lockres_seq_start,
6054e3d24edSSunil Mushran .stop = lockres_seq_stop,
6064e3d24edSSunil Mushran .next = lockres_seq_next,
6074e3d24edSSunil Mushran .show = lockres_seq_show,
6084e3d24edSSunil Mushran };
6094e3d24edSSunil Mushran
debug_lockres_open(struct inode * inode,struct file * file)6104e3d24edSSunil Mushran static int debug_lockres_open(struct inode *inode, struct file *file)
6114e3d24edSSunil Mushran {
6124e3d24edSSunil Mushran struct dlm_ctxt *dlm = inode->i_private;
6138f9ac032SRob Jones struct debug_lockres *dl;
6148f9ac032SRob Jones void *buf;
6154e3d24edSSunil Mushran
6168f9ac032SRob Jones buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
6178f9ac032SRob Jones if (!buf)
6184e3d24edSSunil Mushran goto bail;
6198f9ac032SRob Jones
6208f9ac032SRob Jones dl = __seq_open_private(file, &debug_lockres_ops, sizeof(*dl));
6218f9ac032SRob Jones if (!dl)
6228f9ac032SRob Jones goto bailfree;
6234e3d24edSSunil Mushran
6244e3d24edSSunil Mushran dl->dl_len = PAGE_SIZE;
6258f9ac032SRob Jones dl->dl_buf = buf;
6264e3d24edSSunil Mushran
6274e3d24edSSunil Mushran dlm_grab(dlm);
6284e3d24edSSunil Mushran dl->dl_ctxt = dlm;
6294e3d24edSSunil Mushran
6304e3d24edSSunil Mushran return 0;
6318f9ac032SRob Jones
6328f9ac032SRob Jones bailfree:
6338f9ac032SRob Jones kfree(buf);
6344e3d24edSSunil Mushran bail:
6358f9ac032SRob Jones mlog_errno(-ENOMEM);
6368f9ac032SRob Jones return -ENOMEM;
6374e3d24edSSunil Mushran }
6384e3d24edSSunil Mushran
debug_lockres_release(struct inode * inode,struct file * file)6394e3d24edSSunil Mushran static int debug_lockres_release(struct inode *inode, struct file *file)
6404e3d24edSSunil Mushran {
64133fa1d90SJoe Perches struct seq_file *seq = file->private_data;
6424e3d24edSSunil Mushran struct debug_lockres *dl = (struct debug_lockres *)seq->private;
6434e3d24edSSunil Mushran
6444e3d24edSSunil Mushran if (dl->dl_res)
6454e3d24edSSunil Mushran dlm_lockres_put(dl->dl_res);
6464e3d24edSSunil Mushran dlm_put(dl->dl_ctxt);
6474e3d24edSSunil Mushran kfree(dl->dl_buf);
6484e3d24edSSunil Mushran return seq_release_private(inode, file);
6494e3d24edSSunil Mushran }
6504e3d24edSSunil Mushran
651828c0950SAlexey Dobriyan static const struct file_operations debug_lockres_fops = {
6524e3d24edSSunil Mushran .open = debug_lockres_open,
6534e3d24edSSunil Mushran .release = debug_lockres_release,
6544e3d24edSSunil Mushran .read = seq_read,
6554e3d24edSSunil Mushran .llseek = seq_lseek,
6564e3d24edSSunil Mushran };
6574e3d24edSSunil Mushran /* end - debug lockres funcs */
6584e3d24edSSunil Mushran
659007dce53SSunil Mushran /* begin - debug state funcs */
debug_state_print(struct dlm_ctxt * dlm,char * buf,int len)66002bd9c39SSunil Mushran static int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len)
661007dce53SSunil Mushran {
662007dce53SSunil Mushran int out = 0;
663007dce53SSunil Mushran struct dlm_reco_node_data *node;
664007dce53SSunil Mushran char *state;
665e64ff146SSunil Mushran int cur_mles = 0, tot_mles = 0;
666e64ff146SSunil Mushran int i;
667007dce53SSunil Mushran
668007dce53SSunil Mushran spin_lock(&dlm->spinlock);
669007dce53SSunil Mushran
670007dce53SSunil Mushran switch (dlm->dlm_state) {
671007dce53SSunil Mushran case DLM_CTXT_NEW:
672007dce53SSunil Mushran state = "NEW"; break;
673007dce53SSunil Mushran case DLM_CTXT_JOINED:
674007dce53SSunil Mushran state = "JOINED"; break;
675007dce53SSunil Mushran case DLM_CTXT_IN_SHUTDOWN:
676007dce53SSunil Mushran state = "SHUTDOWN"; break;
677007dce53SSunil Mushran case DLM_CTXT_LEAVING:
678007dce53SSunil Mushran state = "LEAVING"; break;
679007dce53SSunil Mushran default:
680007dce53SSunil Mushran state = "UNKNOWN"; break;
681007dce53SSunil Mushran }
682007dce53SSunil Mushran
683007dce53SSunil Mushran /* Domain: xxxxxxxxxx Key: 0xdfbac769 */
684d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
685b1365d0bSSunil Mushran "Domain: %s Key: 0x%08x Protocol: %d.%d\n",
686b1365d0bSSunil Mushran dlm->name, dlm->key, dlm->dlm_locking_proto.pv_major,
687b1365d0bSSunil Mushran dlm->dlm_locking_proto.pv_minor);
688007dce53SSunil Mushran
689007dce53SSunil Mushran /* Thread Pid: xxx Node: xxx State: xxxxx */
690d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
691007dce53SSunil Mushran "Thread Pid: %d Node: %d State: %s\n",
69237096a79SSunil Mushran task_pid_nr(dlm->dlm_thread_task), dlm->node_num, state);
693007dce53SSunil Mushran
694007dce53SSunil Mushran /* Number of Joins: xxx Joining Node: xxx */
695d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
696007dce53SSunil Mushran "Number of Joins: %d Joining Node: %d\n",
697007dce53SSunil Mushran dlm->num_joins, dlm->joining_node);
698007dce53SSunil Mushran
699007dce53SSunil Mushran /* Domain Map: xx xx xx */
700d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Domain Map: ");
701007dce53SSunil Mushran out += stringify_nodemap(dlm->domain_map, O2NM_MAX_NODES,
70202bd9c39SSunil Mushran buf + out, len - out);
703d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
704007dce53SSunil Mushran
705bddefdeeSSunil Mushran /* Exit Domain Map: xx xx xx */
706d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Exit Domain Map: ");
707bddefdeeSSunil Mushran out += stringify_nodemap(dlm->exit_domain_map, O2NM_MAX_NODES,
708bddefdeeSSunil Mushran buf + out, len - out);
709d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
710bddefdeeSSunil Mushran
711007dce53SSunil Mushran /* Live Map: xx xx xx */
712d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Live Map: ");
713007dce53SSunil Mushran out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES,
71402bd9c39SSunil Mushran buf + out, len - out);
715d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
716007dce53SSunil Mushran
717e64ff146SSunil Mushran /* Lock Resources: xxx (xxx) */
718d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
719e64ff146SSunil Mushran "Lock Resources: %d (%d)\n",
720e64ff146SSunil Mushran atomic_read(&dlm->res_cur_count),
721e64ff146SSunil Mushran atomic_read(&dlm->res_tot_count));
722e64ff146SSunil Mushran
723e64ff146SSunil Mushran for (i = 0; i < DLM_MLE_NUM_TYPES; ++i)
724e64ff146SSunil Mushran tot_mles += atomic_read(&dlm->mle_tot_count[i]);
725e64ff146SSunil Mushran
726e64ff146SSunil Mushran for (i = 0; i < DLM_MLE_NUM_TYPES; ++i)
727e64ff146SSunil Mushran cur_mles += atomic_read(&dlm->mle_cur_count[i]);
728e64ff146SSunil Mushran
729e64ff146SSunil Mushran /* MLEs: xxx (xxx) */
730d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
731e64ff146SSunil Mushran "MLEs: %d (%d)\n", cur_mles, tot_mles);
732e64ff146SSunil Mushran
733e64ff146SSunil Mushran /* Blocking: xxx (xxx) */
734d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
735e64ff146SSunil Mushran " Blocking: %d (%d)\n",
736e64ff146SSunil Mushran atomic_read(&dlm->mle_cur_count[DLM_MLE_BLOCK]),
737e64ff146SSunil Mushran atomic_read(&dlm->mle_tot_count[DLM_MLE_BLOCK]));
738e64ff146SSunil Mushran
739e64ff146SSunil Mushran /* Mastery: xxx (xxx) */
740d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
741e64ff146SSunil Mushran " Mastery: %d (%d)\n",
742e64ff146SSunil Mushran atomic_read(&dlm->mle_cur_count[DLM_MLE_MASTER]),
743e64ff146SSunil Mushran atomic_read(&dlm->mle_tot_count[DLM_MLE_MASTER]));
744e64ff146SSunil Mushran
745e64ff146SSunil Mushran /* Migration: xxx (xxx) */
746d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
747e64ff146SSunil Mushran " Migration: %d (%d)\n",
748e64ff146SSunil Mushran atomic_read(&dlm->mle_cur_count[DLM_MLE_MIGRATION]),
749e64ff146SSunil Mushran atomic_read(&dlm->mle_tot_count[DLM_MLE_MIGRATION]));
750e64ff146SSunil Mushran
751007dce53SSunil Mushran /* Lists: Dirty=Empty Purge=InUse PendingASTs=Empty ... */
752d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
753007dce53SSunil Mushran "Lists: Dirty=%s Purge=%s PendingASTs=%s "
7542ed6c750SSunil Mushran "PendingBASTs=%s\n",
755007dce53SSunil Mushran (list_empty(&dlm->dirty_list) ? "Empty" : "InUse"),
756007dce53SSunil Mushran (list_empty(&dlm->purge_list) ? "Empty" : "InUse"),
757007dce53SSunil Mushran (list_empty(&dlm->pending_asts) ? "Empty" : "InUse"),
7582ed6c750SSunil Mushran (list_empty(&dlm->pending_basts) ? "Empty" : "InUse"));
759007dce53SSunil Mushran
760007dce53SSunil Mushran /* Purge Count: xxx Refs: xxx */
761d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
762007dce53SSunil Mushran "Purge Count: %d Refs: %d\n", dlm->purge_count,
7632c935bc5SPeter Zijlstra kref_read(&dlm->dlm_refs));
764007dce53SSunil Mushran
765007dce53SSunil Mushran /* Dead Node: xxx */
766d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
767007dce53SSunil Mushran "Dead Node: %d\n", dlm->reco.dead_node);
768007dce53SSunil Mushran
769007dce53SSunil Mushran /* What about DLM_RECO_STATE_FINALIZE? */
770007dce53SSunil Mushran if (dlm->reco.state == DLM_RECO_STATE_ACTIVE)
771007dce53SSunil Mushran state = "ACTIVE";
772007dce53SSunil Mushran else
773007dce53SSunil Mushran state = "INACTIVE";
774007dce53SSunil Mushran
775007dce53SSunil Mushran /* Recovery Pid: xxxx Master: xxx State: xxxx */
776d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out,
777007dce53SSunil Mushran "Recovery Pid: %d Master: %d State: %s\n",
77837096a79SSunil Mushran task_pid_nr(dlm->dlm_reco_thread_task),
779007dce53SSunil Mushran dlm->reco.new_master, state);
780007dce53SSunil Mushran
781007dce53SSunil Mushran /* Recovery Map: xx xx */
782d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Recovery Map: ");
783007dce53SSunil Mushran out += stringify_nodemap(dlm->recovery_map, O2NM_MAX_NODES,
78402bd9c39SSunil Mushran buf + out, len - out);
785d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\n");
786007dce53SSunil Mushran
787007dce53SSunil Mushran /* Recovery Node State: */
788d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "Recovery Node State:\n");
789007dce53SSunil Mushran list_for_each_entry(node, &dlm->reco.node_data, list) {
790007dce53SSunil Mushran switch (node->state) {
791007dce53SSunil Mushran case DLM_RECO_NODE_DATA_INIT:
792007dce53SSunil Mushran state = "INIT";
793007dce53SSunil Mushran break;
794007dce53SSunil Mushran case DLM_RECO_NODE_DATA_REQUESTING:
795007dce53SSunil Mushran state = "REQUESTING";
796007dce53SSunil Mushran break;
797007dce53SSunil Mushran case DLM_RECO_NODE_DATA_DEAD:
798007dce53SSunil Mushran state = "DEAD";
799007dce53SSunil Mushran break;
800007dce53SSunil Mushran case DLM_RECO_NODE_DATA_RECEIVING:
801007dce53SSunil Mushran state = "RECEIVING";
802007dce53SSunil Mushran break;
803007dce53SSunil Mushran case DLM_RECO_NODE_DATA_REQUESTED:
804007dce53SSunil Mushran state = "REQUESTED";
805007dce53SSunil Mushran break;
806007dce53SSunil Mushran case DLM_RECO_NODE_DATA_DONE:
807007dce53SSunil Mushran state = "DONE";
808007dce53SSunil Mushran break;
809007dce53SSunil Mushran case DLM_RECO_NODE_DATA_FINALIZE_SENT:
810007dce53SSunil Mushran state = "FINALIZE-SENT";
811007dce53SSunil Mushran break;
812007dce53SSunil Mushran default:
813007dce53SSunil Mushran state = "BAD";
814007dce53SSunil Mushran break;
815007dce53SSunil Mushran }
816d293d3afSTakashi Iwai out += scnprintf(buf + out, len - out, "\t%u - %s\n",
817007dce53SSunil Mushran node->node_num, state);
818007dce53SSunil Mushran }
819007dce53SSunil Mushran
820007dce53SSunil Mushran spin_unlock(&dlm->spinlock);
821007dce53SSunil Mushran
822007dce53SSunil Mushran return out;
823007dce53SSunil Mushran }
824007dce53SSunil Mushran
debug_state_open(struct inode * inode,struct file * file)825007dce53SSunil Mushran static int debug_state_open(struct inode *inode, struct file *file)
826007dce53SSunil Mushran {
827007dce53SSunil Mushran struct dlm_ctxt *dlm = inode->i_private;
82802bd9c39SSunil Mushran char *buf = NULL;
829007dce53SSunil Mushran
83002bd9c39SSunil Mushran buf = (char *) get_zeroed_page(GFP_NOFS);
83102bd9c39SSunil Mushran if (!buf)
832007dce53SSunil Mushran goto bail;
833007dce53SSunil Mushran
83402bd9c39SSunil Mushran i_size_write(inode, debug_state_print(dlm, buf, PAGE_SIZE - 1));
835007dce53SSunil Mushran
83602bd9c39SSunil Mushran file->private_data = buf;
837007dce53SSunil Mushran
838007dce53SSunil Mushran return 0;
839007dce53SSunil Mushran bail:
840007dce53SSunil Mushran return -ENOMEM;
841007dce53SSunil Mushran }
842007dce53SSunil Mushran
843828c0950SAlexey Dobriyan static const struct file_operations debug_state_fops = {
844007dce53SSunil Mushran .open = debug_state_open,
84502bd9c39SSunil Mushran .release = debug_release,
84602bd9c39SSunil Mushran .read = debug_read,
84702bd9c39SSunil Mushran .llseek = generic_file_llseek,
848007dce53SSunil Mushran };
849007dce53SSunil Mushran /* end - debug state funcs */
850007dce53SSunil Mushran
851007dce53SSunil Mushran /* files in subroot */
dlm_debug_init(struct dlm_ctxt * dlm)852e581595eSGreg Kroah-Hartman void dlm_debug_init(struct dlm_ctxt *dlm)
853007dce53SSunil Mushran {
854007dce53SSunil Mushran /* for dumping dlm_ctxt */
8555e7a3ed9SGreg Kroah-Hartman debugfs_create_file(DLM_DEBUGFS_DLM_STATE, S_IFREG|S_IRUSR,
8565e7a3ed9SGreg Kroah-Hartman dlm->dlm_debugfs_subroot, dlm, &debug_state_fops);
857007dce53SSunil Mushran
8584e3d24edSSunil Mushran /* for dumping lockres */
8595e7a3ed9SGreg Kroah-Hartman debugfs_create_file(DLM_DEBUGFS_LOCKING_STATE, S_IFREG|S_IRUSR,
8605e7a3ed9SGreg Kroah-Hartman dlm->dlm_debugfs_subroot, dlm, &debug_lockres_fops);
8614e3d24edSSunil Mushran
862d0129aceSSunil Mushran /* for dumping mles */
8635e7a3ed9SGreg Kroah-Hartman debugfs_create_file(DLM_DEBUGFS_MLE_STATE, S_IFREG|S_IRUSR,
8645e7a3ed9SGreg Kroah-Hartman dlm->dlm_debugfs_subroot, dlm, &debug_mle_fops);
865d0129aceSSunil Mushran
8667209300aSSunil Mushran /* for dumping lockres on the purge list */
8675e7a3ed9SGreg Kroah-Hartman debugfs_create_file(DLM_DEBUGFS_PURGE_LIST, S_IFREG|S_IRUSR,
8685e7a3ed9SGreg Kroah-Hartman dlm->dlm_debugfs_subroot, dlm,
8695e7a3ed9SGreg Kroah-Hartman &debug_purgelist_fops);
870007dce53SSunil Mushran }
8716325b4a2SSunil Mushran
8726325b4a2SSunil Mushran /* subroot - domain dir */
dlm_create_debugfs_subroot(struct dlm_ctxt * dlm)8735e7a3ed9SGreg Kroah-Hartman void dlm_create_debugfs_subroot(struct dlm_ctxt *dlm)
8746325b4a2SSunil Mushran {
875e581595eSGreg Kroah-Hartman dlm->dlm_debugfs_subroot = debugfs_create_dir(dlm->name,
876e581595eSGreg Kroah-Hartman dlm_debugfs_root);
8776325b4a2SSunil Mushran }
8786325b4a2SSunil Mushran
dlm_destroy_debugfs_subroot(struct dlm_ctxt * dlm)8796325b4a2SSunil Mushran void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm)
8806325b4a2SSunil Mushran {
8815e7a3ed9SGreg Kroah-Hartman debugfs_remove_recursive(dlm->dlm_debugfs_subroot);
8826325b4a2SSunil Mushran }
8836325b4a2SSunil Mushran
8846325b4a2SSunil Mushran /* debugfs root */
dlm_create_debugfs_root(void)885e581595eSGreg Kroah-Hartman void dlm_create_debugfs_root(void)
8866325b4a2SSunil Mushran {
8876325b4a2SSunil Mushran dlm_debugfs_root = debugfs_create_dir(DLM_DEBUGFS_DIR, NULL);
8886325b4a2SSunil Mushran }
8896325b4a2SSunil Mushran
dlm_destroy_debugfs_root(void)8906325b4a2SSunil Mushran void dlm_destroy_debugfs_root(void)
8916325b4a2SSunil Mushran {
8926325b4a2SSunil Mushran debugfs_remove(dlm_debugfs_root);
8936325b4a2SSunil Mushran }
8946325b4a2SSunil Mushran #endif /* CONFIG_DEBUG_FS */
895