dlmdebug.c

来自「ocfs1.4.1 oracle分布式文件系统」· C语言 代码 · 共 1,038 行 · 第 1/2 页

C
1,038
字号
			"Total on list: %ld\n", total);	return out;}static int debug_mle_open(struct inode *inode, struct file *file){	struct dlm_ctxt *dlm = inode->i_private;	struct debug_buffer *db;	db = debug_buffer_allocate();	if (!db)		goto bail;	db->len = debug_mle_print(dlm, db);	file->private_data = db;	return 0;bail:	return -ENOMEM;}static struct file_operations debug_mle_fops = {	.open =		debug_mle_open,	.release =	debug_buffer_release,	.read =		debug_buffer_read,	.llseek =	debug_buffer_llseek,};/* end - debug mle funcs *//* begin - debug lockres funcs */static int dump_lock(struct dlm_lock *lock, int list_type, char *buf, int len){	int out;#define DEBUG_LOCK_VERSION	1	spin_lock(&lock->spinlock);	out = snprintf(buf, len, "LOCK:%d,%d,%d,%d,%d,%d:%lld,%d,%d,%d,%d,%d,"		       "%d,%d,%d,%d\n",		       DEBUG_LOCK_VERSION,		       list_type, lock->ml.type, lock->ml.convert_type,		       lock->ml.node,		       dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),		       dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),		       !list_empty(&lock->ast_list),		       !list_empty(&lock->bast_list),		       lock->ast_pending, lock->bast_pending,		       lock->convert_pending, lock->lock_pending,		       lock->cancel_pending, lock->unlock_pending,		       atomic_read(&lock->lock_refs.refcount));	spin_unlock(&lock->spinlock);	return out;}static int dump_lockres(struct dlm_lock_resource *res, char *buf, int len){	struct dlm_lock *lock;	int i;	int out = 0;	out += snprintf(buf + out, len - out, "NAME:");	out += stringify_lockname(res->lockname.name, res->lockname.len,				  buf + out, len - out);	out += snprintf(buf + out, len - out, "\n");#define DEBUG_LRES_VERSION	1	out += snprintf(buf + out, len - out,			"LRES:%d,%d,%d,%ld,%d,%d,%d,%d,%d,%d,%d\n",			DEBUG_LRES_VERSION,			res->owner, res->state, res->last_used,			!list_empty(&res->purge),			!list_empty(&res->dirty),			!list_empty(&res->recovering),			res->inflight_locks, res->migration_pending,			atomic_read(&res->asts_reserved),			atomic_read(&res->refs.refcount));	/* refmap */	out += snprintf(buf + out, len - out, "RMAP:");	out += stringify_nodemap(res->refmap, O2NM_MAX_NODES,				 buf + out, len - out);	out += snprintf(buf + out, len - out, "\n");	/* lvb */	out += snprintf(buf + out, len - out, "LVBX:");	for (i = 0; i < DLM_LVB_LEN; i++)		out += snprintf(buf + out, len - out,					"%02x", (unsigned char)res->lvb[i]);	out += snprintf(buf + out, len - out, "\n");	/* granted */	list_for_each_entry(lock, &res->granted, list)		out += dump_lock(lock, 0, buf + out, len - out);	/* converting */	list_for_each_entry(lock, &res->converting, list)		out += dump_lock(lock, 1, buf + out, len - out);	/* blocked */	list_for_each_entry(lock, &res->blocked, list)		out += dump_lock(lock, 2, buf + out, len - out);	out += snprintf(buf + out, len - out, "\n");	return out;}static void *lockres_seq_start(struct seq_file *m, loff_t *pos){	struct debug_lockres *dl = m->private;	struct dlm_ctxt *dlm = dl->dl_ctxt;	struct dlm_lock_resource *res = NULL;	spin_lock(&dlm->spinlock);	if (dl->dl_res) {		list_for_each_entry(res, &dl->dl_res->tracking, tracking) {			if (dl->dl_res) {				dlm_lockres_put(dl->dl_res);				dl->dl_res = NULL;			}			if (&res->tracking == &dlm->tracking_list) {				mlog(0, "End of list found, %p\n", res);				dl = NULL;				break;			}			dlm_lockres_get(res);			dl->dl_res = res;			break;		}	} else {		if (!list_empty(&dlm->tracking_list)) {			list_for_each_entry(res, &dlm->tracking_list, tracking)				break;			dlm_lockres_get(res);			dl->dl_res = res;		} else			dl = NULL;	}	if (dl) {		spin_lock(&dl->dl_res->spinlock);		dump_lockres(dl->dl_res, dl->dl_buf, dl->dl_len - 1);		spin_unlock(&dl->dl_res->spinlock);	}	spin_unlock(&dlm->spinlock);	return dl;}static void lockres_seq_stop(struct seq_file *m, void *v){}static void *lockres_seq_next(struct seq_file *m, void *v, loff_t *pos){	return NULL;}static int lockres_seq_show(struct seq_file *s, void *v){	struct debug_lockres *dl = (struct debug_lockres *)v;	seq_printf(s, "%s", dl->dl_buf);	return 0;}static struct seq_operations debug_lockres_ops = {	.start =	lockres_seq_start,	.stop =		lockres_seq_stop,	.next =		lockres_seq_next,	.show =		lockres_seq_show,};static int debug_lockres_open(struct inode *inode, struct file *file){	struct dlm_ctxt *dlm = inode->i_private;	int ret = -ENOMEM;	struct seq_file *seq;	struct debug_lockres *dl = NULL;	dl = kzalloc(sizeof(struct debug_lockres), GFP_KERNEL);	if (!dl) {		mlog_errno(ret);		goto bail;	}	dl->dl_len = PAGE_SIZE;	dl->dl_buf = kmalloc(dl->dl_len, GFP_KERNEL);	if (!dl->dl_buf) {		mlog_errno(ret);		goto bail;	}	ret = seq_open(file, &debug_lockres_ops);	if (ret) {		mlog_errno(ret);		goto bail;	}	seq = (struct seq_file *) file->private_data;	seq->private = dl;	dlm_grab(dlm);	dl->dl_ctxt = dlm;	return 0;bail:	if (dl)		kfree(dl->dl_buf);	kfree(dl);	return ret;}static int debug_lockres_release(struct inode *inode, struct file *file){	struct seq_file *seq = (struct seq_file *)file->private_data;	struct debug_lockres *dl = (struct debug_lockres *)seq->private;	if (dl->dl_res)		dlm_lockres_put(dl->dl_res);	dlm_put(dl->dl_ctxt);	kfree(dl->dl_buf);	return seq_release_private(inode, file);}static struct file_operations debug_lockres_fops = {	.open =		debug_lockres_open,	.release =	debug_lockres_release,	.read =		seq_read,	.llseek =	seq_lseek,};/* end - debug lockres funcs *//* begin - debug state funcs */static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db){	int out = 0;	struct dlm_reco_node_data *node;	char *state;	int lres, rres, ures, tres;	lres = atomic_read(&dlm->local_resources);	rres = atomic_read(&dlm->remote_resources);	ures = atomic_read(&dlm->unknown_resources);	tres = lres + rres + ures;	spin_lock(&dlm->spinlock);	switch (dlm->dlm_state) {	case DLM_CTXT_NEW:		state = "NEW"; break;	case DLM_CTXT_JOINED:		state = "JOINED"; break;	case DLM_CTXT_IN_SHUTDOWN:		state = "SHUTDOWN"; break;	case DLM_CTXT_LEAVING:		state = "LEAVING"; break;	default:		state = "UNKNOWN"; break;	}	/* Domain: xxxxxxxxxx  Key: 0xdfbac769 */	out += snprintf(db->buf + out, db->len - out,			"Domain: %s  Key: 0x%08x\n", dlm->name, dlm->key);	/* Thread Pid: xxx  Node: xxx  State: xxxxx */	out += snprintf(db->buf + out, db->len - out,			"Thread Pid: %d  Node: %d  State: %s\n",			dlm->dlm_thread_task->pid, dlm->node_num, state);	/* Number of Joins: xxx  Joining Node: xxx */	out += snprintf(db->buf + out, db->len - out,			"Number of Joins: %d  Joining Node: %d\n",			dlm->num_joins, dlm->joining_node);	/* Domain Map: xx xx xx */	out += snprintf(db->buf + out, db->len - out, "Domain Map: ");	out += stringify_nodemap(dlm->domain_map, O2NM_MAX_NODES,				 db->buf + out, db->len - out);	out += snprintf(db->buf + out, db->len - out, "\n");	/* Live Map: xx xx xx */	out += snprintf(db->buf + out, db->len - out, "Live Map: ");	out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES,				 db->buf + out, db->len - out);	out += snprintf(db->buf + out, db->len - out, "\n");	/* Mastered Resources Total: xxx  Locally: xxx  Remotely: ... */	out += snprintf(db->buf + out, db->len - out,			"Mastered Resources Total: %d  Locally: %d  "			"Remotely: %d  Unknown: %d\n",			tres, lres, rres, ures);	/* Lists: Dirty=Empty  Purge=InUse  PendingASTs=Empty  ... */	out += snprintf(db->buf + out, db->len - out,			"Lists: Dirty=%s  Purge=%s  PendingASTs=%s  "			"PendingBASTs=%s  Master=%s\n",			(list_empty(&dlm->dirty_list) ? "Empty" : "InUse"),			(list_empty(&dlm->purge_list) ? "Empty" : "InUse"),			(list_empty(&dlm->pending_asts) ? "Empty" : "InUse"),			(list_empty(&dlm->pending_basts) ? "Empty" : "InUse"),			(list_empty(&dlm->master_list) ? "Empty" : "InUse"));	/* Purge Count: xxx  Refs: xxx */	out += snprintf(db->buf + out, db->len - out,			"Purge Count: %d  Refs: %d\n", dlm->purge_count,			atomic_read(&dlm->dlm_refs.refcount));	/* Dead Node: xxx */	out += snprintf(db->buf + out, db->len - out,			"Dead Node: %d\n", dlm->reco.dead_node);	/* What about DLM_RECO_STATE_FINALIZE? */	if (dlm->reco.state == DLM_RECO_STATE_ACTIVE)		state = "ACTIVE";	else		state = "INACTIVE";	/* Recovery Pid: xxxx  Master: xxx  State: xxxx */	out += snprintf(db->buf + out, db->len - out,			"Recovery Pid: %d  Master: %d  State: %s\n",			dlm->dlm_reco_thread_task->pid,			dlm->reco.new_master, state);	/* Recovery Map: xx xx */	out += snprintf(db->buf + out, db->len - out, "Recovery Map: ");	out += stringify_nodemap(dlm->recovery_map, O2NM_MAX_NODES,				 db->buf + out, db->len - out);	out += snprintf(db->buf + out, db->len - out, "\n");	/* Recovery Node State: */	out += snprintf(db->buf + out, db->len - out, "Recovery Node State:\n");	list_for_each_entry(node, &dlm->reco.node_data, list) {		switch (node->state) {		case DLM_RECO_NODE_DATA_INIT:			state = "INIT";			break;		case DLM_RECO_NODE_DATA_REQUESTING:			state = "REQUESTING";			break;		case DLM_RECO_NODE_DATA_DEAD:			state = "DEAD";			break;		case DLM_RECO_NODE_DATA_RECEIVING:			state = "RECEIVING";			break;		case DLM_RECO_NODE_DATA_REQUESTED:			state = "REQUESTED";			break;		case DLM_RECO_NODE_DATA_DONE:			state = "DONE";			break;		case DLM_RECO_NODE_DATA_FINALIZE_SENT:			state = "FINALIZE-SENT";			break;		default:			state = "BAD";			break;		}		out += snprintf(db->buf + out, db->len - out, "\t%u - %s\n",				node->node_num, state);	}	spin_unlock(&dlm->spinlock);	return out;}static int debug_state_open(struct inode *inode, struct file *file){	struct dlm_ctxt *dlm = inode->i_private;	struct debug_buffer *db = NULL;	db = debug_buffer_allocate();	if (!db)		goto bail;	db->len = debug_state_print(dlm, db);	file->private_data = db;	return 0;bail:	return -ENOMEM;}static struct file_operations debug_state_fops = {	.open =		debug_state_open,	.release =	debug_buffer_release,	.read =		debug_buffer_read,	.llseek =	debug_buffer_llseek,};/* end  - debug state funcs *//* files in subroot */int dlm_debug_init(struct dlm_ctxt *dlm){	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;	/* for dumping dlm_ctxt */	dc->debug_state_dentry = debugfs_create_file(DLM_DEBUGFS_DLM_STATE,						     S_IFREG|S_IRUSR,						     dlm->dlm_debugfs_subroot,						     dlm, &debug_state_fops);	if (!dc->debug_state_dentry) {		mlog_errno(-ENOMEM);		goto bail;	}	/* for dumping lockres */	dc->debug_lockres_dentry =			debugfs_create_file(DLM_DEBUGFS_LOCKING_STATE,					    S_IFREG|S_IRUSR,					    dlm->dlm_debugfs_subroot,					    dlm, &debug_lockres_fops);	if (!dc->debug_lockres_dentry) {		mlog_errno(-ENOMEM);		goto bail;	}	/* for dumping mles */	dc->debug_mle_dentry = debugfs_create_file(DLM_DEBUGFS_MLE_STATE,						   S_IFREG|S_IRUSR,						   dlm->dlm_debugfs_subroot,						   dlm, &debug_mle_fops);	if (!dc->debug_mle_dentry) {		mlog_errno(-ENOMEM);		goto bail;	}	/* for dumping lockres on the purge list */	dc->debug_purgelist_dentry =			debugfs_create_file(DLM_DEBUGFS_PURGE_LIST,					    S_IFREG|S_IRUSR,					    dlm->dlm_debugfs_subroot,					    dlm, &debug_purgelist_fops);	if (!dc->debug_purgelist_dentry) {		mlog_errno(-ENOMEM);		goto bail;	}	dlm_debug_get(dc);	return 0;bail:	dlm_debug_shutdown(dlm);	return -ENOMEM;}void dlm_debug_shutdown(struct dlm_ctxt *dlm){	struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt;	if (dc) {		if (dc->debug_purgelist_dentry)			debugfs_remove(dc->debug_purgelist_dentry);		if (dc->debug_mle_dentry)			debugfs_remove(dc->debug_mle_dentry);		if (dc->debug_lockres_dentry)			debugfs_remove(dc->debug_lockres_dentry);		if (dc->debug_state_dentry)			debugfs_remove(dc->debug_state_dentry);		dlm_debug_put(dc);	}}/* subroot - domain dir */int dlm_create_debugfs_subroot(struct dlm_ctxt *dlm){	dlm->dlm_debugfs_subroot = debugfs_create_dir(dlm->name,						      dlm_debugfs_root);	if (!dlm->dlm_debugfs_subroot) {		mlog_errno(-ENOMEM);		goto bail;	}	dlm->dlm_debug_ctxt = kzalloc(sizeof(struct dlm_debug_ctxt),				      GFP_KERNEL);	if (!dlm->dlm_debug_ctxt) {		mlog_errno(-ENOMEM);		goto bail;	}	kref_init(&dlm->dlm_debug_ctxt->debug_refcnt);	return 0;bail:	dlm_destroy_debugfs_subroot(dlm);	return -ENOMEM;}void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm){	if (dlm->dlm_debugfs_subroot)		debugfs_remove(dlm->dlm_debugfs_subroot);}/* debugfs root */int dlm_create_debugfs_root(void){	dlm_debugfs_root = debugfs_create_dir(DLM_DEBUGFS_DIR, NULL);	if (!dlm_debugfs_root) {		mlog_errno(-ENOMEM);		return -ENOMEM;	}	return 0;}void dlm_destroy_debugfs_root(void){	if (dlm_debugfs_root)		debugfs_remove(dlm_debugfs_root);}#endif	/* CONFIG_DEBUG_FS */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?