diff options
| author | Sunil Mushran <sunil.mushran@oracle.com> | 2011-07-24 13:32:54 -0400 |
|---|---|---|
| committer | Sunil Mushran <sunil.mushran@oracle.com> | 2011-07-24 13:32:54 -0400 |
| commit | 3ba169ccec1c5ad0f678e04fd29b990197fdfe79 (patch) | |
| tree | 44aa0576afaf198a717e12b0450f45619e2c5cc4 | |
| parent | bb570a5d9e74f71d32751823052db4a97d6a5e7c (diff) | |
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: Sunil Mushran <sunil.mushran@oracle.com>
| -rw-r--r-- | fs/ocfs2/cluster/netdebug.c | 102 | ||||
| -rw-r--r-- | fs/ocfs2/cluster/tcp.c | 19 | ||||
| -rw-r--r-- | fs/ocfs2/cluster/tcp.h | 2 |
3 files changed, 90 insertions, 33 deletions
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 3a5835904b3d..dc45deb19e68 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #define SC_DEBUG_NAME "sock_containers" | 47 | #define SC_DEBUG_NAME "sock_containers" |
| 48 | #define NST_DEBUG_NAME "send_tracking" | 48 | #define NST_DEBUG_NAME "send_tracking" |
| 49 | #define STATS_DEBUG_NAME "stats" | 49 | #define STATS_DEBUG_NAME "stats" |
| 50 | #define NODES_DEBUG_NAME "connected_nodes" | ||
| 50 | 51 | ||
| 51 | #define SHOW_SOCK_CONTAINERS 0 | 52 | #define SHOW_SOCK_CONTAINERS 0 |
| 52 | #define SHOW_SOCK_STATS 1 | 53 | #define SHOW_SOCK_STATS 1 |
| @@ -55,6 +56,7 @@ static struct dentry *o2net_dentry; | |||
| 55 | static struct dentry *sc_dentry; | 56 | static struct dentry *sc_dentry; |
| 56 | static struct dentry *nst_dentry; | 57 | static struct dentry *nst_dentry; |
| 57 | static struct dentry *stats_dentry; | 58 | static struct dentry *stats_dentry; |
| 59 | static struct dentry *nodes_dentry; | ||
| 58 | 60 | ||
| 59 | static DEFINE_SPINLOCK(o2net_debug_lock); | 61 | static DEFINE_SPINLOCK(o2net_debug_lock); |
| 60 | 62 | ||
| @@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = { | |||
| 491 | .release = sc_fop_release, | 493 | .release = sc_fop_release, |
| 492 | }; | 494 | }; |
| 493 | 495 | ||
| 494 | int o2net_debugfs_init(void) | 496 | static int o2net_fill_bitmap(char *buf, int len) |
| 495 | { | 497 | { |
| 496 | o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL); | 498 | unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; |
| 497 | if (!o2net_dentry) { | 499 | int i = -1, out = 0; |
| 498 | mlog_errno(-ENOMEM); | ||
| 499 | goto bail; | ||
| 500 | } | ||
| 501 | 500 | ||
| 502 | nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR, | 501 | o2net_fill_node_map(map, sizeof(map)); |
| 503 | o2net_dentry, NULL, | ||
| 504 | &nst_seq_fops); | ||
| 505 | if (!nst_dentry) { | ||
| 506 | mlog_errno(-ENOMEM); | ||
| 507 | goto bail; | ||
| 508 | } | ||
| 509 | 502 | ||
| 510 | sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR, | 503 | while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) |
| 511 | o2net_dentry, NULL, | 504 | out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); |
| 512 | &sc_seq_fops); | 505 | out += snprintf(buf + out, PAGE_SIZE - out, "\n"); |
| 513 | if (!sc_dentry) { | ||
| 514 | mlog_errno(-ENOMEM); | ||
| 515 | goto bail; | ||
| 516 | } | ||
| 517 | 506 | ||
| 518 | stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR, | 507 | return out; |
| 519 | o2net_dentry, NULL, | 508 | } |
| 520 | &stats_seq_fops); | 509 | |
| 521 | if (!stats_dentry) { | 510 | static int nodes_fop_open(struct inode *inode, struct file *file) |
| 522 | mlog_errno(-ENOMEM); | 511 | { |
| 523 | goto bail; | 512 | char *buf; |
| 524 | } | 513 | |
| 514 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
| 515 | if (!buf) | ||
| 516 | return -ENOMEM; | ||
| 517 | |||
| 518 | i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE)); | ||
| 519 | |||
| 520 | file->private_data = buf; | ||
| 525 | 521 | ||
| 526 | return 0; | 522 | return 0; |
| 527 | bail: | ||
| 528 | debugfs_remove(stats_dentry); | ||
| 529 | debugfs_remove(sc_dentry); | ||
| 530 | debugfs_remove(nst_dentry); | ||
| 531 | debugfs_remove(o2net_dentry); | ||
| 532 | return -ENOMEM; | ||
| 533 | } | 523 | } |
| 534 | 524 | ||
| 525 | static int o2net_debug_release(struct inode *inode, struct file *file) | ||
| 526 | { | ||
| 527 | kfree(file->private_data); | ||
| 528 | return 0; | ||
| 529 | } | ||
| 530 | |||
| 531 | static ssize_t o2net_debug_read(struct file *file, char __user *buf, | ||
| 532 | size_t nbytes, loff_t *ppos) | ||
| 533 | { | ||
| 534 | return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, | ||
| 535 | i_size_read(file->f_mapping->host)); | ||
| 536 | } | ||
| 537 | |||
| 538 | static const struct file_operations nodes_fops = { | ||
| 539 | .open = nodes_fop_open, | ||
| 540 | .release = o2net_debug_release, | ||
| 541 | .read = o2net_debug_read, | ||
| 542 | .llseek = generic_file_llseek, | ||
| 543 | }; | ||
| 544 | |||
| 535 | void o2net_debugfs_exit(void) | 545 | void o2net_debugfs_exit(void) |
| 536 | { | 546 | { |
| 547 | debugfs_remove(nodes_dentry); | ||
| 537 | debugfs_remove(stats_dentry); | 548 | debugfs_remove(stats_dentry); |
| 538 | debugfs_remove(sc_dentry); | 549 | debugfs_remove(sc_dentry); |
| 539 | debugfs_remove(nst_dentry); | 550 | debugfs_remove(nst_dentry); |
| 540 | debugfs_remove(o2net_dentry); | 551 | debugfs_remove(o2net_dentry); |
| 541 | } | 552 | } |
| 542 | 553 | ||
| 554 | int o2net_debugfs_init(void) | ||
| 555 | { | ||
| 556 | mode_t mode = S_IFREG|S_IRUSR; | ||
| 557 | |||
| 558 | o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL); | ||
| 559 | if (o2net_dentry) | ||
| 560 | nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode, | ||
| 561 | o2net_dentry, NULL, &nst_seq_fops); | ||
| 562 | if (nst_dentry) | ||
| 563 | sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode, | ||
| 564 | o2net_dentry, NULL, &sc_seq_fops); | ||
| 565 | if (sc_dentry) | ||
| 566 | stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode, | ||
| 567 | o2net_dentry, NULL, &stats_seq_fops); | ||
| 568 | if (stats_dentry) | ||
| 569 | nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode, | ||
| 570 | o2net_dentry, NULL, &nodes_fops); | ||
| 571 | if (nodes_dentry) | ||
| 572 | return 0; | ||
| 573 | |||
| 574 | o2net_debugfs_exit(); | ||
| 575 | mlog_errno(-ENOMEM); | ||
| 576 | return -ENOMEM; | ||
| 577 | } | ||
| 578 | |||
| 543 | #endif /* CONFIG_DEBUG_FS */ | 579 | #endif /* CONFIG_DEBUG_FS */ |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 6e97895ecf24..ae13d5ca7908 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
| @@ -1034,6 +1034,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn, | |||
| 1034 | return ret; | 1034 | return ret; |
| 1035 | } | 1035 | } |
| 1036 | 1036 | ||
| 1037 | /* Get a map of all nodes to which this node is currently connected to */ | ||
| 1038 | void o2net_fill_node_map(unsigned long *map, unsigned bytes) | ||
| 1039 | { | ||
| 1040 | struct o2net_sock_container *sc; | ||
| 1041 | int node, ret; | ||
| 1042 | |||
| 1043 | BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long))); | ||
| 1044 | |||
| 1045 | memset(map, 0, bytes); | ||
| 1046 | for (node = 0; node < O2NM_MAX_NODES; ++node) { | ||
| 1047 | o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret); | ||
| 1048 | if (!ret) { | ||
| 1049 | set_bit(node, map); | ||
| 1050 | sc_put(sc); | ||
| 1051 | } | ||
| 1052 | } | ||
| 1053 | } | ||
| 1054 | EXPORT_SYMBOL_GPL(o2net_fill_node_map); | ||
| 1055 | |||
| 1037 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, | 1056 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, |
| 1038 | size_t caller_veclen, u8 target_node, int *status) | 1057 | size_t caller_veclen, u8 target_node, int *status) |
| 1039 | { | 1058 | { |
diff --git a/fs/ocfs2/cluster/tcp.h b/fs/ocfs2/cluster/tcp.h index fd6179eb26d4..5bada2a69b50 100644 --- a/fs/ocfs2/cluster/tcp.h +++ b/fs/ocfs2/cluster/tcp.h | |||
| @@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, | |||
| 106 | struct list_head *unreg_list); | 106 | struct list_head *unreg_list); |
| 107 | void o2net_unregister_handler_list(struct list_head *list); | 107 | void o2net_unregister_handler_list(struct list_head *list); |
| 108 | 108 | ||
| 109 | void o2net_fill_node_map(unsigned long *map, unsigned bytes); | ||
| 110 | |||
| 109 | struct o2nm_node; | 111 | struct o2nm_node; |
| 110 | int o2net_register_hb_callbacks(void); | 112 | int o2net_register_hb_callbacks(void); |
| 111 | void o2net_unregister_hb_callbacks(void); | 113 | void o2net_unregister_hb_callbacks(void); |
