Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
0004  */
0005 
0006 #include <linux/slab.h>
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/configfs.h>
0010 
0011 #include "tcp.h"
0012 #include "nodemanager.h"
0013 #include "heartbeat.h"
0014 #include "masklog.h"
0015 #include "sys.h"
0016 
0017 /* for now we operate under the assertion that there can be only one
0018  * cluster active at a time.  Changing this will require trickling
0019  * cluster references throughout where nodes are looked up */
0020 struct o2nm_cluster *o2nm_single_cluster = NULL;
0021 
0022 static const char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = {
0023     "reset",    /* O2NM_FENCE_RESET */
0024     "panic",    /* O2NM_FENCE_PANIC */
0025 };
0026 
0027 static inline void o2nm_lock_subsystem(void);
0028 static inline void o2nm_unlock_subsystem(void);
0029 
0030 struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
0031 {
0032     struct o2nm_node *node = NULL;
0033 
0034     if (node_num >= O2NM_MAX_NODES || o2nm_single_cluster == NULL)
0035         goto out;
0036 
0037     read_lock(&o2nm_single_cluster->cl_nodes_lock);
0038     node = o2nm_single_cluster->cl_nodes[node_num];
0039     if (node)
0040         config_item_get(&node->nd_item);
0041     read_unlock(&o2nm_single_cluster->cl_nodes_lock);
0042 out:
0043     return node;
0044 }
0045 EXPORT_SYMBOL_GPL(o2nm_get_node_by_num);
0046 
0047 int o2nm_configured_node_map(unsigned long *map, unsigned bytes)
0048 {
0049     struct o2nm_cluster *cluster = o2nm_single_cluster;
0050 
0051     BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap)));
0052 
0053     if (cluster == NULL)
0054         return -EINVAL;
0055 
0056     read_lock(&cluster->cl_nodes_lock);
0057     memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap));
0058     read_unlock(&cluster->cl_nodes_lock);
0059 
0060     return 0;
0061 }
0062 EXPORT_SYMBOL_GPL(o2nm_configured_node_map);
0063 
0064 static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster,
0065                           __be32 ip_needle,
0066                           struct rb_node ***ret_p,
0067                           struct rb_node **ret_parent)
0068 {
0069     struct rb_node **p = &cluster->cl_node_ip_tree.rb_node;
0070     struct rb_node *parent = NULL;
0071     struct o2nm_node *node, *ret = NULL;
0072 
0073     while (*p) {
0074         int cmp;
0075 
0076         parent = *p;
0077         node = rb_entry(parent, struct o2nm_node, nd_ip_node);
0078 
0079         cmp = memcmp(&ip_needle, &node->nd_ipv4_address,
0080                 sizeof(ip_needle));
0081         if (cmp < 0)
0082             p = &(*p)->rb_left;
0083         else if (cmp > 0)
0084             p = &(*p)->rb_right;
0085         else {
0086             ret = node;
0087             break;
0088         }
0089     }
0090 
0091     if (ret_p != NULL)
0092         *ret_p = p;
0093     if (ret_parent != NULL)
0094         *ret_parent = parent;
0095 
0096     return ret;
0097 }
0098 
0099 struct o2nm_node *o2nm_get_node_by_ip(__be32 addr)
0100 {
0101     struct o2nm_node *node = NULL;
0102     struct o2nm_cluster *cluster = o2nm_single_cluster;
0103 
0104     if (cluster == NULL)
0105         goto out;
0106 
0107     read_lock(&cluster->cl_nodes_lock);
0108     node = o2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL);
0109     if (node)
0110         config_item_get(&node->nd_item);
0111     read_unlock(&cluster->cl_nodes_lock);
0112 
0113 out:
0114     return node;
0115 }
0116 EXPORT_SYMBOL_GPL(o2nm_get_node_by_ip);
0117 
0118 void o2nm_node_put(struct o2nm_node *node)
0119 {
0120     config_item_put(&node->nd_item);
0121 }
0122 EXPORT_SYMBOL_GPL(o2nm_node_put);
0123 
0124 void o2nm_node_get(struct o2nm_node *node)
0125 {
0126     config_item_get(&node->nd_item);
0127 }
0128 EXPORT_SYMBOL_GPL(o2nm_node_get);
0129 
0130 u8 o2nm_this_node(void)
0131 {
0132     u8 node_num = O2NM_MAX_NODES;
0133 
0134     if (o2nm_single_cluster && o2nm_single_cluster->cl_has_local)
0135         node_num = o2nm_single_cluster->cl_local_node;
0136 
0137     return node_num;
0138 }
0139 EXPORT_SYMBOL_GPL(o2nm_this_node);
0140 
0141 /* node configfs bits */
0142 
0143 static struct o2nm_cluster *to_o2nm_cluster(struct config_item *item)
0144 {
0145     return item ?
0146         container_of(to_config_group(item), struct o2nm_cluster,
0147                  cl_group)
0148         : NULL;
0149 }
0150 
0151 static struct o2nm_node *to_o2nm_node(struct config_item *item)
0152 {
0153     return item ? container_of(item, struct o2nm_node, nd_item) : NULL;
0154 }
0155 
0156 static void o2nm_node_release(struct config_item *item)
0157 {
0158     struct o2nm_node *node = to_o2nm_node(item);
0159     kfree(node);
0160 }
0161 
0162 static ssize_t o2nm_node_num_show(struct config_item *item, char *page)
0163 {
0164     return sprintf(page, "%d\n", to_o2nm_node(item)->nd_num);
0165 }
0166 
0167 static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node)
0168 {
0169     /* through the first node_set .parent
0170      * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */
0171     if (node->nd_item.ci_parent)
0172         return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
0173     else
0174         return NULL;
0175 }
0176 
0177 enum {
0178     O2NM_NODE_ATTR_NUM = 0,
0179     O2NM_NODE_ATTR_PORT,
0180     O2NM_NODE_ATTR_ADDRESS,
0181 };
0182 
0183 static ssize_t o2nm_node_num_store(struct config_item *item, const char *page,
0184                    size_t count)
0185 {
0186     struct o2nm_node *node = to_o2nm_node(item);
0187     struct o2nm_cluster *cluster;
0188     unsigned long tmp;
0189     char *p = (char *)page;
0190     int ret = 0;
0191 
0192     tmp = simple_strtoul(p, &p, 0);
0193     if (!p || (*p && (*p != '\n')))
0194         return -EINVAL;
0195 
0196     if (tmp >= O2NM_MAX_NODES)
0197         return -ERANGE;
0198 
0199     /* once we're in the cl_nodes tree networking can look us up by
0200      * node number and try to use our address and port attributes
0201      * to connect to this node.. make sure that they've been set
0202      * before writing the node attribute? */
0203     if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
0204         !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
0205         return -EINVAL; /* XXX */
0206 
0207     o2nm_lock_subsystem();
0208     cluster = to_o2nm_cluster_from_node(node);
0209     if (!cluster) {
0210         o2nm_unlock_subsystem();
0211         return -EINVAL;
0212     }
0213 
0214     write_lock(&cluster->cl_nodes_lock);
0215     if (cluster->cl_nodes[tmp])
0216         ret = -EEXIST;
0217     else if (test_and_set_bit(O2NM_NODE_ATTR_NUM,
0218             &node->nd_set_attributes))
0219         ret = -EBUSY;
0220     else  {
0221         cluster->cl_nodes[tmp] = node;
0222         node->nd_num = tmp;
0223         set_bit(tmp, cluster->cl_nodes_bitmap);
0224     }
0225     write_unlock(&cluster->cl_nodes_lock);
0226     o2nm_unlock_subsystem();
0227 
0228     if (ret)
0229         return ret;
0230 
0231     return count;
0232 }
0233 static ssize_t o2nm_node_ipv4_port_show(struct config_item *item, char *page)
0234 {
0235     return sprintf(page, "%u\n", ntohs(to_o2nm_node(item)->nd_ipv4_port));
0236 }
0237 
0238 static ssize_t o2nm_node_ipv4_port_store(struct config_item *item,
0239                      const char *page, size_t count)
0240 {
0241     struct o2nm_node *node = to_o2nm_node(item);
0242     unsigned long tmp;
0243     char *p = (char *)page;
0244 
0245     tmp = simple_strtoul(p, &p, 0);
0246     if (!p || (*p && (*p != '\n')))
0247         return -EINVAL;
0248 
0249     if (tmp == 0)
0250         return -EINVAL;
0251     if (tmp >= (u16)-1)
0252         return -ERANGE;
0253 
0254     if (test_and_set_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
0255         return -EBUSY;
0256     node->nd_ipv4_port = htons(tmp);
0257 
0258     return count;
0259 }
0260 
0261 static ssize_t o2nm_node_ipv4_address_show(struct config_item *item, char *page)
0262 {
0263     return sprintf(page, "%pI4\n", &to_o2nm_node(item)->nd_ipv4_address);
0264 }
0265 
0266 static ssize_t o2nm_node_ipv4_address_store(struct config_item *item,
0267                         const char *page,
0268                         size_t count)
0269 {
0270     struct o2nm_node *node = to_o2nm_node(item);
0271     struct o2nm_cluster *cluster;
0272     int ret, i;
0273     struct rb_node **p, *parent;
0274     unsigned int octets[4];
0275     __be32 ipv4_addr = 0;
0276 
0277     ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2],
0278              &octets[1], &octets[0]);
0279     if (ret != 4)
0280         return -EINVAL;
0281 
0282     for (i = 0; i < ARRAY_SIZE(octets); i++) {
0283         if (octets[i] > 255)
0284             return -ERANGE;
0285         be32_add_cpu(&ipv4_addr, octets[i] << (i * 8));
0286     }
0287 
0288     o2nm_lock_subsystem();
0289     cluster = to_o2nm_cluster_from_node(node);
0290     if (!cluster) {
0291         o2nm_unlock_subsystem();
0292         return -EINVAL;
0293     }
0294 
0295     ret = 0;
0296     write_lock(&cluster->cl_nodes_lock);
0297     if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
0298         ret = -EEXIST;
0299     else if (test_and_set_bit(O2NM_NODE_ATTR_ADDRESS,
0300             &node->nd_set_attributes))
0301         ret = -EBUSY;
0302     else {
0303         rb_link_node(&node->nd_ip_node, parent, p);
0304         rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
0305     }
0306     write_unlock(&cluster->cl_nodes_lock);
0307     o2nm_unlock_subsystem();
0308 
0309     if (ret)
0310         return ret;
0311 
0312     memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr));
0313 
0314     return count;
0315 }
0316 
0317 static ssize_t o2nm_node_local_show(struct config_item *item, char *page)
0318 {
0319     return sprintf(page, "%d\n", to_o2nm_node(item)->nd_local);
0320 }
0321 
0322 static ssize_t o2nm_node_local_store(struct config_item *item, const char *page,
0323                      size_t count)
0324 {
0325     struct o2nm_node *node = to_o2nm_node(item);
0326     struct o2nm_cluster *cluster;
0327     unsigned long tmp;
0328     char *p = (char *)page;
0329     ssize_t ret;
0330 
0331     tmp = simple_strtoul(p, &p, 0);
0332     if (!p || (*p && (*p != '\n')))
0333         return -EINVAL;
0334 
0335     tmp = !!tmp; /* boolean of whether this node wants to be local */
0336 
0337     /* setting local turns on networking rx for now so we require having
0338      * set everything else first */
0339     if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
0340         !test_bit(O2NM_NODE_ATTR_NUM, &node->nd_set_attributes) ||
0341         !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
0342         return -EINVAL; /* XXX */
0343 
0344     o2nm_lock_subsystem();
0345     cluster = to_o2nm_cluster_from_node(node);
0346     if (!cluster) {
0347         ret = -EINVAL;
0348         goto out;
0349     }
0350 
0351     /* the only failure case is trying to set a new local node
0352      * when a different one is already set */
0353     if (tmp && tmp == cluster->cl_has_local &&
0354         cluster->cl_local_node != node->nd_num) {
0355         ret = -EBUSY;
0356         goto out;
0357     }
0358 
0359     /* bring up the rx thread if we're setting the new local node. */
0360     if (tmp && !cluster->cl_has_local) {
0361         ret = o2net_start_listening(node);
0362         if (ret)
0363             goto out;
0364     }
0365 
0366     if (!tmp && cluster->cl_has_local &&
0367         cluster->cl_local_node == node->nd_num) {
0368         o2net_stop_listening(node);
0369         cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
0370     }
0371 
0372     node->nd_local = tmp;
0373     if (node->nd_local) {
0374         cluster->cl_has_local = tmp;
0375         cluster->cl_local_node = node->nd_num;
0376     }
0377 
0378     ret = count;
0379 
0380 out:
0381     o2nm_unlock_subsystem();
0382     return ret;
0383 }
0384 
0385 CONFIGFS_ATTR(o2nm_node_, num);
0386 CONFIGFS_ATTR(o2nm_node_, ipv4_port);
0387 CONFIGFS_ATTR(o2nm_node_, ipv4_address);
0388 CONFIGFS_ATTR(o2nm_node_, local);
0389 
0390 static struct configfs_attribute *o2nm_node_attrs[] = {
0391     &o2nm_node_attr_num,
0392     &o2nm_node_attr_ipv4_port,
0393     &o2nm_node_attr_ipv4_address,
0394     &o2nm_node_attr_local,
0395     NULL,
0396 };
0397 
0398 static struct configfs_item_operations o2nm_node_item_ops = {
0399     .release        = o2nm_node_release,
0400 };
0401 
0402 static const struct config_item_type o2nm_node_type = {
0403     .ct_item_ops    = &o2nm_node_item_ops,
0404     .ct_attrs   = o2nm_node_attrs,
0405     .ct_owner   = THIS_MODULE,
0406 };
0407 
0408 /* node set */
0409 
0410 struct o2nm_node_group {
0411     struct config_group ns_group;
0412     /* some stuff? */
0413 };
0414 
0415 #if 0
0416 static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group)
0417 {
0418     return group ?
0419         container_of(group, struct o2nm_node_group, ns_group)
0420         : NULL;
0421 }
0422 #endif
0423 
0424 static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count,
0425                                        unsigned int *val)
0426 {
0427     unsigned long tmp;
0428     char *p = (char *)page;
0429 
0430     tmp = simple_strtoul(p, &p, 0);
0431     if (!p || (*p && (*p != '\n')))
0432         return -EINVAL;
0433 
0434     if (tmp == 0)
0435         return -EINVAL;
0436     if (tmp >= (u32)-1)
0437         return -ERANGE;
0438 
0439     *val = tmp;
0440 
0441     return count;
0442 }
0443 
0444 static ssize_t o2nm_cluster_idle_timeout_ms_show(struct config_item *item,
0445     char *page)
0446 {
0447     return sprintf(page, "%u\n", to_o2nm_cluster(item)->cl_idle_timeout_ms);
0448 }
0449 
0450 static ssize_t o2nm_cluster_idle_timeout_ms_store(struct config_item *item,
0451     const char *page, size_t count)
0452 {
0453     struct o2nm_cluster *cluster = to_o2nm_cluster(item);
0454     ssize_t ret;
0455     unsigned int val;
0456 
0457     ret =  o2nm_cluster_attr_write(page, count, &val);
0458 
0459     if (ret > 0) {
0460         if (cluster->cl_idle_timeout_ms != val
0461             && o2net_num_connected_peers()) {
0462             mlog(ML_NOTICE,
0463                  "o2net: cannot change idle timeout after "
0464                  "the first peer has agreed to it."
0465                  "  %d connected peers\n",
0466                  o2net_num_connected_peers());
0467             ret = -EINVAL;
0468         } else if (val <= cluster->cl_keepalive_delay_ms) {
0469             mlog(ML_NOTICE, "o2net: idle timeout must be larger "
0470                  "than keepalive delay\n");
0471             ret = -EINVAL;
0472         } else {
0473             cluster->cl_idle_timeout_ms = val;
0474         }
0475     }
0476 
0477     return ret;
0478 }
0479 
0480 static ssize_t o2nm_cluster_keepalive_delay_ms_show(
0481     struct config_item *item, char *page)
0482 {
0483     return sprintf(page, "%u\n",
0484             to_o2nm_cluster(item)->cl_keepalive_delay_ms);
0485 }
0486 
0487 static ssize_t o2nm_cluster_keepalive_delay_ms_store(
0488     struct config_item *item, const char *page, size_t count)
0489 {
0490     struct o2nm_cluster *cluster = to_o2nm_cluster(item);
0491     ssize_t ret;
0492     unsigned int val;
0493 
0494     ret =  o2nm_cluster_attr_write(page, count, &val);
0495 
0496     if (ret > 0) {
0497         if (cluster->cl_keepalive_delay_ms != val
0498             && o2net_num_connected_peers()) {
0499             mlog(ML_NOTICE,
0500                  "o2net: cannot change keepalive delay after"
0501                  " the first peer has agreed to it."
0502                  "  %d connected peers\n",
0503                  o2net_num_connected_peers());
0504             ret = -EINVAL;
0505         } else if (val >= cluster->cl_idle_timeout_ms) {
0506             mlog(ML_NOTICE, "o2net: keepalive delay must be "
0507                  "smaller than idle timeout\n");
0508             ret = -EINVAL;
0509         } else {
0510             cluster->cl_keepalive_delay_ms = val;
0511         }
0512     }
0513 
0514     return ret;
0515 }
0516 
0517 static ssize_t o2nm_cluster_reconnect_delay_ms_show(
0518     struct config_item *item, char *page)
0519 {
0520     return sprintf(page, "%u\n",
0521             to_o2nm_cluster(item)->cl_reconnect_delay_ms);
0522 }
0523 
0524 static ssize_t o2nm_cluster_reconnect_delay_ms_store(
0525     struct config_item *item, const char *page, size_t count)
0526 {
0527     return o2nm_cluster_attr_write(page, count,
0528                                &to_o2nm_cluster(item)->cl_reconnect_delay_ms);
0529 }
0530 
0531 static ssize_t o2nm_cluster_fence_method_show(
0532     struct config_item *item, char *page)
0533 {
0534     struct o2nm_cluster *cluster = to_o2nm_cluster(item);
0535     ssize_t ret = 0;
0536 
0537     if (cluster)
0538         ret = sprintf(page, "%s\n",
0539                   o2nm_fence_method_desc[cluster->cl_fence_method]);
0540     return ret;
0541 }
0542 
0543 static ssize_t o2nm_cluster_fence_method_store(
0544     struct config_item *item, const char *page, size_t count)
0545 {
0546     unsigned int i;
0547 
0548     if (page[count - 1] != '\n')
0549         goto bail;
0550 
0551     for (i = 0; i < O2NM_FENCE_METHODS; ++i) {
0552         if (count != strlen(o2nm_fence_method_desc[i]) + 1)
0553             continue;
0554         if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1))
0555             continue;
0556         if (to_o2nm_cluster(item)->cl_fence_method != i) {
0557             printk(KERN_INFO "ocfs2: Changing fence method to %s\n",
0558                    o2nm_fence_method_desc[i]);
0559             to_o2nm_cluster(item)->cl_fence_method = i;
0560         }
0561         return count;
0562     }
0563 
0564 bail:
0565     return -EINVAL;
0566 }
0567 
0568 CONFIGFS_ATTR(o2nm_cluster_, idle_timeout_ms);
0569 CONFIGFS_ATTR(o2nm_cluster_, keepalive_delay_ms);
0570 CONFIGFS_ATTR(o2nm_cluster_, reconnect_delay_ms);
0571 CONFIGFS_ATTR(o2nm_cluster_, fence_method);
0572 
0573 static struct configfs_attribute *o2nm_cluster_attrs[] = {
0574     &o2nm_cluster_attr_idle_timeout_ms,
0575     &o2nm_cluster_attr_keepalive_delay_ms,
0576     &o2nm_cluster_attr_reconnect_delay_ms,
0577     &o2nm_cluster_attr_fence_method,
0578     NULL,
0579 };
0580 
0581 static struct config_item *o2nm_node_group_make_item(struct config_group *group,
0582                              const char *name)
0583 {
0584     struct o2nm_node *node = NULL;
0585 
0586     if (strlen(name) > O2NM_MAX_NAME_LEN)
0587         return ERR_PTR(-ENAMETOOLONG);
0588 
0589     node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
0590     if (node == NULL)
0591         return ERR_PTR(-ENOMEM);
0592 
0593     strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
0594     config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
0595     spin_lock_init(&node->nd_lock);
0596 
0597     mlog(ML_CLUSTER, "o2nm: Registering node %s\n", name);
0598 
0599     return &node->nd_item;
0600 }
0601 
0602 static void o2nm_node_group_drop_item(struct config_group *group,
0603                       struct config_item *item)
0604 {
0605     struct o2nm_node *node = to_o2nm_node(item);
0606     struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent);
0607 
0608     if (cluster->cl_nodes[node->nd_num] == node) {
0609         o2net_disconnect_node(node);
0610 
0611         if (cluster->cl_has_local &&
0612             (cluster->cl_local_node == node->nd_num)) {
0613             cluster->cl_has_local = 0;
0614             cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
0615             o2net_stop_listening(node);
0616         }
0617     }
0618 
0619     /* XXX call into net to stop this node from trading messages */
0620 
0621     write_lock(&cluster->cl_nodes_lock);
0622 
0623     /* XXX sloppy */
0624     if (node->nd_ipv4_address)
0625         rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree);
0626 
0627     /* nd_num might be 0 if the node number hasn't been set.. */
0628     if (cluster->cl_nodes[node->nd_num] == node) {
0629         cluster->cl_nodes[node->nd_num] = NULL;
0630         clear_bit(node->nd_num, cluster->cl_nodes_bitmap);
0631     }
0632     write_unlock(&cluster->cl_nodes_lock);
0633 
0634     mlog(ML_CLUSTER, "o2nm: Unregistered node %s\n",
0635          config_item_name(&node->nd_item));
0636 
0637     config_item_put(item);
0638 }
0639 
0640 static struct configfs_group_operations o2nm_node_group_group_ops = {
0641     .make_item  = o2nm_node_group_make_item,
0642     .drop_item  = o2nm_node_group_drop_item,
0643 };
0644 
0645 static const struct config_item_type o2nm_node_group_type = {
0646     .ct_group_ops   = &o2nm_node_group_group_ops,
0647     .ct_owner   = THIS_MODULE,
0648 };
0649 
0650 /* cluster */
0651 
0652 static void o2nm_cluster_release(struct config_item *item)
0653 {
0654     struct o2nm_cluster *cluster = to_o2nm_cluster(item);
0655 
0656     kfree(cluster);
0657 }
0658 
0659 static struct configfs_item_operations o2nm_cluster_item_ops = {
0660     .release    = o2nm_cluster_release,
0661 };
0662 
0663 static const struct config_item_type o2nm_cluster_type = {
0664     .ct_item_ops    = &o2nm_cluster_item_ops,
0665     .ct_attrs   = o2nm_cluster_attrs,
0666     .ct_owner   = THIS_MODULE,
0667 };
0668 
0669 /* cluster set */
0670 
0671 struct o2nm_cluster_group {
0672     struct configfs_subsystem cs_subsys;
0673     /* some stuff? */
0674 };
0675 
0676 #if 0
0677 static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *group)
0678 {
0679     return group ?
0680         container_of(to_configfs_subsystem(group), struct o2nm_cluster_group, cs_subsys)
0681            : NULL;
0682 }
0683 #endif
0684 
0685 static struct config_group *o2nm_cluster_group_make_group(struct config_group *group,
0686                               const char *name)
0687 {
0688     struct o2nm_cluster *cluster = NULL;
0689     struct o2nm_node_group *ns = NULL;
0690     struct config_group *o2hb_group = NULL, *ret = NULL;
0691 
0692     /* this runs under the parent dir's i_rwsem; there can be only
0693      * one caller in here at a time */
0694     if (o2nm_single_cluster)
0695         return ERR_PTR(-ENOSPC);
0696 
0697     cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
0698     ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
0699     o2hb_group = o2hb_alloc_hb_set();
0700     if (cluster == NULL || ns == NULL || o2hb_group == NULL)
0701         goto out;
0702 
0703     config_group_init_type_name(&cluster->cl_group, name,
0704                     &o2nm_cluster_type);
0705     configfs_add_default_group(&ns->ns_group, &cluster->cl_group);
0706 
0707     config_group_init_type_name(&ns->ns_group, "node",
0708                     &o2nm_node_group_type);
0709     configfs_add_default_group(o2hb_group, &cluster->cl_group);
0710 
0711     rwlock_init(&cluster->cl_nodes_lock);
0712     cluster->cl_node_ip_tree = RB_ROOT;
0713     cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT;
0714     cluster->cl_idle_timeout_ms    = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
0715     cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
0716     cluster->cl_fence_method       = O2NM_FENCE_RESET;
0717 
0718     ret = &cluster->cl_group;
0719     o2nm_single_cluster = cluster;
0720 
0721 out:
0722     if (ret == NULL) {
0723         kfree(cluster);
0724         kfree(ns);
0725         o2hb_free_hb_set(o2hb_group);
0726         ret = ERR_PTR(-ENOMEM);
0727     }
0728 
0729     return ret;
0730 }
0731 
0732 static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item)
0733 {
0734     struct o2nm_cluster *cluster = to_o2nm_cluster(item);
0735 
0736     BUG_ON(o2nm_single_cluster != cluster);
0737     o2nm_single_cluster = NULL;
0738 
0739     configfs_remove_default_groups(&cluster->cl_group);
0740     config_item_put(item);
0741 }
0742 
0743 static struct configfs_group_operations o2nm_cluster_group_group_ops = {
0744     .make_group = o2nm_cluster_group_make_group,
0745     .drop_item  = o2nm_cluster_group_drop_item,
0746 };
0747 
0748 static const struct config_item_type o2nm_cluster_group_type = {
0749     .ct_group_ops   = &o2nm_cluster_group_group_ops,
0750     .ct_owner   = THIS_MODULE,
0751 };
0752 
0753 static struct o2nm_cluster_group o2nm_cluster_group = {
0754     .cs_subsys = {
0755         .su_group = {
0756             .cg_item = {
0757                 .ci_namebuf = "cluster",
0758                 .ci_type = &o2nm_cluster_group_type,
0759             },
0760         },
0761     },
0762 };
0763 
0764 static inline void o2nm_lock_subsystem(void)
0765 {
0766     mutex_lock(&o2nm_cluster_group.cs_subsys.su_mutex);
0767 }
0768 
0769 static inline void o2nm_unlock_subsystem(void)
0770 {
0771     mutex_unlock(&o2nm_cluster_group.cs_subsys.su_mutex);
0772 }
0773 
0774 int o2nm_depend_item(struct config_item *item)
0775 {
0776     return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item);
0777 }
0778 
0779 void o2nm_undepend_item(struct config_item *item)
0780 {
0781     configfs_undepend_item(item);
0782 }
0783 
0784 int o2nm_depend_this_node(void)
0785 {
0786     int ret = 0;
0787     struct o2nm_node *local_node;
0788 
0789     local_node = o2nm_get_node_by_num(o2nm_this_node());
0790     if (!local_node) {
0791         ret = -EINVAL;
0792         goto out;
0793     }
0794 
0795     ret = o2nm_depend_item(&local_node->nd_item);
0796     o2nm_node_put(local_node);
0797 
0798 out:
0799     return ret;
0800 }
0801 
0802 void o2nm_undepend_this_node(void)
0803 {
0804     struct o2nm_node *local_node;
0805 
0806     local_node = o2nm_get_node_by_num(o2nm_this_node());
0807     BUG_ON(!local_node);
0808 
0809     o2nm_undepend_item(&local_node->nd_item);
0810     o2nm_node_put(local_node);
0811 }
0812 
0813 
0814 static void __exit exit_o2nm(void)
0815 {
0816     /* XXX sync with hb callbacks and shut down hb? */
0817     o2net_unregister_hb_callbacks();
0818     configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
0819     o2cb_sys_shutdown();
0820 
0821     o2net_exit();
0822     o2hb_exit();
0823 }
0824 
0825 static int __init init_o2nm(void)
0826 {
0827     int ret;
0828 
0829     o2hb_init();
0830 
0831     ret = o2net_init();
0832     if (ret)
0833         goto out_o2hb;
0834 
0835     ret = o2net_register_hb_callbacks();
0836     if (ret)
0837         goto out_o2net;
0838 
0839     config_group_init(&o2nm_cluster_group.cs_subsys.su_group);
0840     mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex);
0841     ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys);
0842     if (ret) {
0843         printk(KERN_ERR "nodemanager: Registration returned %d\n", ret);
0844         goto out_callbacks;
0845     }
0846 
0847     ret = o2cb_sys_init();
0848     if (!ret)
0849         goto out;
0850 
0851     configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
0852 out_callbacks:
0853     o2net_unregister_hb_callbacks();
0854 out_o2net:
0855     o2net_exit();
0856 out_o2hb:
0857     o2hb_exit();
0858 out:
0859     return ret;
0860 }
0861 
0862 MODULE_AUTHOR("Oracle");
0863 MODULE_LICENSE("GPL");
0864 MODULE_DESCRIPTION("OCFS2 cluster management");
0865 
0866 module_init(init_o2nm)
0867 module_exit(exit_o2nm)