📄 nodemanager.c
字号:
ret = o2net_start_listening(node); if (ret) return ret; } if (!tmp && cluster->cl_has_local && cluster->cl_local_node == node->nd_num) { o2net_stop_listening(node); cluster->cl_local_node = O2NM_INVALID_NODE_NUM; } node->nd_local = tmp; if (node->nd_local) { cluster->cl_has_local = tmp; cluster->cl_local_node = node->nd_num; } return count;}struct o2nm_node_attribute { struct configfs_attribute attr; ssize_t (*show)(struct o2nm_node *, char *); ssize_t (*store)(struct o2nm_node *, const char *, size_t);};static struct o2nm_node_attribute o2nm_node_attr_num = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "num", .ca_mode = S_IRUGO | S_IWUSR }, .show = o2nm_node_num_read, .store = o2nm_node_num_write,};static struct o2nm_node_attribute o2nm_node_attr_ipv4_port = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "ipv4_port", .ca_mode = S_IRUGO | S_IWUSR }, .show = o2nm_node_ipv4_port_read, .store = o2nm_node_ipv4_port_write,};static struct o2nm_node_attribute o2nm_node_attr_ipv4_address = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "ipv4_address", .ca_mode = S_IRUGO | S_IWUSR }, .show = o2nm_node_ipv4_address_read, .store = o2nm_node_ipv4_address_write,};static struct o2nm_node_attribute o2nm_node_attr_local = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "local", .ca_mode = S_IRUGO | S_IWUSR }, .show = o2nm_node_local_read, .store = o2nm_node_local_write,};static struct configfs_attribute *o2nm_node_attrs[] = { [O2NM_NODE_ATTR_NUM] = &o2nm_node_attr_num.attr, [O2NM_NODE_ATTR_PORT] = &o2nm_node_attr_ipv4_port.attr, [O2NM_NODE_ATTR_ADDRESS] = &o2nm_node_attr_ipv4_address.attr, [O2NM_NODE_ATTR_LOCAL] = &o2nm_node_attr_local.attr, NULL,};static int o2nm_attr_index(struct configfs_attribute *attr){ int i; for (i = 0; i < ARRAY_SIZE(o2nm_node_attrs); i++) { if (attr == o2nm_node_attrs[i]) return i; } BUG(); return 0;}static ssize_t o2nm_node_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct o2nm_node *node = to_o2nm_node(item); struct o2nm_node_attribute *o2nm_node_attr = container_of(attr, struct o2nm_node_attribute, attr); ssize_t ret = 0; if (o2nm_node_attr->show) ret = o2nm_node_attr->show(node, page); return ret;}static ssize_t o2nm_node_store(struct config_item *item, struct configfs_attribute *attr, const char *page, size_t count){ struct o2nm_node *node = to_o2nm_node(item); struct o2nm_node_attribute *o2nm_node_attr = container_of(attr, struct o2nm_node_attribute, attr); ssize_t ret; int attr_index = o2nm_attr_index(attr); if (o2nm_node_attr->store == NULL) { ret = -EINVAL; goto out; } if (test_bit(attr_index, &node->nd_set_attributes)) return -EBUSY; ret = o2nm_node_attr->store(node, page, count); if (ret < count) goto out; set_bit(attr_index, &node->nd_set_attributes);out: return ret;}static struct configfs_item_operations o2nm_node_item_ops = { .release = o2nm_node_release, .show_attribute = o2nm_node_show, .store_attribute = o2nm_node_store,};static struct config_item_type o2nm_node_type = { .ct_item_ops = &o2nm_node_item_ops, .ct_attrs = o2nm_node_attrs, .ct_owner = THIS_MODULE,};/* node set */struct o2nm_node_group { struct config_group ns_group; /* some stuff? */};#if 0static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group){ return group ? container_of(group, struct o2nm_node_group, ns_group) : NULL;}#endifstatic 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,};static struct config_item_type o2nm_cluster_type = { .ct_item_ops = &o2nm_cluster_item_ops, .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_mutex; 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; 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, }, }, },};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); o2cb_sys_shutdown(); o2net_exit();}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_o2net; } 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; } ret = o2cb_sys_init(); if (!ret) goto out; configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);out_callbacks: o2net_unregister_hb_callbacks();out_sysctl: unregister_sysctl_table(ocfs2_table_header);out_o2net: o2net_exit();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 + -