Commit 3ba169cc authored by Sunil Mushran's avatar Sunil Mushran

ocfs2/cluster: Add new function o2net_fill_node_map()

Patch adds function o2net_fill_node_map() to return the bitmap of nodes that
it is connected to. This bitmap is also accessible by the user via the debugfs
file, /sys/kernel/debug/o2net/connected_nodes.
Signed-off-by: default avatarSunil Mushran <sunil.mushran@oracle.com>
parent bb570a5d
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#define SC_DEBUG_NAME "sock_containers" #define SC_DEBUG_NAME "sock_containers"
#define NST_DEBUG_NAME "send_tracking" #define NST_DEBUG_NAME "send_tracking"
#define STATS_DEBUG_NAME "stats" #define STATS_DEBUG_NAME "stats"
#define NODES_DEBUG_NAME "connected_nodes"
#define SHOW_SOCK_CONTAINERS 0 #define SHOW_SOCK_CONTAINERS 0
#define SHOW_SOCK_STATS 1 #define SHOW_SOCK_STATS 1
...@@ -55,6 +56,7 @@ static struct dentry *o2net_dentry; ...@@ -55,6 +56,7 @@ static struct dentry *o2net_dentry;
static struct dentry *sc_dentry; static struct dentry *sc_dentry;
static struct dentry *nst_dentry; static struct dentry *nst_dentry;
static struct dentry *stats_dentry; static struct dentry *stats_dentry;
static struct dentry *nodes_dentry;
static DEFINE_SPINLOCK(o2net_debug_lock); static DEFINE_SPINLOCK(o2net_debug_lock);
...@@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = { ...@@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = {
.release = sc_fop_release, .release = sc_fop_release,
}; };
int o2net_debugfs_init(void) static int o2net_fill_bitmap(char *buf, int len)
{ {
o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL); unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
if (!o2net_dentry) { int i = -1, out = 0;
mlog_errno(-ENOMEM);
goto bail;
}
nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR, o2net_fill_node_map(map, sizeof(map));
o2net_dentry, NULL,
&nst_seq_fops);
if (!nst_dentry) {
mlog_errno(-ENOMEM);
goto bail;
}
sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR, while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
o2net_dentry, NULL, out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
&sc_seq_fops); out += snprintf(buf + out, PAGE_SIZE - out, "\n");
if (!sc_dentry) {
mlog_errno(-ENOMEM);
goto bail;
}
stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR, return out;
o2net_dentry, NULL, }
&stats_seq_fops);
if (!stats_dentry) { static int nodes_fop_open(struct inode *inode, struct file *file)
mlog_errno(-ENOMEM); {
goto bail; char *buf;
}
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE));
file->private_data = buf;
return 0; return 0;
bail:
debugfs_remove(stats_dentry);
debugfs_remove(sc_dentry);
debugfs_remove(nst_dentry);
debugfs_remove(o2net_dentry);
return -ENOMEM;
} }
static int o2net_debug_release(struct inode *inode, struct file *file)
{
kfree(file->private_data);
return 0;
}
static ssize_t o2net_debug_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
{
return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
i_size_read(file->f_mapping->host));
}
static const struct file_operations nodes_fops = {
.open = nodes_fop_open,
.release = o2net_debug_release,
.read = o2net_debug_read,
.llseek = generic_file_llseek,
};
void o2net_debugfs_exit(void) void o2net_debugfs_exit(void)
{ {
debugfs_remove(nodes_dentry);
debugfs_remove(stats_dentry); debugfs_remove(stats_dentry);
debugfs_remove(sc_dentry); debugfs_remove(sc_dentry);
debugfs_remove(nst_dentry); debugfs_remove(nst_dentry);
debugfs_remove(o2net_dentry); debugfs_remove(o2net_dentry);
} }
int o2net_debugfs_init(void)
{
mode_t mode = S_IFREG|S_IRUSR;
o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
if (o2net_dentry)
nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode,
o2net_dentry, NULL, &nst_seq_fops);
if (nst_dentry)
sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode,
o2net_dentry, NULL, &sc_seq_fops);
if (sc_dentry)
stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode,
o2net_dentry, NULL, &stats_seq_fops);
if (stats_dentry)
nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode,
o2net_dentry, NULL, &nodes_fops);
if (nodes_dentry)
return 0;
o2net_debugfs_exit();
mlog_errno(-ENOMEM);
return -ENOMEM;
}
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */
...@@ -1034,6 +1034,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn, ...@@ -1034,6 +1034,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn,
return ret; return ret;
} }
/* Get a map of all nodes to which this node is currently connected to */
void o2net_fill_node_map(unsigned long *map, unsigned bytes)
{
struct o2net_sock_container *sc;
int node, ret;
BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long)));
memset(map, 0, bytes);
for (node = 0; node < O2NM_MAX_NODES; ++node) {
o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret);
if (!ret) {
set_bit(node, map);
sc_put(sc);
}
}
}
EXPORT_SYMBOL_GPL(o2net_fill_node_map);
int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
size_t caller_veclen, u8 target_node, int *status) size_t caller_veclen, u8 target_node, int *status)
{ {
......
...@@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, ...@@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
struct list_head *unreg_list); struct list_head *unreg_list);
void o2net_unregister_handler_list(struct list_head *list); void o2net_unregister_handler_list(struct list_head *list);
void o2net_fill_node_map(unsigned long *map, unsigned bytes);
struct o2nm_node; struct o2nm_node;
int o2net_register_hb_callbacks(void); int o2net_register_hb_callbacks(void);
void o2net_unregister_hb_callbacks(void); void o2net_unregister_hb_callbacks(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment