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 + -
显示快捷键?