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