📄 nodemanager.c
字号:
*val = tmp; return count;}static ssize_t o2nm_cluster_attr_idle_timeout_ms_read( struct o2nm_cluster *cluster, char *page){ return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms);}static ssize_t o2nm_cluster_attr_idle_timeout_ms_write( struct o2nm_cluster *cluster, const char *page, size_t count){ ssize_t ret; unsigned int val; ret = o2nm_cluster_attr_write(page, count, &val); if (ret > 0) { if (cluster->cl_idle_timeout_ms != val && o2net_num_connected_peers()) { mlog(ML_NOTICE, "o2net: cannot change idle timeout after " "the first peer has agreed to it." " %d connected peers\n", o2net_num_connected_peers()); ret = -EINVAL; } else if (val <= cluster->cl_keepalive_delay_ms) { mlog(ML_NOTICE, "o2net: idle timeout must be larger " "than keepalive delay\n"); ret = -EINVAL; } else { cluster->cl_idle_timeout_ms = val; } } return ret;}static ssize_t o2nm_cluster_attr_keepalive_delay_ms_read( struct o2nm_cluster *cluster, char *page){ return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms);}static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write( struct o2nm_cluster *cluster, const char *page, size_t count){ ssize_t ret; unsigned int val; ret = o2nm_cluster_attr_write(page, count, &val); if (ret > 0) { if (cluster->cl_keepalive_delay_ms != val && o2net_num_connected_peers()) { mlog(ML_NOTICE, "o2net: cannot change keepalive delay after" " the first peer has agreed to it." " %d connected peers\n", o2net_num_connected_peers()); ret = -EINVAL; } else if (val >= cluster->cl_idle_timeout_ms) { mlog(ML_NOTICE, "o2net: keepalive delay must be " "smaller than idle timeout\n"); ret = -EINVAL; } else { cluster->cl_keepalive_delay_ms = val; } } return ret;}static ssize_t o2nm_cluster_attr_reconnect_delay_ms_read( struct o2nm_cluster *cluster, char *page){ return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms);}static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write( struct o2nm_cluster *cluster, const char *page, size_t count){ return o2nm_cluster_attr_write(page, count, &cluster->cl_reconnect_delay_ms);}static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "idle_timeout_ms", .ca_mode = S_IRUGO | S_IWUSR }, .show = o2nm_cluster_attr_idle_timeout_ms_read, .store = o2nm_cluster_attr_idle_timeout_ms_write,};static struct o2nm_cluster_attribute o2nm_cluster_attr_keepalive_delay_ms = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "keepalive_delay_ms", .ca_mode = S_IRUGO | S_IWUSR }, .show = o2nm_cluster_attr_keepalive_delay_ms_read, .store = o2nm_cluster_attr_keepalive_delay_ms_write,};static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "reconnect_delay_ms", .ca_mode = S_IRUGO | S_IWUSR }, .show = o2nm_cluster_attr_reconnect_delay_ms_read, .store = o2nm_cluster_attr_reconnect_delay_ms_write,};static struct configfs_attribute *o2nm_cluster_attrs[] = { &o2nm_cluster_attr_idle_timeout_ms.attr, &o2nm_cluster_attr_keepalive_delay_ms.attr, &o2nm_cluster_attr_reconnect_delay_ms.attr, NULL,};static ssize_t o2nm_cluster_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct o2nm_cluster *cluster = to_o2nm_cluster(item); struct o2nm_cluster_attribute *o2nm_cluster_attr = container_of(attr, struct o2nm_cluster_attribute, attr); ssize_t ret = 0; if (o2nm_cluster_attr->show) ret = o2nm_cluster_attr->show(cluster, page); return ret;}static ssize_t o2nm_cluster_store(struct config_item *item, struct configfs_attribute *attr, const char *page, size_t count){ struct o2nm_cluster *cluster = to_o2nm_cluster(item); struct o2nm_cluster_attribute *o2nm_cluster_attr = container_of(attr, struct o2nm_cluster_attribute, attr); ssize_t ret; if (o2nm_cluster_attr->store == NULL) { ret = -EINVAL; goto out; } ret = o2nm_cluster_attr->store(cluster, page, count); if (ret < count) goto out;out: return ret;}static struct config_item *o2nm_node_group_make_item(struct config_group *group, const char *name){ struct o2nm_node *node = NULL; struct config_item *ret = NULL; if (strlen(name) > O2NM_MAX_NAME_LEN) goto out; /* ENAMETOOLONG */ node = kcalloc(1, sizeof(struct o2nm_node), GFP_KERNEL); if (node == NULL) goto out; /* ENOMEM */ strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); spin_lock_init(&node->nd_lock); ret = &node->nd_item;out: if (ret == NULL) kfree(node); return ret;}static void o2nm_node_group_drop_item(struct config_group *group, struct config_item *item){ struct o2nm_node *node = to_o2nm_node(item); struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent); o2net_disconnect_node(node); if (cluster->cl_has_local && (cluster->cl_local_node == node->nd_num)) { cluster->cl_has_local = 0; cluster->cl_local_node = O2NM_INVALID_NODE_NUM; o2net_stop_listening(node); } /* XXX call into net to stop this node from trading messages */ write_lock(&cluster->cl_nodes_lock); /* XXX sloppy */ if (node->nd_ipv4_address) rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree); /* nd_num might be 0 if the node number hasn't been set.. */ if (cluster->cl_nodes[node->nd_num] == node) { cluster->cl_nodes[node->nd_num] = NULL; clear_bit(node->nd_num, cluster->cl_nodes_bitmap); } write_unlock(&cluster->cl_nodes_lock); config_item_put(item);}static struct configfs_group_operations o2nm_node_group_group_ops = { .make_item = o2nm_node_group_make_item, .drop_item = o2nm_node_group_drop_item,};static struct config_item_type o2nm_node_group_type = { .ct_group_ops = &o2nm_node_group_group_ops, .ct_owner = THIS_MODULE,};/* cluster */static void o2nm_cluster_release(struct config_item *item){ struct o2nm_cluster *cluster = to_o2nm_cluster(item); kfree(cluster->cl_group.default_groups); kfree(cluster);}static struct configfs_item_operations o2nm_cluster_item_ops = { .release = o2nm_cluster_release, .show_attribute = o2nm_cluster_show, .store_attribute = o2nm_cluster_store,};static struct config_item_type o2nm_cluster_type = { .ct_item_ops = &o2nm_cluster_item_ops, .ct_attrs = o2nm_cluster_attrs, .ct_owner = THIS_MODULE,};/* cluster set */struct o2nm_cluster_group { struct configfs_subsystem cs_subsys; /* some stuff? */};#if 0static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *group){ return group ? container_of(to_configfs_subsystem(group), struct o2nm_cluster_group, cs_subsys) : NULL;}#endifstatic struct config_group *o2nm_cluster_group_make_group(struct config_group *group, const char *name){ struct o2nm_cluster *cluster = NULL; struct o2nm_node_group *ns = NULL; struct config_group *o2hb_group = NULL, *ret = NULL; void *defs = NULL; /* this runs under the parent dir's i_sem; there can be only * one caller in here at a time */ if (o2nm_single_cluster) goto out; /* ENOSPC */ cluster = kcalloc(1, sizeof(struct o2nm_cluster), GFP_KERNEL); ns = kcalloc(1, sizeof(struct o2nm_node_group), GFP_KERNEL); defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); o2hb_group = o2hb_alloc_hb_set(); if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) goto out; config_group_init_type_name(&cluster->cl_group, name, &o2nm_cluster_type); config_group_init_type_name(&ns->ns_group, "node", &o2nm_node_group_type); cluster->cl_group.default_groups = defs; cluster->cl_group.default_groups[0] = &ns->ns_group; cluster->cl_group.default_groups[1] = o2hb_group; cluster->cl_group.default_groups[2] = NULL; rwlock_init(&cluster->cl_nodes_lock); cluster->cl_node_ip_tree = RB_ROOT; cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT; cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; ret = &cluster->cl_group; o2nm_single_cluster = cluster;out: if (ret == NULL) { kfree(cluster); kfree(ns); o2hb_free_hb_set(o2hb_group); kfree(defs); } return ret;}static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item){ struct o2nm_cluster *cluster = to_o2nm_cluster(item); int i; struct config_item *killme; BUG_ON(o2nm_single_cluster != cluster); o2nm_single_cluster = NULL; for (i = 0; cluster->cl_group.default_groups[i]; i++) { killme = &cluster->cl_group.default_groups[i]->cg_item; cluster->cl_group.default_groups[i] = NULL; config_item_put(killme); } config_item_put(item);}static struct configfs_group_operations o2nm_cluster_group_group_ops = { .make_group = o2nm_cluster_group_make_group, .drop_item = o2nm_cluster_group_drop_item,};static struct config_item_type o2nm_cluster_group_type = { .ct_group_ops = &o2nm_cluster_group_group_ops, .ct_owner = THIS_MODULE,};static struct o2nm_cluster_group o2nm_cluster_group = { .cs_subsys = { .su_group = { .cg_item = { .ci_namebuf = "cluster", .ci_type = &o2nm_cluster_group_type, }, }, },};#define O2NM_PROC_PATH "fs/ocfs2_nodemanager"static struct proc_dir_entry *o2nm_proc;#define O2NM_VERSION_PROC_NAME "interface_revision"#define O2NM_HB_DEAD_THRESHOLD_NAME "hb_dead_threshold"#define O2NM_FENCE_OPTION_NAME "fence_method"static void o2nm_remove_proc(struct proc_dir_entry *parent){ remove_proc_entry(O2NM_VERSION_PROC_NAME, parent); remove_proc_entry(O2NM_HB_DEAD_THRESHOLD_NAME, parent); remove_proc_entry(O2NM_FENCE_OPTION_NAME, parent);}static void __exit exit_o2nm(void){ if (ocfs2_table_header) unregister_sysctl_table(ocfs2_table_header); /* XXX sync with hb callbacks and shut down hb? */ o2net_unregister_hb_callbacks(); configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); o2nm_remove_proc(o2nm_proc); mlog_remove_proc(o2nm_proc); o2net_proc_exit(o2nm_proc); remove_proc_entry(O2NM_PROC_PATH, NULL); o2net_exit();}static int o2nm_proc_write_uint(struct file *file, const char __user *buffer, unsigned long count, void *data){ char buf[32]; char *p = buf; unsigned long tmp; if (count > ARRAY_SIZE(buf) - 1) count = ARRAY_SIZE(buf) - 1; if (copy_from_user(buf, buffer, count)) return -EFAULT; buf[ARRAY_SIZE(buf) - 1] = '\0'; tmp = simple_strtoul(p, &p, 10); if (!p || (*p && (*p != '\n'))) return -EINVAL; *(unsigned int *)data = tmp; return count;}static int o2nm_proc_read_uint(char *page, char **start, off_t off, int count, int *eof, void *data){ int len; unsigned int val = *(unsigned int *)data; len = sprintf(page, "%u\n", val); if (len < 0) return len; if (len <= off + count) *eof = 1; *start = page + off; len -= off; if (len > count) len = count; if (len < 0) len = 0; return len;}static int o2nm_proc_write_threshold(struct file *file, const char __user *buffer, unsigned long count, void *data){ char buf[32]; char *p = buf; unsigned long tmp; if (count > ARRAY_SIZE(buf) - 1) count = ARRAY_SIZE(buf) - 1; if (copy_from_user(buf, buffer, count)) return -EFAULT; buf[ARRAY_SIZE(buf) - 1] = '\0'; tmp = simple_strtoul(p, &p, 10); if (!p || (*p && (*p != '\n'))) return -EINVAL; /* this will validate ranges for us. */ o2hb_dead_threshold_set((unsigned int) tmp); return count;}static int o2nm_init_proc(struct proc_dir_entry *parent){ struct proc_dir_entry *p; p = create_proc_entry(O2NM_VERSION_PROC_NAME, S_IFREG | S_IRUGO, parent); if (!p) goto bail1; p->read_proc = o2nm_proc_read_uint; p->data = (void *)&o2nm_api_version; p = create_proc_entry(O2NM_HB_DEAD_THRESHOLD_NAME, S_IFREG | S_IRUGO | S_IWUSR, parent); if (!p) goto bail2; p->write_proc = o2nm_proc_write_threshold; p->read_proc = o2nm_proc_read_uint; p->data = (void *)&o2hb_dead_threshold; p = create_proc_entry(O2NM_FENCE_OPTION_NAME, S_IFREG | S_IRUGO | S_IWUSR, parent); if (!p) goto bail3; p->write_proc = o2nm_proc_write_uint; p->read_proc = o2nm_proc_read_uint; p->data = (void *)&o2quo_fence_option; return 0;bail3: remove_proc_entry(O2NM_HB_DEAD_THRESHOLD_NAME, parent);bail2: remove_proc_entry(O2NM_VERSION_PROC_NAME, parent);bail1: return -ENOMEM;}static int __init init_o2nm(void){ int ret = -1; cluster_print_version(); o2hb_init(); o2net_init(); ocfs2_table_header = register_sysctl_table(ocfs2_root_table, 0); if (!ocfs2_table_header) { printk(KERN_ERR "nodemanager: unable to register sysctl\n"); ret = -ENOMEM; /* or something. */ goto out; } ret = o2net_register_hb_callbacks(); if (ret) goto out_sysctl; config_group_init(&o2nm_cluster_group.cs_subsys.su_group); init_MUTEX(&o2nm_cluster_group.cs_subsys.su_sem); ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys); if (ret) { printk(KERN_ERR "nodemanager: Registration returned %d\n", ret); goto out_callbacks; } o2nm_proc = proc_mkdir(O2NM_PROC_PATH, NULL); if (o2nm_proc == NULL) { ret = -ENOMEM; /* shrug */ goto out_subsys; } ret = mlog_init_proc(o2nm_proc); if (ret) goto out_remove; ret = o2net_proc_init(o2nm_proc); if (ret) goto out_mlog; ret = o2nm_init_proc(o2nm_proc); if (ret == 0) goto out;out_mlog: mlog_remove_proc(o2nm_proc);out_remove: remove_proc_entry(O2NM_PROC_PATH, NULL);out_subsys: configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);out_callbacks: o2net_unregister_hb_callbacks();out_sysctl: unregister_sysctl_table(ocfs2_table_header);out: return ret;}MODULE_AUTHOR("Oracle");MODULE_LICENSE("GPL");module_init(init_o2nm)module_exit(exit_o2nm)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -