162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * dlmdebug.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * debug functionality for the dlm 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2004, 2008 Oracle. All rights reserved. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/types.h> 1162306a36Sopenharmony_ci#include <linux/slab.h> 1262306a36Sopenharmony_ci#include <linux/highmem.h> 1362306a36Sopenharmony_ci#include <linux/sysctl.h> 1462306a36Sopenharmony_ci#include <linux/spinlock.h> 1562306a36Sopenharmony_ci#include <linux/debugfs.h> 1662306a36Sopenharmony_ci#include <linux/export.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "../cluster/heartbeat.h" 1962306a36Sopenharmony_ci#include "../cluster/nodemanager.h" 2062306a36Sopenharmony_ci#include "../cluster/tcp.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include "dlmapi.h" 2362306a36Sopenharmony_ci#include "dlmcommon.h" 2462306a36Sopenharmony_ci#include "dlmdomain.h" 2562306a36Sopenharmony_ci#include "dlmdebug.h" 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define MLOG_MASK_PREFIX ML_DLM 2862306a36Sopenharmony_ci#include "../cluster/masklog.h" 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic int stringify_lockname(const char *lockname, int locklen, char *buf, 3162306a36Sopenharmony_ci int len); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_civoid dlm_print_one_lock_resource(struct dlm_lock_resource *res) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci spin_lock(&res->spinlock); 3662306a36Sopenharmony_ci __dlm_print_one_lock_resource(res); 3762306a36Sopenharmony_ci spin_unlock(&res->spinlock); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic void dlm_print_lockres_refmap(struct dlm_lock_resource *res) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci int bit; 4362306a36Sopenharmony_ci assert_spin_locked(&res->spinlock); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci printk(" refmap nodes: [ "); 4662306a36Sopenharmony_ci bit = 0; 4762306a36Sopenharmony_ci while (1) { 4862306a36Sopenharmony_ci bit = find_next_bit(res->refmap, O2NM_MAX_NODES, bit); 4962306a36Sopenharmony_ci if (bit >= O2NM_MAX_NODES) 5062306a36Sopenharmony_ci break; 5162306a36Sopenharmony_ci printk("%u ", bit); 5262306a36Sopenharmony_ci bit++; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci printk("], inflight=%u\n", res->inflight_locks); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic void __dlm_print_lock(struct dlm_lock *lock) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci spin_lock(&lock->spinlock); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci printk(" type=%d, conv=%d, node=%u, cookie=%u:%llu, " 6262306a36Sopenharmony_ci "ref=%u, ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c), " 6362306a36Sopenharmony_ci "pending=(conv=%c,lock=%c,cancel=%c,unlock=%c)\n", 6462306a36Sopenharmony_ci lock->ml.type, lock->ml.convert_type, lock->ml.node, 6562306a36Sopenharmony_ci dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), 6662306a36Sopenharmony_ci dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), 6762306a36Sopenharmony_ci kref_read(&lock->lock_refs), 6862306a36Sopenharmony_ci (list_empty(&lock->ast_list) ? 'y' : 'n'), 6962306a36Sopenharmony_ci (lock->ast_pending ? 'y' : 'n'), 7062306a36Sopenharmony_ci (list_empty(&lock->bast_list) ? 'y' : 'n'), 7162306a36Sopenharmony_ci (lock->bast_pending ? 'y' : 'n'), 7262306a36Sopenharmony_ci (lock->convert_pending ? 'y' : 'n'), 7362306a36Sopenharmony_ci (lock->lock_pending ? 'y' : 'n'), 7462306a36Sopenharmony_ci (lock->cancel_pending ? 'y' : 'n'), 7562306a36Sopenharmony_ci (lock->unlock_pending ? 'y' : 'n')); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci spin_unlock(&lock->spinlock); 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_civoid __dlm_print_one_lock_resource(struct dlm_lock_resource *res) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci struct dlm_lock *lock; 8362306a36Sopenharmony_ci char buf[DLM_LOCKID_NAME_MAX]; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci assert_spin_locked(&res->spinlock); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci stringify_lockname(res->lockname.name, res->lockname.len, 8862306a36Sopenharmony_ci buf, sizeof(buf)); 8962306a36Sopenharmony_ci printk("lockres: %s, owner=%u, state=%u\n", 9062306a36Sopenharmony_ci buf, res->owner, res->state); 9162306a36Sopenharmony_ci printk(" last used: %lu, refcnt: %u, on purge list: %s\n", 9262306a36Sopenharmony_ci res->last_used, kref_read(&res->refs), 9362306a36Sopenharmony_ci list_empty(&res->purge) ? "no" : "yes"); 9462306a36Sopenharmony_ci printk(" on dirty list: %s, on reco list: %s, " 9562306a36Sopenharmony_ci "migrating pending: %s\n", 9662306a36Sopenharmony_ci list_empty(&res->dirty) ? "no" : "yes", 9762306a36Sopenharmony_ci list_empty(&res->recovering) ? "no" : "yes", 9862306a36Sopenharmony_ci res->migration_pending ? "yes" : "no"); 9962306a36Sopenharmony_ci printk(" inflight locks: %d, asts reserved: %d\n", 10062306a36Sopenharmony_ci res->inflight_locks, atomic_read(&res->asts_reserved)); 10162306a36Sopenharmony_ci dlm_print_lockres_refmap(res); 10262306a36Sopenharmony_ci printk(" granted queue:\n"); 10362306a36Sopenharmony_ci list_for_each_entry(lock, &res->granted, list) { 10462306a36Sopenharmony_ci __dlm_print_lock(lock); 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci printk(" converting queue:\n"); 10762306a36Sopenharmony_ci list_for_each_entry(lock, &res->converting, list) { 10862306a36Sopenharmony_ci __dlm_print_lock(lock); 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci printk(" blocked queue:\n"); 11162306a36Sopenharmony_ci list_for_each_entry(lock, &res->blocked, list) { 11262306a36Sopenharmony_ci __dlm_print_lock(lock); 11362306a36Sopenharmony_ci } 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_civoid dlm_print_one_lock(struct dlm_lock *lockid) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci dlm_print_one_lock_resource(lockid->lockres); 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dlm_print_one_lock); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic const char *dlm_errnames[] = { 12362306a36Sopenharmony_ci [DLM_NORMAL] = "DLM_NORMAL", 12462306a36Sopenharmony_ci [DLM_GRANTED] = "DLM_GRANTED", 12562306a36Sopenharmony_ci [DLM_DENIED] = "DLM_DENIED", 12662306a36Sopenharmony_ci [DLM_DENIED_NOLOCKS] = "DLM_DENIED_NOLOCKS", 12762306a36Sopenharmony_ci [DLM_WORKING] = "DLM_WORKING", 12862306a36Sopenharmony_ci [DLM_BLOCKED] = "DLM_BLOCKED", 12962306a36Sopenharmony_ci [DLM_BLOCKED_ORPHAN] = "DLM_BLOCKED_ORPHAN", 13062306a36Sopenharmony_ci [DLM_DENIED_GRACE_PERIOD] = "DLM_DENIED_GRACE_PERIOD", 13162306a36Sopenharmony_ci [DLM_SYSERR] = "DLM_SYSERR", 13262306a36Sopenharmony_ci [DLM_NOSUPPORT] = "DLM_NOSUPPORT", 13362306a36Sopenharmony_ci [DLM_CANCELGRANT] = "DLM_CANCELGRANT", 13462306a36Sopenharmony_ci [DLM_IVLOCKID] = "DLM_IVLOCKID", 13562306a36Sopenharmony_ci [DLM_SYNC] = "DLM_SYNC", 13662306a36Sopenharmony_ci [DLM_BADTYPE] = "DLM_BADTYPE", 13762306a36Sopenharmony_ci [DLM_BADRESOURCE] = "DLM_BADRESOURCE", 13862306a36Sopenharmony_ci [DLM_MAXHANDLES] = "DLM_MAXHANDLES", 13962306a36Sopenharmony_ci [DLM_NOCLINFO] = "DLM_NOCLINFO", 14062306a36Sopenharmony_ci [DLM_NOLOCKMGR] = "DLM_NOLOCKMGR", 14162306a36Sopenharmony_ci [DLM_NOPURGED] = "DLM_NOPURGED", 14262306a36Sopenharmony_ci [DLM_BADARGS] = "DLM_BADARGS", 14362306a36Sopenharmony_ci [DLM_VOID] = "DLM_VOID", 14462306a36Sopenharmony_ci [DLM_NOTQUEUED] = "DLM_NOTQUEUED", 14562306a36Sopenharmony_ci [DLM_IVBUFLEN] = "DLM_IVBUFLEN", 14662306a36Sopenharmony_ci [DLM_CVTUNGRANT] = "DLM_CVTUNGRANT", 14762306a36Sopenharmony_ci [DLM_BADPARAM] = "DLM_BADPARAM", 14862306a36Sopenharmony_ci [DLM_VALNOTVALID] = "DLM_VALNOTVALID", 14962306a36Sopenharmony_ci [DLM_REJECTED] = "DLM_REJECTED", 15062306a36Sopenharmony_ci [DLM_ABORT] = "DLM_ABORT", 15162306a36Sopenharmony_ci [DLM_CANCEL] = "DLM_CANCEL", 15262306a36Sopenharmony_ci [DLM_IVRESHANDLE] = "DLM_IVRESHANDLE", 15362306a36Sopenharmony_ci [DLM_DEADLOCK] = "DLM_DEADLOCK", 15462306a36Sopenharmony_ci [DLM_DENIED_NOASTS] = "DLM_DENIED_NOASTS", 15562306a36Sopenharmony_ci [DLM_FORWARD] = "DLM_FORWARD", 15662306a36Sopenharmony_ci [DLM_TIMEOUT] = "DLM_TIMEOUT", 15762306a36Sopenharmony_ci [DLM_IVGROUPID] = "DLM_IVGROUPID", 15862306a36Sopenharmony_ci [DLM_VERS_CONFLICT] = "DLM_VERS_CONFLICT", 15962306a36Sopenharmony_ci [DLM_BAD_DEVICE_PATH] = "DLM_BAD_DEVICE_PATH", 16062306a36Sopenharmony_ci [DLM_NO_DEVICE_PERMISSION] = "DLM_NO_DEVICE_PERMISSION", 16162306a36Sopenharmony_ci [DLM_NO_CONTROL_DEVICE ] = "DLM_NO_CONTROL_DEVICE ", 16262306a36Sopenharmony_ci [DLM_RECOVERING] = "DLM_RECOVERING", 16362306a36Sopenharmony_ci [DLM_MIGRATING] = "DLM_MIGRATING", 16462306a36Sopenharmony_ci [DLM_MAXSTATS] = "DLM_MAXSTATS", 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic const char *dlm_errmsgs[] = { 16862306a36Sopenharmony_ci [DLM_NORMAL] = "request in progress", 16962306a36Sopenharmony_ci [DLM_GRANTED] = "request granted", 17062306a36Sopenharmony_ci [DLM_DENIED] = "request denied", 17162306a36Sopenharmony_ci [DLM_DENIED_NOLOCKS] = "request denied, out of system resources", 17262306a36Sopenharmony_ci [DLM_WORKING] = "async request in progress", 17362306a36Sopenharmony_ci [DLM_BLOCKED] = "lock request blocked", 17462306a36Sopenharmony_ci [DLM_BLOCKED_ORPHAN] = "lock request blocked by a orphan lock", 17562306a36Sopenharmony_ci [DLM_DENIED_GRACE_PERIOD] = "topological change in progress", 17662306a36Sopenharmony_ci [DLM_SYSERR] = "system error", 17762306a36Sopenharmony_ci [DLM_NOSUPPORT] = "unsupported", 17862306a36Sopenharmony_ci [DLM_CANCELGRANT] = "can't cancel convert: already granted", 17962306a36Sopenharmony_ci [DLM_IVLOCKID] = "bad lockid", 18062306a36Sopenharmony_ci [DLM_SYNC] = "synchronous request granted", 18162306a36Sopenharmony_ci [DLM_BADTYPE] = "bad resource type", 18262306a36Sopenharmony_ci [DLM_BADRESOURCE] = "bad resource handle", 18362306a36Sopenharmony_ci [DLM_MAXHANDLES] = "no more resource handles", 18462306a36Sopenharmony_ci [DLM_NOCLINFO] = "can't contact cluster manager", 18562306a36Sopenharmony_ci [DLM_NOLOCKMGR] = "can't contact lock manager", 18662306a36Sopenharmony_ci [DLM_NOPURGED] = "can't contact purge daemon", 18762306a36Sopenharmony_ci [DLM_BADARGS] = "bad api args", 18862306a36Sopenharmony_ci [DLM_VOID] = "no status", 18962306a36Sopenharmony_ci [DLM_NOTQUEUED] = "NOQUEUE was specified and request failed", 19062306a36Sopenharmony_ci [DLM_IVBUFLEN] = "invalid resource name length", 19162306a36Sopenharmony_ci [DLM_CVTUNGRANT] = "attempted to convert ungranted lock", 19262306a36Sopenharmony_ci [DLM_BADPARAM] = "invalid lock mode specified", 19362306a36Sopenharmony_ci [DLM_VALNOTVALID] = "value block has been invalidated", 19462306a36Sopenharmony_ci [DLM_REJECTED] = "request rejected, unrecognized client", 19562306a36Sopenharmony_ci [DLM_ABORT] = "blocked lock request cancelled", 19662306a36Sopenharmony_ci [DLM_CANCEL] = "conversion request cancelled", 19762306a36Sopenharmony_ci [DLM_IVRESHANDLE] = "invalid resource handle", 19862306a36Sopenharmony_ci [DLM_DEADLOCK] = "deadlock recovery refused this request", 19962306a36Sopenharmony_ci [DLM_DENIED_NOASTS] = "failed to allocate AST", 20062306a36Sopenharmony_ci [DLM_FORWARD] = "request must wait for primary's response", 20162306a36Sopenharmony_ci [DLM_TIMEOUT] = "timeout value for lock has expired", 20262306a36Sopenharmony_ci [DLM_IVGROUPID] = "invalid group specification", 20362306a36Sopenharmony_ci [DLM_VERS_CONFLICT] = "version conflicts prevent request handling", 20462306a36Sopenharmony_ci [DLM_BAD_DEVICE_PATH] = "Locks device does not exist or path wrong", 20562306a36Sopenharmony_ci [DLM_NO_DEVICE_PERMISSION] = "Client has insufficient perms for device", 20662306a36Sopenharmony_ci [DLM_NO_CONTROL_DEVICE] = "Cannot set options on opened device ", 20762306a36Sopenharmony_ci [DLM_RECOVERING] = "lock resource being recovered", 20862306a36Sopenharmony_ci [DLM_MIGRATING] = "lock resource being migrated", 20962306a36Sopenharmony_ci [DLM_MAXSTATS] = "invalid error number", 21062306a36Sopenharmony_ci}; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ciconst char *dlm_errmsg(enum dlm_status err) 21362306a36Sopenharmony_ci{ 21462306a36Sopenharmony_ci if (err >= DLM_MAXSTATS || err < 0) 21562306a36Sopenharmony_ci return dlm_errmsgs[DLM_MAXSTATS]; 21662306a36Sopenharmony_ci return dlm_errmsgs[err]; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dlm_errmsg); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ciconst char *dlm_errname(enum dlm_status err) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci if (err >= DLM_MAXSTATS || err < 0) 22362306a36Sopenharmony_ci return dlm_errnames[DLM_MAXSTATS]; 22462306a36Sopenharmony_ci return dlm_errnames[err]; 22562306a36Sopenharmony_ci} 22662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dlm_errname); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci/* NOTE: This function converts a lockname into a string. It uses knowledge 22962306a36Sopenharmony_ci * of the format of the lockname that should be outside the purview of the dlm. 23062306a36Sopenharmony_ci * We are adding only to make dlm debugging slightly easier. 23162306a36Sopenharmony_ci * 23262306a36Sopenharmony_ci * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h. 23362306a36Sopenharmony_ci */ 23462306a36Sopenharmony_cistatic int stringify_lockname(const char *lockname, int locklen, char *buf, 23562306a36Sopenharmony_ci int len) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci int out = 0; 23862306a36Sopenharmony_ci __be64 inode_blkno_be; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci#define OCFS2_DENTRY_LOCK_INO_START 18 24162306a36Sopenharmony_ci if (*lockname == 'N') { 24262306a36Sopenharmony_ci memcpy((__be64 *)&inode_blkno_be, 24362306a36Sopenharmony_ci (char *)&lockname[OCFS2_DENTRY_LOCK_INO_START], 24462306a36Sopenharmony_ci sizeof(__be64)); 24562306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "%.*s%08x", 24662306a36Sopenharmony_ci OCFS2_DENTRY_LOCK_INO_START - 1, lockname, 24762306a36Sopenharmony_ci (unsigned int)be64_to_cpu(inode_blkno_be)); 24862306a36Sopenharmony_ci } else 24962306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "%.*s", 25062306a36Sopenharmony_ci locklen, lockname); 25162306a36Sopenharmony_ci return out; 25262306a36Sopenharmony_ci} 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_cistatic int stringify_nodemap(unsigned long *nodemap, int maxnodes, 25562306a36Sopenharmony_ci char *buf, int len) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci int out = 0; 25862306a36Sopenharmony_ci int i = -1; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci while ((i = find_next_bit(nodemap, maxnodes, i + 1)) < maxnodes) 26162306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "%d ", i); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci return out; 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci int out = 0; 26962306a36Sopenharmony_ci char *mle_type; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci if (mle->type == DLM_MLE_BLOCK) 27262306a36Sopenharmony_ci mle_type = "BLK"; 27362306a36Sopenharmony_ci else if (mle->type == DLM_MLE_MASTER) 27462306a36Sopenharmony_ci mle_type = "MAS"; 27562306a36Sopenharmony_ci else 27662306a36Sopenharmony_ci mle_type = "MIG"; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci out += stringify_lockname(mle->mname, mle->mnamelen, buf + out, len - out); 27962306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 28062306a36Sopenharmony_ci "\t%3s\tmas=%3u\tnew=%3u\tevt=%1d\tuse=%1d\tref=%3d\n", 28162306a36Sopenharmony_ci mle_type, mle->master, mle->new_master, 28262306a36Sopenharmony_ci !list_empty(&mle->hb_events), 28362306a36Sopenharmony_ci !!mle->inuse, 28462306a36Sopenharmony_ci kref_read(&mle->mle_refs)); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Maybe="); 28762306a36Sopenharmony_ci out += stringify_nodemap(mle->maybe_map, O2NM_MAX_NODES, 28862306a36Sopenharmony_ci buf + out, len - out); 28962306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Vote="); 29262306a36Sopenharmony_ci out += stringify_nodemap(mle->vote_map, O2NM_MAX_NODES, 29362306a36Sopenharmony_ci buf + out, len - out); 29462306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Response="); 29762306a36Sopenharmony_ci out += stringify_nodemap(mle->response_map, O2NM_MAX_NODES, 29862306a36Sopenharmony_ci buf + out, len - out); 29962306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Node="); 30262306a36Sopenharmony_ci out += stringify_nodemap(mle->node_map, O2NM_MAX_NODES, 30362306a36Sopenharmony_ci buf + out, len - out); 30462306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci return out; 30962306a36Sopenharmony_ci} 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_civoid dlm_print_one_mle(struct dlm_master_list_entry *mle) 31262306a36Sopenharmony_ci{ 31362306a36Sopenharmony_ci char *buf; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci buf = (char *) get_zeroed_page(GFP_ATOMIC); 31662306a36Sopenharmony_ci if (buf) { 31762306a36Sopenharmony_ci dump_mle(mle, buf, PAGE_SIZE - 1); 31862306a36Sopenharmony_ci free_page((unsigned long)buf); 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci} 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_cistatic struct dentry *dlm_debugfs_root; 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci#define DLM_DEBUGFS_DIR "o2dlm" 32762306a36Sopenharmony_ci#define DLM_DEBUGFS_DLM_STATE "dlm_state" 32862306a36Sopenharmony_ci#define DLM_DEBUGFS_LOCKING_STATE "locking_state" 32962306a36Sopenharmony_ci#define DLM_DEBUGFS_MLE_STATE "mle_state" 33062306a36Sopenharmony_ci#define DLM_DEBUGFS_PURGE_LIST "purge_list" 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci/* begin - utils funcs */ 33362306a36Sopenharmony_cistatic int debug_release(struct inode *inode, struct file *file) 33462306a36Sopenharmony_ci{ 33562306a36Sopenharmony_ci free_page((unsigned long)file->private_data); 33662306a36Sopenharmony_ci return 0; 33762306a36Sopenharmony_ci} 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistatic ssize_t debug_read(struct file *file, char __user *buf, 34062306a36Sopenharmony_ci size_t nbytes, loff_t *ppos) 34162306a36Sopenharmony_ci{ 34262306a36Sopenharmony_ci return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, 34362306a36Sopenharmony_ci i_size_read(file->f_mapping->host)); 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci/* end - util funcs */ 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci/* begin - purge list funcs */ 34862306a36Sopenharmony_cistatic int debug_purgelist_print(struct dlm_ctxt *dlm, char *buf, int len) 34962306a36Sopenharmony_ci{ 35062306a36Sopenharmony_ci struct dlm_lock_resource *res; 35162306a36Sopenharmony_ci int out = 0; 35262306a36Sopenharmony_ci unsigned long total = 0; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 35562306a36Sopenharmony_ci "Dumping Purgelist for Domain: %s\n", dlm->name); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci spin_lock(&dlm->spinlock); 35862306a36Sopenharmony_ci list_for_each_entry(res, &dlm->purge_list, purge) { 35962306a36Sopenharmony_ci ++total; 36062306a36Sopenharmony_ci if (len - out < 100) 36162306a36Sopenharmony_ci continue; 36262306a36Sopenharmony_ci spin_lock(&res->spinlock); 36362306a36Sopenharmony_ci out += stringify_lockname(res->lockname.name, 36462306a36Sopenharmony_ci res->lockname.len, 36562306a36Sopenharmony_ci buf + out, len - out); 36662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\t%ld\n", 36762306a36Sopenharmony_ci (jiffies - res->last_used)/HZ); 36862306a36Sopenharmony_ci spin_unlock(&res->spinlock); 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci spin_unlock(&dlm->spinlock); 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Total on list: %lu\n", total); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci return out; 37562306a36Sopenharmony_ci} 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_cistatic int debug_purgelist_open(struct inode *inode, struct file *file) 37862306a36Sopenharmony_ci{ 37962306a36Sopenharmony_ci struct dlm_ctxt *dlm = inode->i_private; 38062306a36Sopenharmony_ci char *buf = NULL; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci buf = (char *) get_zeroed_page(GFP_NOFS); 38362306a36Sopenharmony_ci if (!buf) 38462306a36Sopenharmony_ci goto bail; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci i_size_write(inode, debug_purgelist_print(dlm, buf, PAGE_SIZE - 1)); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci file->private_data = buf; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci return 0; 39162306a36Sopenharmony_cibail: 39262306a36Sopenharmony_ci return -ENOMEM; 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_cistatic const struct file_operations debug_purgelist_fops = { 39662306a36Sopenharmony_ci .open = debug_purgelist_open, 39762306a36Sopenharmony_ci .release = debug_release, 39862306a36Sopenharmony_ci .read = debug_read, 39962306a36Sopenharmony_ci .llseek = generic_file_llseek, 40062306a36Sopenharmony_ci}; 40162306a36Sopenharmony_ci/* end - purge list funcs */ 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci/* begin - debug mle funcs */ 40462306a36Sopenharmony_cistatic int debug_mle_print(struct dlm_ctxt *dlm, char *buf, int len) 40562306a36Sopenharmony_ci{ 40662306a36Sopenharmony_ci struct dlm_master_list_entry *mle; 40762306a36Sopenharmony_ci struct hlist_head *bucket; 40862306a36Sopenharmony_ci int i, out = 0; 40962306a36Sopenharmony_ci unsigned long total = 0, longest = 0, bucket_count = 0; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 41262306a36Sopenharmony_ci "Dumping MLEs for Domain: %s\n", dlm->name); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci spin_lock(&dlm->master_lock); 41562306a36Sopenharmony_ci for (i = 0; i < DLM_HASH_BUCKETS; i++) { 41662306a36Sopenharmony_ci bucket = dlm_master_hash(dlm, i); 41762306a36Sopenharmony_ci hlist_for_each_entry(mle, bucket, master_hash_node) { 41862306a36Sopenharmony_ci ++total; 41962306a36Sopenharmony_ci ++bucket_count; 42062306a36Sopenharmony_ci if (len - out < 200) 42162306a36Sopenharmony_ci continue; 42262306a36Sopenharmony_ci out += dump_mle(mle, buf + out, len - out); 42362306a36Sopenharmony_ci } 42462306a36Sopenharmony_ci longest = max(longest, bucket_count); 42562306a36Sopenharmony_ci bucket_count = 0; 42662306a36Sopenharmony_ci } 42762306a36Sopenharmony_ci spin_unlock(&dlm->master_lock); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 43062306a36Sopenharmony_ci "Total: %lu, Longest: %lu\n", total, longest); 43162306a36Sopenharmony_ci return out; 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_cistatic int debug_mle_open(struct inode *inode, struct file *file) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci struct dlm_ctxt *dlm = inode->i_private; 43762306a36Sopenharmony_ci char *buf = NULL; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci buf = (char *) get_zeroed_page(GFP_NOFS); 44062306a36Sopenharmony_ci if (!buf) 44162306a36Sopenharmony_ci goto bail; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci i_size_write(inode, debug_mle_print(dlm, buf, PAGE_SIZE - 1)); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci file->private_data = buf; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci return 0; 44862306a36Sopenharmony_cibail: 44962306a36Sopenharmony_ci return -ENOMEM; 45062306a36Sopenharmony_ci} 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_cistatic const struct file_operations debug_mle_fops = { 45362306a36Sopenharmony_ci .open = debug_mle_open, 45462306a36Sopenharmony_ci .release = debug_release, 45562306a36Sopenharmony_ci .read = debug_read, 45662306a36Sopenharmony_ci .llseek = generic_file_llseek, 45762306a36Sopenharmony_ci}; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci/* end - debug mle funcs */ 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci/* begin - debug lockres funcs */ 46262306a36Sopenharmony_cistatic int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci int out; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci#define DEBUG_LOCK_VERSION 1 46762306a36Sopenharmony_ci spin_lock(&lock->spinlock); 46862306a36Sopenharmony_ci out = scnprintf(buf, len, "LOCK:%d,%d,%d,%d,%d,%d:%lld,%d,%d,%d,%d,%d," 46962306a36Sopenharmony_ci "%d,%d,%d,%d\n", 47062306a36Sopenharmony_ci DEBUG_LOCK_VERSION, 47162306a36Sopenharmony_ci list_type, lock->ml.type, lock->ml.convert_type, 47262306a36Sopenharmony_ci lock->ml.node, 47362306a36Sopenharmony_ci dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), 47462306a36Sopenharmony_ci dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), 47562306a36Sopenharmony_ci !list_empty(&lock->ast_list), 47662306a36Sopenharmony_ci !list_empty(&lock->bast_list), 47762306a36Sopenharmony_ci lock->ast_pending, lock->bast_pending, 47862306a36Sopenharmony_ci lock->convert_pending, lock->lock_pending, 47962306a36Sopenharmony_ci lock->cancel_pending, lock->unlock_pending, 48062306a36Sopenharmony_ci kref_read(&lock->lock_refs)); 48162306a36Sopenharmony_ci spin_unlock(&lock->spinlock); 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci return out; 48462306a36Sopenharmony_ci} 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_cistatic int dump_lockres(struct dlm_lock_resource *res, char *buf, int len) 48762306a36Sopenharmony_ci{ 48862306a36Sopenharmony_ci struct dlm_lock *lock; 48962306a36Sopenharmony_ci int i; 49062306a36Sopenharmony_ci int out = 0; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "NAME:"); 49362306a36Sopenharmony_ci out += stringify_lockname(res->lockname.name, res->lockname.len, 49462306a36Sopenharmony_ci buf + out, len - out); 49562306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci#define DEBUG_LRES_VERSION 1 49862306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 49962306a36Sopenharmony_ci "LRES:%d,%d,%d,%ld,%d,%d,%d,%d,%d,%d,%d\n", 50062306a36Sopenharmony_ci DEBUG_LRES_VERSION, 50162306a36Sopenharmony_ci res->owner, res->state, res->last_used, 50262306a36Sopenharmony_ci !list_empty(&res->purge), 50362306a36Sopenharmony_ci !list_empty(&res->dirty), 50462306a36Sopenharmony_ci !list_empty(&res->recovering), 50562306a36Sopenharmony_ci res->inflight_locks, res->migration_pending, 50662306a36Sopenharmony_ci atomic_read(&res->asts_reserved), 50762306a36Sopenharmony_ci kref_read(&res->refs)); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci /* refmap */ 51062306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "RMAP:"); 51162306a36Sopenharmony_ci out += stringify_nodemap(res->refmap, O2NM_MAX_NODES, 51262306a36Sopenharmony_ci buf + out, len - out); 51362306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci /* lvb */ 51662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "LVBX:"); 51762306a36Sopenharmony_ci for (i = 0; i < DLM_LVB_LEN; i++) 51862306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 51962306a36Sopenharmony_ci "%02x", (unsigned char)res->lvb[i]); 52062306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci /* granted */ 52362306a36Sopenharmony_ci list_for_each_entry(lock, &res->granted, list) 52462306a36Sopenharmony_ci out += dump_lock(lock, 0, buf + out, len - out); 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci /* converting */ 52762306a36Sopenharmony_ci list_for_each_entry(lock, &res->converting, list) 52862306a36Sopenharmony_ci out += dump_lock(lock, 1, buf + out, len - out); 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci /* blocked */ 53162306a36Sopenharmony_ci list_for_each_entry(lock, &res->blocked, list) 53262306a36Sopenharmony_ci out += dump_lock(lock, 2, buf + out, len - out); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci return out; 53762306a36Sopenharmony_ci} 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_cistatic void *lockres_seq_start(struct seq_file *m, loff_t *pos) 54062306a36Sopenharmony_ci{ 54162306a36Sopenharmony_ci struct debug_lockres *dl = m->private; 54262306a36Sopenharmony_ci struct dlm_ctxt *dlm = dl->dl_ctxt; 54362306a36Sopenharmony_ci struct dlm_lock_resource *oldres = dl->dl_res; 54462306a36Sopenharmony_ci struct dlm_lock_resource *res = NULL, *iter; 54562306a36Sopenharmony_ci struct list_head *track_list; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci spin_lock(&dlm->track_lock); 54862306a36Sopenharmony_ci if (oldres) 54962306a36Sopenharmony_ci track_list = &oldres->tracking; 55062306a36Sopenharmony_ci else { 55162306a36Sopenharmony_ci track_list = &dlm->tracking_list; 55262306a36Sopenharmony_ci if (list_empty(track_list)) { 55362306a36Sopenharmony_ci dl = NULL; 55462306a36Sopenharmony_ci spin_unlock(&dlm->track_lock); 55562306a36Sopenharmony_ci goto bail; 55662306a36Sopenharmony_ci } 55762306a36Sopenharmony_ci } 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci list_for_each_entry(iter, track_list, tracking) { 56062306a36Sopenharmony_ci if (&iter->tracking != &dlm->tracking_list) { 56162306a36Sopenharmony_ci dlm_lockres_get(iter); 56262306a36Sopenharmony_ci res = iter; 56362306a36Sopenharmony_ci } 56462306a36Sopenharmony_ci break; 56562306a36Sopenharmony_ci } 56662306a36Sopenharmony_ci spin_unlock(&dlm->track_lock); 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci if (oldres) 56962306a36Sopenharmony_ci dlm_lockres_put(oldres); 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci dl->dl_res = res; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci if (res) { 57462306a36Sopenharmony_ci spin_lock(&res->spinlock); 57562306a36Sopenharmony_ci dump_lockres(res, dl->dl_buf, dl->dl_len - 1); 57662306a36Sopenharmony_ci spin_unlock(&res->spinlock); 57762306a36Sopenharmony_ci } else 57862306a36Sopenharmony_ci dl = NULL; 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cibail: 58162306a36Sopenharmony_ci /* passed to seq_show */ 58262306a36Sopenharmony_ci return dl; 58362306a36Sopenharmony_ci} 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistatic void lockres_seq_stop(struct seq_file *m, void *v) 58662306a36Sopenharmony_ci{ 58762306a36Sopenharmony_ci} 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_cistatic void *lockres_seq_next(struct seq_file *m, void *v, loff_t *pos) 59062306a36Sopenharmony_ci{ 59162306a36Sopenharmony_ci return NULL; 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_cistatic int lockres_seq_show(struct seq_file *s, void *v) 59562306a36Sopenharmony_ci{ 59662306a36Sopenharmony_ci struct debug_lockres *dl = (struct debug_lockres *)v; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci seq_printf(s, "%s", dl->dl_buf); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci return 0; 60162306a36Sopenharmony_ci} 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_cistatic const struct seq_operations debug_lockres_ops = { 60462306a36Sopenharmony_ci .start = lockres_seq_start, 60562306a36Sopenharmony_ci .stop = lockres_seq_stop, 60662306a36Sopenharmony_ci .next = lockres_seq_next, 60762306a36Sopenharmony_ci .show = lockres_seq_show, 60862306a36Sopenharmony_ci}; 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_cistatic int debug_lockres_open(struct inode *inode, struct file *file) 61162306a36Sopenharmony_ci{ 61262306a36Sopenharmony_ci struct dlm_ctxt *dlm = inode->i_private; 61362306a36Sopenharmony_ci struct debug_lockres *dl; 61462306a36Sopenharmony_ci void *buf; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 61762306a36Sopenharmony_ci if (!buf) 61862306a36Sopenharmony_ci goto bail; 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci dl = __seq_open_private(file, &debug_lockres_ops, sizeof(*dl)); 62162306a36Sopenharmony_ci if (!dl) 62262306a36Sopenharmony_ci goto bailfree; 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci dl->dl_len = PAGE_SIZE; 62562306a36Sopenharmony_ci dl->dl_buf = buf; 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci dlm_grab(dlm); 62862306a36Sopenharmony_ci dl->dl_ctxt = dlm; 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci return 0; 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_cibailfree: 63362306a36Sopenharmony_ci kfree(buf); 63462306a36Sopenharmony_cibail: 63562306a36Sopenharmony_ci mlog_errno(-ENOMEM); 63662306a36Sopenharmony_ci return -ENOMEM; 63762306a36Sopenharmony_ci} 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_cistatic int debug_lockres_release(struct inode *inode, struct file *file) 64062306a36Sopenharmony_ci{ 64162306a36Sopenharmony_ci struct seq_file *seq = file->private_data; 64262306a36Sopenharmony_ci struct debug_lockres *dl = (struct debug_lockres *)seq->private; 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci if (dl->dl_res) 64562306a36Sopenharmony_ci dlm_lockres_put(dl->dl_res); 64662306a36Sopenharmony_ci dlm_put(dl->dl_ctxt); 64762306a36Sopenharmony_ci kfree(dl->dl_buf); 64862306a36Sopenharmony_ci return seq_release_private(inode, file); 64962306a36Sopenharmony_ci} 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_cistatic const struct file_operations debug_lockres_fops = { 65262306a36Sopenharmony_ci .open = debug_lockres_open, 65362306a36Sopenharmony_ci .release = debug_lockres_release, 65462306a36Sopenharmony_ci .read = seq_read, 65562306a36Sopenharmony_ci .llseek = seq_lseek, 65662306a36Sopenharmony_ci}; 65762306a36Sopenharmony_ci/* end - debug lockres funcs */ 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci/* begin - debug state funcs */ 66062306a36Sopenharmony_cistatic int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len) 66162306a36Sopenharmony_ci{ 66262306a36Sopenharmony_ci int out = 0; 66362306a36Sopenharmony_ci struct dlm_reco_node_data *node; 66462306a36Sopenharmony_ci char *state; 66562306a36Sopenharmony_ci int cur_mles = 0, tot_mles = 0; 66662306a36Sopenharmony_ci int i; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci spin_lock(&dlm->spinlock); 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci switch (dlm->dlm_state) { 67162306a36Sopenharmony_ci case DLM_CTXT_NEW: 67262306a36Sopenharmony_ci state = "NEW"; break; 67362306a36Sopenharmony_ci case DLM_CTXT_JOINED: 67462306a36Sopenharmony_ci state = "JOINED"; break; 67562306a36Sopenharmony_ci case DLM_CTXT_IN_SHUTDOWN: 67662306a36Sopenharmony_ci state = "SHUTDOWN"; break; 67762306a36Sopenharmony_ci case DLM_CTXT_LEAVING: 67862306a36Sopenharmony_ci state = "LEAVING"; break; 67962306a36Sopenharmony_ci default: 68062306a36Sopenharmony_ci state = "UNKNOWN"; break; 68162306a36Sopenharmony_ci } 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci /* Domain: xxxxxxxxxx Key: 0xdfbac769 */ 68462306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 68562306a36Sopenharmony_ci "Domain: %s Key: 0x%08x Protocol: %d.%d\n", 68662306a36Sopenharmony_ci dlm->name, dlm->key, dlm->dlm_locking_proto.pv_major, 68762306a36Sopenharmony_ci dlm->dlm_locking_proto.pv_minor); 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci /* Thread Pid: xxx Node: xxx State: xxxxx */ 69062306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 69162306a36Sopenharmony_ci "Thread Pid: %d Node: %d State: %s\n", 69262306a36Sopenharmony_ci task_pid_nr(dlm->dlm_thread_task), dlm->node_num, state); 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci /* Number of Joins: xxx Joining Node: xxx */ 69562306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 69662306a36Sopenharmony_ci "Number of Joins: %d Joining Node: %d\n", 69762306a36Sopenharmony_ci dlm->num_joins, dlm->joining_node); 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci /* Domain Map: xx xx xx */ 70062306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Domain Map: "); 70162306a36Sopenharmony_ci out += stringify_nodemap(dlm->domain_map, O2NM_MAX_NODES, 70262306a36Sopenharmony_ci buf + out, len - out); 70362306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci /* Exit Domain Map: xx xx xx */ 70662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Exit Domain Map: "); 70762306a36Sopenharmony_ci out += stringify_nodemap(dlm->exit_domain_map, O2NM_MAX_NODES, 70862306a36Sopenharmony_ci buf + out, len - out); 70962306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci /* Live Map: xx xx xx */ 71262306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Live Map: "); 71362306a36Sopenharmony_ci out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES, 71462306a36Sopenharmony_ci buf + out, len - out); 71562306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci /* Lock Resources: xxx (xxx) */ 71862306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 71962306a36Sopenharmony_ci "Lock Resources: %d (%d)\n", 72062306a36Sopenharmony_ci atomic_read(&dlm->res_cur_count), 72162306a36Sopenharmony_ci atomic_read(&dlm->res_tot_count)); 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_ci for (i = 0; i < DLM_MLE_NUM_TYPES; ++i) 72462306a36Sopenharmony_ci tot_mles += atomic_read(&dlm->mle_tot_count[i]); 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci for (i = 0; i < DLM_MLE_NUM_TYPES; ++i) 72762306a36Sopenharmony_ci cur_mles += atomic_read(&dlm->mle_cur_count[i]); 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci /* MLEs: xxx (xxx) */ 73062306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 73162306a36Sopenharmony_ci "MLEs: %d (%d)\n", cur_mles, tot_mles); 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci /* Blocking: xxx (xxx) */ 73462306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 73562306a36Sopenharmony_ci " Blocking: %d (%d)\n", 73662306a36Sopenharmony_ci atomic_read(&dlm->mle_cur_count[DLM_MLE_BLOCK]), 73762306a36Sopenharmony_ci atomic_read(&dlm->mle_tot_count[DLM_MLE_BLOCK])); 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci /* Mastery: xxx (xxx) */ 74062306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 74162306a36Sopenharmony_ci " Mastery: %d (%d)\n", 74262306a36Sopenharmony_ci atomic_read(&dlm->mle_cur_count[DLM_MLE_MASTER]), 74362306a36Sopenharmony_ci atomic_read(&dlm->mle_tot_count[DLM_MLE_MASTER])); 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci /* Migration: xxx (xxx) */ 74662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 74762306a36Sopenharmony_ci " Migration: %d (%d)\n", 74862306a36Sopenharmony_ci atomic_read(&dlm->mle_cur_count[DLM_MLE_MIGRATION]), 74962306a36Sopenharmony_ci atomic_read(&dlm->mle_tot_count[DLM_MLE_MIGRATION])); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci /* Lists: Dirty=Empty Purge=InUse PendingASTs=Empty ... */ 75262306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 75362306a36Sopenharmony_ci "Lists: Dirty=%s Purge=%s PendingASTs=%s " 75462306a36Sopenharmony_ci "PendingBASTs=%s\n", 75562306a36Sopenharmony_ci (list_empty(&dlm->dirty_list) ? "Empty" : "InUse"), 75662306a36Sopenharmony_ci (list_empty(&dlm->purge_list) ? "Empty" : "InUse"), 75762306a36Sopenharmony_ci (list_empty(&dlm->pending_asts) ? "Empty" : "InUse"), 75862306a36Sopenharmony_ci (list_empty(&dlm->pending_basts) ? "Empty" : "InUse")); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci /* Purge Count: xxx Refs: xxx */ 76162306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 76262306a36Sopenharmony_ci "Purge Count: %d Refs: %d\n", dlm->purge_count, 76362306a36Sopenharmony_ci kref_read(&dlm->dlm_refs)); 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci /* Dead Node: xxx */ 76662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 76762306a36Sopenharmony_ci "Dead Node: %d\n", dlm->reco.dead_node); 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci /* What about DLM_RECO_STATE_FINALIZE? */ 77062306a36Sopenharmony_ci if (dlm->reco.state == DLM_RECO_STATE_ACTIVE) 77162306a36Sopenharmony_ci state = "ACTIVE"; 77262306a36Sopenharmony_ci else 77362306a36Sopenharmony_ci state = "INACTIVE"; 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_ci /* Recovery Pid: xxxx Master: xxx State: xxxx */ 77662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, 77762306a36Sopenharmony_ci "Recovery Pid: %d Master: %d State: %s\n", 77862306a36Sopenharmony_ci task_pid_nr(dlm->dlm_reco_thread_task), 77962306a36Sopenharmony_ci dlm->reco.new_master, state); 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci /* Recovery Map: xx xx */ 78262306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Recovery Map: "); 78362306a36Sopenharmony_ci out += stringify_nodemap(dlm->recovery_map, O2NM_MAX_NODES, 78462306a36Sopenharmony_ci buf + out, len - out); 78562306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\n"); 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci /* Recovery Node State: */ 78862306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "Recovery Node State:\n"); 78962306a36Sopenharmony_ci list_for_each_entry(node, &dlm->reco.node_data, list) { 79062306a36Sopenharmony_ci switch (node->state) { 79162306a36Sopenharmony_ci case DLM_RECO_NODE_DATA_INIT: 79262306a36Sopenharmony_ci state = "INIT"; 79362306a36Sopenharmony_ci break; 79462306a36Sopenharmony_ci case DLM_RECO_NODE_DATA_REQUESTING: 79562306a36Sopenharmony_ci state = "REQUESTING"; 79662306a36Sopenharmony_ci break; 79762306a36Sopenharmony_ci case DLM_RECO_NODE_DATA_DEAD: 79862306a36Sopenharmony_ci state = "DEAD"; 79962306a36Sopenharmony_ci break; 80062306a36Sopenharmony_ci case DLM_RECO_NODE_DATA_RECEIVING: 80162306a36Sopenharmony_ci state = "RECEIVING"; 80262306a36Sopenharmony_ci break; 80362306a36Sopenharmony_ci case DLM_RECO_NODE_DATA_REQUESTED: 80462306a36Sopenharmony_ci state = "REQUESTED"; 80562306a36Sopenharmony_ci break; 80662306a36Sopenharmony_ci case DLM_RECO_NODE_DATA_DONE: 80762306a36Sopenharmony_ci state = "DONE"; 80862306a36Sopenharmony_ci break; 80962306a36Sopenharmony_ci case DLM_RECO_NODE_DATA_FINALIZE_SENT: 81062306a36Sopenharmony_ci state = "FINALIZE-SENT"; 81162306a36Sopenharmony_ci break; 81262306a36Sopenharmony_ci default: 81362306a36Sopenharmony_ci state = "BAD"; 81462306a36Sopenharmony_ci break; 81562306a36Sopenharmony_ci } 81662306a36Sopenharmony_ci out += scnprintf(buf + out, len - out, "\t%u - %s\n", 81762306a36Sopenharmony_ci node->node_num, state); 81862306a36Sopenharmony_ci } 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_ci spin_unlock(&dlm->spinlock); 82162306a36Sopenharmony_ci 82262306a36Sopenharmony_ci return out; 82362306a36Sopenharmony_ci} 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_cistatic int debug_state_open(struct inode *inode, struct file *file) 82662306a36Sopenharmony_ci{ 82762306a36Sopenharmony_ci struct dlm_ctxt *dlm = inode->i_private; 82862306a36Sopenharmony_ci char *buf = NULL; 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci buf = (char *) get_zeroed_page(GFP_NOFS); 83162306a36Sopenharmony_ci if (!buf) 83262306a36Sopenharmony_ci goto bail; 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci i_size_write(inode, debug_state_print(dlm, buf, PAGE_SIZE - 1)); 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci file->private_data = buf; 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci return 0; 83962306a36Sopenharmony_cibail: 84062306a36Sopenharmony_ci return -ENOMEM; 84162306a36Sopenharmony_ci} 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_cistatic const struct file_operations debug_state_fops = { 84462306a36Sopenharmony_ci .open = debug_state_open, 84562306a36Sopenharmony_ci .release = debug_release, 84662306a36Sopenharmony_ci .read = debug_read, 84762306a36Sopenharmony_ci .llseek = generic_file_llseek, 84862306a36Sopenharmony_ci}; 84962306a36Sopenharmony_ci/* end - debug state funcs */ 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci/* files in subroot */ 85262306a36Sopenharmony_civoid dlm_debug_init(struct dlm_ctxt *dlm) 85362306a36Sopenharmony_ci{ 85462306a36Sopenharmony_ci /* for dumping dlm_ctxt */ 85562306a36Sopenharmony_ci debugfs_create_file(DLM_DEBUGFS_DLM_STATE, S_IFREG|S_IRUSR, 85662306a36Sopenharmony_ci dlm->dlm_debugfs_subroot, dlm, &debug_state_fops); 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci /* for dumping lockres */ 85962306a36Sopenharmony_ci debugfs_create_file(DLM_DEBUGFS_LOCKING_STATE, S_IFREG|S_IRUSR, 86062306a36Sopenharmony_ci dlm->dlm_debugfs_subroot, dlm, &debug_lockres_fops); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci /* for dumping mles */ 86362306a36Sopenharmony_ci debugfs_create_file(DLM_DEBUGFS_MLE_STATE, S_IFREG|S_IRUSR, 86462306a36Sopenharmony_ci dlm->dlm_debugfs_subroot, dlm, &debug_mle_fops); 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci /* for dumping lockres on the purge list */ 86762306a36Sopenharmony_ci debugfs_create_file(DLM_DEBUGFS_PURGE_LIST, S_IFREG|S_IRUSR, 86862306a36Sopenharmony_ci dlm->dlm_debugfs_subroot, dlm, 86962306a36Sopenharmony_ci &debug_purgelist_fops); 87062306a36Sopenharmony_ci} 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci/* subroot - domain dir */ 87362306a36Sopenharmony_civoid dlm_create_debugfs_subroot(struct dlm_ctxt *dlm) 87462306a36Sopenharmony_ci{ 87562306a36Sopenharmony_ci dlm->dlm_debugfs_subroot = debugfs_create_dir(dlm->name, 87662306a36Sopenharmony_ci dlm_debugfs_root); 87762306a36Sopenharmony_ci} 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_civoid dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm) 88062306a36Sopenharmony_ci{ 88162306a36Sopenharmony_ci debugfs_remove_recursive(dlm->dlm_debugfs_subroot); 88262306a36Sopenharmony_ci} 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci/* debugfs root */ 88562306a36Sopenharmony_civoid dlm_create_debugfs_root(void) 88662306a36Sopenharmony_ci{ 88762306a36Sopenharmony_ci dlm_debugfs_root = debugfs_create_dir(DLM_DEBUGFS_DIR, NULL); 88862306a36Sopenharmony_ci} 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_civoid dlm_destroy_debugfs_root(void) 89162306a36Sopenharmony_ci{ 89262306a36Sopenharmony_ci debugfs_remove(dlm_debugfs_root); 89362306a36Sopenharmony_ci} 89462306a36Sopenharmony_ci#endif /* CONFIG_DEBUG_FS */ 895