linux/fs/ocfs2/cluster/nodemanager.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
   4 */
   5
   6#include <linux/slab.h>
   7#include <linux/kernel.h>
   8#include <linux/module.h>
   9#include <linux/configfs.h>
  10
  11#include "tcp.h"
  12#include "nodemanager.h"
  13#include "heartbeat.h"
  14#include "masklog.h"
  15#include "sys.h"
  16
  17/* for now we operate under the assertion that there can be only one
  18 * cluster active at a time.  Changing this will require trickling
  19 * cluster references throughout where nodes are looked up */
  20struct o2nm_cluster *o2nm_single_cluster = NULL;
  21
  22static const char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = {
  23        "reset",        /* O2NM_FENCE_RESET */
  24        "panic",        /* O2NM_FENCE_PANIC */
  25};
  26
  27static inline void o2nm_lock_subsystem(void);
  28static inline void o2nm_unlock_subsystem(void);
  29
  30struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
  31{
  32        struct o2nm_node *node = NULL;
  33
  34        if (node_num >= O2NM_MAX_NODES || o2nm_single_cluster == NULL)
  35                goto out;
  36
  37        read_lock(&o2nm_single_cluster->cl_nodes_lock);
  38        node = o2nm_single_cluster->cl_nodes[node_num];
  39        if (node)
  40                config_item_get(&node->nd_item);
  41        read_unlock(&o2nm_single_cluster->cl_nodes_lock);
  42out:
  43        return node;
  44}
  45EXPORT_SYMBOL_GPL(o2nm_get_node_by_num);
  46
  47int o2nm_configured_node_map(unsigned long *map, unsigned bytes)
  48{
  49        struct o2nm_cluster *cluster = o2nm_single_cluster;
  50
  51        BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap)));
  52
  53        if (cluster == NULL)
  54                return -EINVAL;
  55
  56        read_lock(&cluster->cl_nodes_lock);
  57        memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap));
  58        read_unlock(&cluster->cl_nodes_lock);
  59
  60        return 0;
  61}
  62EXPORT_SYMBOL_GPL(o2nm_configured_node_map);
  63
  64static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster,
  65                                                  __be32 ip_needle,
  66                                                  struct rb_node ***ret_p,
  67                                                  struct rb_node **ret_parent)
  68{
  69        struct rb_node **p = &cluster->cl_node_ip_tree.rb_node;
  70        struct rb_node *parent = NULL;
  71        struct o2nm_node *node, *ret = NULL;
  72
  73        while (*p) {
  74                int cmp;
  75
  76                parent = *p;
  77                node = rb_entry(parent, struct o2nm_node, nd_ip_node);
  78
  79                cmp = memcmp(&ip_needle, &node->nd_ipv4_address,
  80                                sizeof(ip_needle));
  81                if (cmp < 0)
  82                        p = &(*p)->rb_left;
  83                else if (cmp > 0)
  84                        p = &(*p)->rb_right;
  85                else {
  86                        ret = node;
  87                        break;
  88                }
  89        }
  90
  91        if (ret_p != NULL)
  92                *ret_p = p;
  93        if (ret_parent != NULL)
  94                *ret_parent = parent;
  95
  96        return ret;
  97}
  98
  99struct o2nm_node *o2nm_get_node_by_ip(__be32 addr)
 100{
 101        struct o2nm_node *node = NULL;
 102        struct o2nm_cluster *cluster = o2nm_single_cluster;
 103
 104        if (cluster == NULL)
 105                goto out;
 106
 107        read_lock(&cluster->cl_nodes_lock);
 108        node = o2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL);
 109        if (node)
 110                config_item_get(&node->nd_item);
 111        read_unlock(&cluster->cl_nodes_lock);
 112
 113out:
 114        return node;
 115}
 116EXPORT_SYMBOL_GPL(o2nm_get_node_by_ip);
 117
 118void o2nm_node_put(struct o2nm_node *node)
 119{
 120        config_item_put(&node->nd_item);
 121}
 122EXPORT_SYMBOL_GPL(o2nm_node_put);
 123
 124void o2nm_node_get(struct o2nm_node *node)
 125{
 126        config_item_get(&node->nd_item);
 127}
 128EXPORT_SYMBOL_GPL(o2nm_node_get);
 129
 130u8 o2nm_this_node(void)
 131{
 132        u8 node_num = O2NM_MAX_NODES;
 133
 134        if (o2nm_single_cluster && o2nm_single_cluster->cl_has_local)
 135                node_num = o2nm_single_cluster->cl_local_node;
 136
 137        return node_num;
 138}
 139EXPORT_SYMBOL_GPL(o2nm_this_node);
 140
 141/* node configfs bits */
 142
 143static struct o2nm_cluster *to_o2nm_cluster(struct config_item *item)
 144{
 145        return item ?
 146                container_of(to_config_group(item), struct o2nm_cluster,
 147                             cl_group)
 148                : NULL;
 149}
 150
 151static struct o2nm_node *to_o2nm_node(struct config_item *item)
 152{
 153        return item ? container_of(item, struct o2nm_node, nd_item) : NULL;
 154}
 155
 156static void o2nm_node_release(struct config_item *item)
 157{
 158        struct o2nm_node *node = to_o2nm_node(item);
 159        kfree(node);
 160}
 161
 162static ssize_t o2nm_node_num_show(struct config_item *item, char *page)
 163{
 164        return sprintf(page, "%d\n", to_o2nm_node(item)->nd_num);
 165}
 166
 167static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node)
 168{
 169        /* through the first node_set .parent
 170         * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */
 171        if (node->nd_item.ci_parent)
 172                return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
 173        else
 174                return NULL;
 175}
 176
 177enum {
 178        O2NM_NODE_ATTR_NUM = 0,
 179        O2NM_NODE_ATTR_PORT,
 180        O2NM_NODE_ATTR_ADDRESS,
 181};
 182
 183static ssize_t o2nm_node_num_store(struct config_item *item, const char *page,
 184                                   size_t count)
 185{
 186        struct o2nm_node *node = to_o2nm_node(item);
 187        struct o2nm_cluster *cluster;
 188        unsigned long tmp;
 189        char *p = (char *)page;
 190        int ret = 0;
 191
 192        tmp = simple_strtoul(p, &p, 0);
 193        if (!p || (*p && (*p != '\n')))
 194                return -EINVAL;
 195
 196        if (tmp >= O2NM_MAX_NODES)
 197                return -ERANGE;
 198
 199        /* once we're in the cl_nodes tree networking can look us up by
 200         * node number and try to use our address and port attributes
 201         * to connect to this node.. make sure that they've been set
 202         * before writing the node attribute? */
 203        if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
 204            !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
 205                return -EINVAL; /* XXX */
 206
 207        o2nm_lock_subsystem();
 208        cluster = to_o2nm_cluster_from_node(node);
 209        if (!cluster) {
 210                o2nm_unlock_subsystem();
 211                return -EINVAL;
 212        }
 213
 214        write_lock(&cluster->cl_nodes_lock);
 215        if (cluster->cl_nodes[tmp])
 216                ret = -EEXIST;
 217        else if (test_and_set_bit(O2NM_NODE_ATTR_NUM,
 218                        &node->nd_set_attributes))
 219                ret = -EBUSY;
 220        else  {
 221                cluster->cl_nodes[tmp] = node;
 222                node->nd_num = tmp;
 223                set_bit(tmp, cluster->cl_nodes_bitmap);
 224        }
 225        write_unlock(&cluster->cl_nodes_lock);
 226        o2nm_unlock_subsystem();
 227
 228        if (ret)
 229                return ret;
 230
 231        return count;
 232}
 233static ssize_t o2nm_node_ipv4_port_show(struct config_item *item, char *page)
 234{
 235        return sprintf(page, "%u\n", ntohs(to_o2nm_node(item)->nd_ipv4_port));
 236}
 237
 238static ssize_t o2nm_node_ipv4_port_store(struct config_item *item,
 239                                         const char *page, size_t count)
 240{
 241        struct o2nm_node *node = to_o2nm_node(item);
 242        unsigned long tmp;
 243        char *p = (char *)page;
 244
 245        tmp = simple_strtoul(p, &p, 0);
 246        if (!p || (*p && (*p != '\n')))
 247                return -EINVAL;
 248
 249        if (tmp == 0)
 250                return -EINVAL;
 251        if (tmp >= (u16)-1)
 252                return -ERANGE;
 253
 254        if (test_and_set_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
 255                return -EBUSY;
 256        node->nd_ipv4_port = htons(tmp);
 257
 258        return count;
 259}
 260
 261static ssize_t o2nm_node_ipv4_address_show(struct config_item *item, char *page)
 262{
 263        return sprintf(page, "%pI4\n", &to_o2nm_node(item)->nd_ipv4_address);
 264}
 265
 266static ssize_t o2nm_node_ipv4_address_store(struct config_item *item,
 267                                            const char *page,
 268                                            size_t count)
 269{
 270        struct o2nm_node *node = to_o2nm_node(item);
 271        struct o2nm_cluster *cluster;
 272        int ret, i;
 273        struct rb_node **p, *parent;
 274        unsigned int octets[4];
 275        __be32 ipv4_addr = 0;
 276
 277        ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2],
 278                     &octets[1], &octets[0]);
 279        if (ret != 4)
 280                return -EINVAL;
 281
 282        for (i = 0; i < ARRAY_SIZE(octets); i++) {
 283                if (octets[i] > 255)
 284                        return -ERANGE;
 285                be32_add_cpu(&ipv4_addr, octets[i] << (i * 8));
 286        }
 287
 288        o2nm_lock_subsystem();
 289        cluster = to_o2nm_cluster_from_node(node);
 290        if (!cluster) {
 291                o2nm_unlock_subsystem();
 292                return -EINVAL;
 293        }
 294
 295        ret = 0;
 296        write_lock(&cluster->cl_nodes_lock);
 297        if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
 298                ret = -EEXIST;
 299        else if (test_and_set_bit(O2NM_NODE_ATTR_ADDRESS,
 300                        &node->nd_set_attributes))
 301                ret = -EBUSY;
 302        else {
 303                rb_link_node(&node->nd_ip_node, parent, p);
 304                rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
 305        }
 306        write_unlock(&cluster->cl_nodes_lock);
 307        o2nm_unlock_subsystem();
 308
 309        if (ret)
 310                return ret;
 311
 312        memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr));
 313
 314        return count;
 315}
 316
 317static ssize_t o2nm_node_local_show(struct config_item *item, char *page)
 318{
 319        return sprintf(page, "%d\n", to_o2nm_node(item)->nd_local);
 320}
 321
 322static ssize_t o2nm_node_local_store(struct config_item *item, const char *page,
 323                                     size_t count)
 324{
 325        struct o2nm_node *node = to_o2nm_node(item);
 326        struct o2nm_cluster *cluster;
 327        unsigned long tmp;
 328        char *p = (char *)page;
 329        ssize_t ret;
 330
 331        tmp = simple_strtoul(p, &p, 0);
 332        if (!p || (*p && (*p != '\n')))
 333                return -EINVAL;
 334
 335        tmp = !!tmp; /* boolean of whether this node wants to be local */
 336
 337        /* setting local turns on networking rx for now so we require having
 338         * set everything else first */
 339        if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
 340            !test_bit(O2NM_NODE_ATTR_NUM, &node->nd_set_attributes) ||
 341            !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
 342                return -EINVAL; /* XXX */
 343
 344        o2nm_lock_subsystem();
 345        cluster = to_o2nm_cluster_from_node(node);
 346        if (!cluster) {
 347                ret = -EINVAL;
 348                goto out;
 349        }
 350
 351        /* the only failure case is trying to set a new local node
 352         * when a different one is already set */
 353        if (tmp && tmp == cluster->cl_has_local &&
 354            cluster->cl_local_node != node->nd_num) {
 355                ret = -EBUSY;
 356                goto out;
 357        }
 358
 359        /* bring up the rx thread if we're setting the new local node. */
 360        if (tmp && !cluster->cl_has_local) {
 361                ret = o2net_start_listening(node);
 362                if (ret)
 363                        goto out;
 364        }
 365
 366        if (!tmp && cluster->cl_has_local &&
 367            cluster->cl_local_node == node->nd_num) {
 368                o2net_stop_listening(node);
 369                cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
 370        }
 371
 372        node->nd_local = tmp;
 373        if (node->nd_local) {
 374                cluster->cl_has_local = tmp;
 375                cluster->cl_local_node = node->nd_num;
 376        }
 377
 378        ret = count;
 379
 380out:
 381        o2nm_unlock_subsystem();
 382        return ret;
 383}
 384
 385CONFIGFS_ATTR(o2nm_node_, num);
 386CONFIGFS_ATTR(o2nm_node_, ipv4_port);
 387CONFIGFS_ATTR(o2nm_node_, ipv4_address);
 388CONFIGFS_ATTR(o2nm_node_, local);
 389
 390static struct configfs_attribute *o2nm_node_attrs[] = {
 391        &o2nm_node_attr_num,
 392        &o2nm_node_attr_ipv4_port,
 393        &o2nm_node_attr_ipv4_address,
 394        &o2nm_node_attr_local,
 395        NULL,
 396};
 397
 398static struct configfs_item_operations o2nm_node_item_ops = {
 399        .release                = o2nm_node_release,
 400};
 401
 402static const struct config_item_type o2nm_node_type = {
 403        .ct_item_ops    = &o2nm_node_item_ops,
 404        .ct_attrs       = o2nm_node_attrs,
 405        .ct_owner       = THIS_MODULE,
 406};
 407
 408/* node set */
 409
 410struct o2nm_node_group {
 411        struct config_group ns_group;
 412        /* some stuff? */
 413};
 414
 415#if 0
 416static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group)
 417{
 418        return group ?
 419                container_of(group, struct o2nm_node_group, ns_group)
 420                : NULL;
 421}
 422#endif
 423
 424static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count,
 425                                       unsigned int *val)
 426{
 427        unsigned long tmp;
 428        char *p = (char *)page;
 429
 430        tmp = simple_strtoul(p, &p, 0);
 431        if (!p || (*p && (*p != '\n')))
 432                return -EINVAL;
 433
 434        if (tmp == 0)
 435                return -EINVAL;
 436        if (tmp >= (u32)-1)
 437                return -ERANGE;
 438
 439        *val = tmp;
 440
 441        return count;
 442}
 443
 444static ssize_t o2nm_cluster_idle_timeout_ms_show(struct config_item *item,
 445        char *page)
 446{
 447        return sprintf(page, "%u\n", to_o2nm_cluster(item)->cl_idle_timeout_ms);
 448}
 449
 450static ssize_t o2nm_cluster_idle_timeout_ms_store(struct config_item *item,
 451        const char *page, size_t count)
 452{
 453        struct o2nm_cluster *cluster = to_o2nm_cluster(item);
 454        ssize_t ret;
 455        unsigned int val;
 456
 457        ret =  o2nm_cluster_attr_write(page, count, &val);
 458
 459        if (ret > 0) {
 460                if (cluster->cl_idle_timeout_ms != val
 461                        && o2net_num_connected_peers()) {
 462                        mlog(ML_NOTICE,
 463                             "o2net: cannot change idle timeout after "
 464                             "the first peer has agreed to it."
 465                             "  %d connected peers\n",
 466                             o2net_num_connected_peers());
 467                        ret = -EINVAL;
 468                } else if (val <= cluster->cl_keepalive_delay_ms) {
 469                        mlog(ML_NOTICE, "o2net: idle timeout must be larger "
 470                             "than keepalive delay\n");
 471                        ret = -EINVAL;
 472                } else {
 473                        cluster->cl_idle_timeout_ms = val;
 474                }
 475        }
 476
 477        return ret;
 478}
 479
 480static ssize_t o2nm_cluster_keepalive_delay_ms_show(
 481        struct config_item *item, char *page)
 482{
 483        return sprintf(page, "%u\n",
 484                        to_o2nm_cluster(item)->cl_keepalive_delay_ms);
 485}
 486
 487static ssize_t o2nm_cluster_keepalive_delay_ms_store(
 488        struct config_item *item, const char *page, size_t count)
 489{
 490        struct o2nm_cluster *cluster = to_o2nm_cluster(item);
 491        ssize_t ret;
 492        unsigned int val;
 493
 494        ret =  o2nm_cluster_attr_write(page, count, &val);
 495
 496        if (ret > 0) {
 497                if (cluster->cl_keepalive_delay_ms != val
 498                    && o2net_num_connected_peers()) {
 499                        mlog(ML_NOTICE,
 500                             "o2net: cannot change keepalive delay after"
 501                             " the first peer has agreed to it."
 502                             "  %d connected peers\n",
 503                             o2net_num_connected_peers());
 504                        ret = -EINVAL;
 505                } else if (val >= cluster->cl_idle_timeout_ms) {
 506                        mlog(ML_NOTICE, "o2net: keepalive delay must be "
 507                             "smaller than idle timeout\n");
 508                        ret = -EINVAL;
 509                } else {
 510                        cluster->cl_keepalive_delay_ms = val;
 511                }
 512        }
 513
 514        return ret;
 515}
 516
 517static ssize_t o2nm_cluster_reconnect_delay_ms_show(
 518        struct config_item *item, char *page)
 519{
 520        return sprintf(page, "%u\n",
 521                        to_o2nm_cluster(item)->cl_reconnect_delay_ms);
 522}
 523
 524static ssize_t o2nm_cluster_reconnect_delay_ms_store(
 525        struct config_item *item, const char *page, size_t count)
 526{
 527        return o2nm_cluster_attr_write(page, count,
 528                               &to_o2nm_cluster(item)->cl_reconnect_delay_ms);
 529}
 530
 531static ssize_t o2nm_cluster_fence_method_show(
 532        struct config_item *item, char *page)
 533{
 534        struct o2nm_cluster *cluster = to_o2nm_cluster(item);
 535        ssize_t ret = 0;
 536
 537        if (cluster)
 538                ret = sprintf(page, "%s\n",
 539                              o2nm_fence_method_desc[cluster->cl_fence_method]);
 540        return ret;
 541}
 542
 543static ssize_t o2nm_cluster_fence_method_store(
 544        struct config_item *item, const char *page, size_t count)
 545{
 546        unsigned int i;
 547
 548        if (page[count - 1] != '\n')
 549                goto bail;
 550
 551        for (i = 0; i < O2NM_FENCE_METHODS; ++i) {
 552                if (count != strlen(o2nm_fence_method_desc[i]) + 1)
 553                        continue;
 554                if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1))
 555                        continue;
 556                if (to_o2nm_cluster(item)->cl_fence_method != i) {
 557                        printk(KERN_INFO "ocfs2: Changing fence method to %s\n",
 558                               o2nm_fence_method_desc[i]);
 559                        to_o2nm_cluster(item)->cl_fence_method = i;
 560                }
 561                return count;
 562        }
 563
 564bail:
 565        return -EINVAL;
 566}
 567
 568CONFIGFS_ATTR(o2nm_cluster_, idle_timeout_ms);
 569CONFIGFS_ATTR(o2nm_cluster_, keepalive_delay_ms);
 570CONFIGFS_ATTR(o2nm_cluster_, reconnect_delay_ms);
 571CONFIGFS_ATTR(o2nm_cluster_, fence_method);
 572
 573static struct configfs_attribute *o2nm_cluster_attrs[] = {
 574        &o2nm_cluster_attr_idle_timeout_ms,
 575        &o2nm_cluster_attr_keepalive_delay_ms,
 576        &o2nm_cluster_attr_reconnect_delay_ms,
 577        &o2nm_cluster_attr_fence_method,
 578        NULL,
 579};
 580
 581static struct config_item *o2nm_node_group_make_item(struct config_group *group,
 582                                                     const char *name)
 583{
 584        struct o2nm_node *node = NULL;
 585
 586        if (strlen(name) > O2NM_MAX_NAME_LEN)
 587                return ERR_PTR(-ENAMETOOLONG);
 588
 589        node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
 590        if (node == NULL)
 591                return ERR_PTR(-ENOMEM);
 592
 593        strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
 594        config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
 595        spin_lock_init(&node->nd_lock);
 596
 597        mlog(ML_CLUSTER, "o2nm: Registering node %s\n", name);
 598
 599        return &node->nd_item;
 600}
 601
 602static void o2nm_node_group_drop_item(struct config_group *group,
 603                                      struct config_item *item)
 604{
 605        struct o2nm_node *node = to_o2nm_node(item);
 606        struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent);
 607
 608        if (cluster->cl_nodes[node->nd_num] == node) {
 609                o2net_disconnect_node(node);
 610
 611                if (cluster->cl_has_local &&
 612                    (cluster->cl_local_node == node->nd_num)) {
 613                        cluster->cl_has_local = 0;
 614                        cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
 615                        o2net_stop_listening(node);
 616                }
 617        }
 618
 619        /* XXX call into net to stop this node from trading messages */
 620
 621        write_lock(&cluster->cl_nodes_lock);
 622
 623        /* XXX sloppy */
 624        if (node->nd_ipv4_address)
 625                rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree);
 626
 627        /* nd_num might be 0 if the node number hasn't been set.. */
 628        if (cluster->cl_nodes[node->nd_num] == node) {
 629                cluster->cl_nodes[node->nd_num] = NULL;
 630                clear_bit(node->nd_num, cluster->cl_nodes_bitmap);
 631        }
 632        write_unlock(&cluster->cl_nodes_lock);
 633
 634        mlog(ML_CLUSTER, "o2nm: Unregistered node %s\n",
 635             config_item_name(&node->nd_item));
 636
 637        config_item_put(item);
 638}
 639
 640static struct configfs_group_operations o2nm_node_group_group_ops = {
 641        .make_item      = o2nm_node_group_make_item,
 642        .drop_item      = o2nm_node_group_drop_item,
 643};
 644
 645static const struct config_item_type o2nm_node_group_type = {
 646        .ct_group_ops   = &o2nm_node_group_group_ops,
 647        .ct_owner       = THIS_MODULE,
 648};
 649
 650/* cluster */
 651
 652static void o2nm_cluster_release(struct config_item *item)
 653{
 654        struct o2nm_cluster *cluster = to_o2nm_cluster(item);
 655
 656        kfree(cluster);
 657}
 658
 659static struct configfs_item_operations o2nm_cluster_item_ops = {
 660        .release        = o2nm_cluster_release,
 661};
 662
 663static const struct config_item_type o2nm_cluster_type = {
 664        .ct_item_ops    = &o2nm_cluster_item_ops,
 665        .ct_attrs       = o2nm_cluster_attrs,
 666        .ct_owner       = THIS_MODULE,
 667};
 668
 669/* cluster set */
 670
 671struct o2nm_cluster_group {
 672        struct configfs_subsystem cs_subsys;
 673        /* some stuff? */
 674};
 675
 676#if 0
 677static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *group)
 678{
 679        return group ?
 680                container_of(to_configfs_subsystem(group), struct o2nm_cluster_group, cs_subsys)
 681               : NULL;
 682}
 683#endif
 684
 685static struct config_group *o2nm_cluster_group_make_group(struct config_group *group,
 686                                                          const char *name)
 687{
 688        struct o2nm_cluster *cluster = NULL;
 689        struct o2nm_node_group *ns = NULL;
 690        struct config_group *o2hb_group = NULL, *ret = NULL;
 691
 692        /* this runs under the parent dir's i_mutex; there can be only
 693         * one caller in here at a time */
 694        if (o2nm_single_cluster)
 695                return ERR_PTR(-ENOSPC);
 696
 697        cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
 698        ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
 699        o2hb_group = o2hb_alloc_hb_set();
 700        if (cluster == NULL || ns == NULL || o2hb_group == NULL)
 701                goto out;
 702
 703        config_group_init_type_name(&cluster->cl_group, name,
 704                                    &o2nm_cluster_type);
 705        configfs_add_default_group(&ns->ns_group, &cluster->cl_group);
 706
 707        config_group_init_type_name(&ns->ns_group, "node",
 708                                    &o2nm_node_group_type);
 709        configfs_add_default_group(o2hb_group, &cluster->cl_group);
 710
 711        rwlock_init(&cluster->cl_nodes_lock);
 712        cluster->cl_node_ip_tree = RB_ROOT;
 713        cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT;
 714        cluster->cl_idle_timeout_ms    = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
 715        cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
 716        cluster->cl_fence_method       = O2NM_FENCE_RESET;
 717
 718        ret = &cluster->cl_group;
 719        o2nm_single_cluster = cluster;
 720
 721out:
 722        if (ret == NULL) {
 723                kfree(cluster);
 724                kfree(ns);
 725                o2hb_free_hb_set(o2hb_group);
 726                ret = ERR_PTR(-ENOMEM);
 727        }
 728
 729        return ret;
 730}
 731
 732static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item)
 733{
 734        struct o2nm_cluster *cluster = to_o2nm_cluster(item);
 735
 736        BUG_ON(o2nm_single_cluster != cluster);
 737        o2nm_single_cluster = NULL;
 738
 739        configfs_remove_default_groups(&cluster->cl_group);
 740        config_item_put(item);
 741}
 742
 743static struct configfs_group_operations o2nm_cluster_group_group_ops = {
 744        .make_group     = o2nm_cluster_group_make_group,
 745        .drop_item      = o2nm_cluster_group_drop_item,
 746};
 747
 748static const struct config_item_type o2nm_cluster_group_type = {
 749        .ct_group_ops   = &o2nm_cluster_group_group_ops,
 750        .ct_owner       = THIS_MODULE,
 751};
 752
 753static struct o2nm_cluster_group o2nm_cluster_group = {
 754        .cs_subsys = {
 755                .su_group = {
 756                        .cg_item = {
 757                                .ci_namebuf = "cluster",
 758                                .ci_type = &o2nm_cluster_group_type,
 759                        },
 760                },
 761        },
 762};
 763
 764static inline void o2nm_lock_subsystem(void)
 765{
 766        mutex_lock(&o2nm_cluster_group.cs_subsys.su_mutex);
 767}
 768
 769static inline void o2nm_unlock_subsystem(void)
 770{
 771        mutex_unlock(&o2nm_cluster_group.cs_subsys.su_mutex);
 772}
 773
 774int o2nm_depend_item(struct config_item *item)
 775{
 776        return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item);
 777}
 778
 779void o2nm_undepend_item(struct config_item *item)
 780{
 781        configfs_undepend_item(item);
 782}
 783
 784int o2nm_depend_this_node(void)
 785{
 786        int ret = 0;
 787        struct o2nm_node *local_node;
 788
 789        local_node = o2nm_get_node_by_num(o2nm_this_node());
 790        if (!local_node) {
 791                ret = -EINVAL;
 792                goto out;
 793        }
 794
 795        ret = o2nm_depend_item(&local_node->nd_item);
 796        o2nm_node_put(local_node);
 797
 798out:
 799        return ret;
 800}
 801
 802void o2nm_undepend_this_node(void)
 803{
 804        struct o2nm_node *local_node;
 805
 806        local_node = o2nm_get_node_by_num(o2nm_this_node());
 807        BUG_ON(!local_node);
 808
 809        o2nm_undepend_item(&local_node->nd_item);
 810        o2nm_node_put(local_node);
 811}
 812
 813
 814static void __exit exit_o2nm(void)
 815{
 816        /* XXX sync with hb callbacks and shut down hb? */
 817        o2net_unregister_hb_callbacks();
 818        configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
 819        o2cb_sys_shutdown();
 820
 821        o2net_exit();
 822        o2hb_exit();
 823}
 824
 825static int __init init_o2nm(void)
 826{
 827        int ret;
 828
 829        o2hb_init();
 830
 831        ret = o2net_init();
 832        if (ret)
 833                goto out_o2hb;
 834
 835        ret = o2net_register_hb_callbacks();
 836        if (ret)
 837                goto out_o2net;
 838
 839        config_group_init(&o2nm_cluster_group.cs_subsys.su_group);
 840        mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex);
 841        ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys);
 842        if (ret) {
 843                printk(KERN_ERR "nodemanager: Registration returned %d\n", ret);
 844                goto out_callbacks;
 845        }
 846
 847        ret = o2cb_sys_init();
 848        if (!ret)
 849                goto out;
 850
 851        configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
 852out_callbacks:
 853        o2net_unregister_hb_callbacks();
 854out_o2net:
 855        o2net_exit();
 856out_o2hb:
 857        o2hb_exit();
 858out:
 859        return ret;
 860}
 861
 862MODULE_AUTHOR("Oracle");
 863MODULE_LICENSE("GPL");
 864MODULE_DESCRIPTION("OCFS2 cluster management");
 865
 866module_init(init_o2nm)
 867module_exit(exit_o2nm)
 868