nodemanager.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /* -*- mode: c; c-basic-offset: 8; -*-
  2. * vim: noexpandtab sw=8 ts=8 sts=0:
  3. *
  4. * Copyright (C) 2004, 2005 Oracle. All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public
  17. * License along with this program; if not, write to the
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 021110-1307, USA.
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/module.h>
  23. #include <linux/sysctl.h>
  24. #include <linux/configfs.h>
  25. #include "endian.h"
  26. #include "tcp.h"
  27. #include "nodemanager.h"
  28. #include "heartbeat.h"
  29. #include "masklog.h"
  30. #include "sys.h"
  31. #include "ver.h"
  32. /* for now we operate under the assertion that there can be only one
  33. * cluster active at a time. Changing this will require trickling
  34. * cluster references throughout where nodes are looked up */
  35. static struct o2nm_cluster *o2nm_single_cluster = NULL;
  36. #define OCFS2_MAX_HB_CTL_PATH 256
  37. static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl";
  38. static ctl_table ocfs2_nm_table[] = {
  39. {
  40. .ctl_name = 1,
  41. .procname = "hb_ctl_path",
  42. .data = ocfs2_hb_ctl_path,
  43. .maxlen = OCFS2_MAX_HB_CTL_PATH,
  44. .mode = 0644,
  45. .proc_handler = &proc_dostring,
  46. .strategy = &sysctl_string,
  47. },
  48. { .ctl_name = 0 }
  49. };
  50. static ctl_table ocfs2_mod_table[] = {
  51. {
  52. .ctl_name = KERN_OCFS2_NM,
  53. .procname = "nm",
  54. .data = NULL,
  55. .maxlen = 0,
  56. .mode = 0555,
  57. .child = ocfs2_nm_table
  58. },
  59. { .ctl_name = 0}
  60. };
  61. static ctl_table ocfs2_kern_table[] = {
  62. {
  63. .ctl_name = KERN_OCFS2,
  64. .procname = "ocfs2",
  65. .data = NULL,
  66. .maxlen = 0,
  67. .mode = 0555,
  68. .child = ocfs2_mod_table
  69. },
  70. { .ctl_name = 0}
  71. };
  72. static ctl_table ocfs2_root_table[] = {
  73. {
  74. .ctl_name = CTL_FS,
  75. .procname = "fs",
  76. .data = NULL,
  77. .maxlen = 0,
  78. .mode = 0555,
  79. .child = ocfs2_kern_table
  80. },
  81. { .ctl_name = 0 }
  82. };
  83. static struct ctl_table_header *ocfs2_table_header = NULL;
  84. const char *o2nm_get_hb_ctl_path(void)
  85. {
  86. return ocfs2_hb_ctl_path;
  87. }
  88. EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path);
  89. struct o2nm_cluster {
  90. struct config_group cl_group;
  91. unsigned cl_has_local:1;
  92. u8 cl_local_node;
  93. rwlock_t cl_nodes_lock;
  94. struct o2nm_node *cl_nodes[O2NM_MAX_NODES];
  95. struct rb_root cl_node_ip_tree;
  96. /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */
  97. unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
  98. };
  99. struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
  100. {
  101. struct o2nm_node *node = NULL;
  102. if (node_num >= O2NM_MAX_NODES || o2nm_single_cluster == NULL)
  103. goto out;
  104. read_lock(&o2nm_single_cluster->cl_nodes_lock);
  105. node = o2nm_single_cluster->cl_nodes[node_num];
  106. if (node)
  107. config_item_get(&node->nd_item);
  108. read_unlock(&o2nm_single_cluster->cl_nodes_lock);
  109. out:
  110. return node;
  111. }
  112. EXPORT_SYMBOL_GPL(o2nm_get_node_by_num);
  113. int o2nm_configured_node_map(unsigned long *map, unsigned bytes)
  114. {
  115. struct o2nm_cluster *cluster = o2nm_single_cluster;
  116. BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap)));
  117. if (cluster == NULL)
  118. return -EINVAL;
  119. read_lock(&cluster->cl_nodes_lock);
  120. memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap));
  121. read_unlock(&cluster->cl_nodes_lock);
  122. return 0;
  123. }
  124. EXPORT_SYMBOL_GPL(o2nm_configured_node_map);
  125. static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster,
  126. __be32 ip_needle,
  127. struct rb_node ***ret_p,
  128. struct rb_node **ret_parent)
  129. {
  130. struct rb_node **p = &cluster->cl_node_ip_tree.rb_node;
  131. struct rb_node *parent = NULL;
  132. struct o2nm_node *node, *ret = NULL;
  133. while (*p) {
  134. parent = *p;
  135. node = rb_entry(parent, struct o2nm_node, nd_ip_node);
  136. if (memcmp(&ip_needle, &node->nd_ipv4_address,
  137. sizeof(ip_needle)) < 0)
  138. p = &(*p)->rb_left;
  139. else if (memcmp(&ip_needle, &node->nd_ipv4_address,
  140. sizeof(ip_needle)) > 0)
  141. p = &(*p)->rb_right;
  142. else {
  143. ret = node;
  144. break;
  145. }
  146. }
  147. if (ret_p != NULL)
  148. *ret_p = p;
  149. if (ret_parent != NULL)
  150. *ret_parent = parent;
  151. return ret;
  152. }
  153. struct o2nm_node *o2nm_get_node_by_ip(__be32 addr)
  154. {
  155. struct o2nm_node *node = NULL;
  156. struct o2nm_cluster *cluster = o2nm_single_cluster;
  157. if (cluster == NULL)
  158. goto out;
  159. read_lock(&cluster->cl_nodes_lock);
  160. node = o2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL);
  161. if (node)
  162. config_item_get(&node->nd_item);
  163. read_unlock(&cluster->cl_nodes_lock);
  164. out:
  165. return node;
  166. }
  167. EXPORT_SYMBOL_GPL(o2nm_get_node_by_ip);
  168. void o2nm_node_put(struct o2nm_node *node)
  169. {
  170. config_item_put(&node->nd_item);
  171. }
  172. EXPORT_SYMBOL_GPL(o2nm_node_put);
  173. void o2nm_node_get(struct o2nm_node *node)
  174. {
  175. config_item_get(&node->nd_item);
  176. }
  177. EXPORT_SYMBOL_GPL(o2nm_node_get);
  178. u8 o2nm_this_node(void)
  179. {
  180. u8 node_num = O2NM_MAX_NODES;
  181. if (o2nm_single_cluster && o2nm_single_cluster->cl_has_local)
  182. node_num = o2nm_single_cluster->cl_local_node;
  183. return node_num;
  184. }
  185. EXPORT_SYMBOL_GPL(o2nm_this_node);
  186. /* node configfs bits */
  187. static struct o2nm_cluster *to_o2nm_cluster(struct config_item *item)
  188. {
  189. return item ?
  190. container_of(to_config_group(item), struct o2nm_cluster,
  191. cl_group)
  192. : NULL;
  193. }
  194. static struct o2nm_node *to_o2nm_node(struct config_item *item)
  195. {
  196. return item ? container_of(item, struct o2nm_node, nd_item) : NULL;
  197. }
  198. static void o2nm_node_release(struct config_item *item)
  199. {
  200. struct o2nm_node *node = to_o2nm_node(item);
  201. kfree(node);
  202. }
  203. static ssize_t o2nm_node_num_read(struct o2nm_node *node, char *page)
  204. {
  205. return sprintf(page, "%d\n", node->nd_num);
  206. }
  207. static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node)
  208. {
  209. /* through the first node_set .parent
  210. * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */
  211. return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
  212. }
  213. enum {
  214. O2NM_NODE_ATTR_NUM = 0,
  215. O2NM_NODE_ATTR_PORT,
  216. O2NM_NODE_ATTR_ADDRESS,
  217. O2NM_NODE_ATTR_LOCAL,
  218. };
  219. static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page,
  220. size_t count)
  221. {
  222. struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
  223. unsigned long tmp;
  224. char *p = (char *)page;
  225. tmp = simple_strtoul(p, &p, 0);
  226. if (!p || (*p && (*p != '\n')))
  227. return -EINVAL;
  228. if (tmp >= O2NM_MAX_NODES)
  229. return -ERANGE;
  230. /* once we're in the cl_nodes tree networking can look us up by
  231. * node number and try to use our address and port attributes
  232. * to connect to this node.. make sure that they've been set
  233. * before writing the node attribute? */
  234. if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
  235. !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
  236. return -EINVAL; /* XXX */
  237. write_lock(&cluster->cl_nodes_lock);
  238. if (cluster->cl_nodes[tmp])
  239. p = NULL;
  240. else {
  241. cluster->cl_nodes[tmp] = node;
  242. node->nd_num = tmp;
  243. set_bit(tmp, cluster->cl_nodes_bitmap);
  244. }
  245. write_unlock(&cluster->cl_nodes_lock);
  246. if (p == NULL)
  247. return -EEXIST;
  248. return count;
  249. }
  250. static ssize_t o2nm_node_ipv4_port_read(struct o2nm_node *node, char *page)
  251. {
  252. return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port));
  253. }
  254. static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node,
  255. const char *page, size_t count)
  256. {
  257. unsigned long tmp;
  258. char *p = (char *)page;
  259. tmp = simple_strtoul(p, &p, 0);
  260. if (!p || (*p && (*p != '\n')))
  261. return -EINVAL;
  262. if (tmp == 0)
  263. return -EINVAL;
  264. if (tmp >= (u16)-1)
  265. return -ERANGE;
  266. node->nd_ipv4_port = htons(tmp);
  267. return count;
  268. }
  269. static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page)
  270. {
  271. return sprintf(page, "%u.%u.%u.%u\n", NIPQUAD(node->nd_ipv4_address));
  272. }
  273. static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node,
  274. const char *page,
  275. size_t count)
  276. {
  277. struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
  278. int ret, i;
  279. struct rb_node **p, *parent;
  280. unsigned int octets[4];
  281. __be32 ipv4_addr = 0;
  282. ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2],
  283. &octets[1], &octets[0]);
  284. if (ret != 4)
  285. return -EINVAL;
  286. for (i = 0; i < ARRAY_SIZE(octets); i++) {
  287. if (octets[i] > 255)
  288. return -ERANGE;
  289. be32_add_cpu(&ipv4_addr, octets[i] << (i * 8));
  290. }
  291. ret = 0;
  292. write_lock(&cluster->cl_nodes_lock);
  293. if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
  294. ret = -EEXIST;
  295. else {
  296. rb_link_node(&node->nd_ip_node, parent, p);
  297. rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
  298. }
  299. write_unlock(&cluster->cl_nodes_lock);
  300. if (ret)
  301. return ret;
  302. memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr));
  303. return count;
  304. }
  305. static ssize_t o2nm_node_local_read(struct o2nm_node *node, char *page)
  306. {
  307. return sprintf(page, "%d\n", node->nd_local);
  308. }
  309. static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page,
  310. size_t count)
  311. {
  312. struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
  313. unsigned long tmp;
  314. char *p = (char *)page;
  315. ssize_t ret;
  316. tmp = simple_strtoul(p, &p, 0);
  317. if (!p || (*p && (*p != '\n')))
  318. return -EINVAL;
  319. tmp = !!tmp; /* boolean of whether this node wants to be local */
  320. /* setting local turns on networking rx for now so we require having
  321. * set everything else first */
  322. if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
  323. !test_bit(O2NM_NODE_ATTR_NUM, &node->nd_set_attributes) ||
  324. !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
  325. return -EINVAL; /* XXX */
  326. /* the only failure case is trying to set a new local node
  327. * when a different one is already set */
  328. if (tmp && tmp == cluster->cl_has_local &&
  329. cluster->cl_local_node != node->nd_num)
  330. return -EBUSY;
  331. /* bring up the rx thread if we're setting the new local node. */
  332. if (tmp && !cluster->cl_has_local) {
  333. ret = o2net_start_listening(node);
  334. if (ret)
  335. return ret;
  336. }
  337. if (!tmp && cluster->cl_has_local &&
  338. cluster->cl_local_node == node->nd_num) {
  339. o2net_stop_listening(node);
  340. cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
  341. }
  342. node->nd_local = tmp;
  343. if (node->nd_local) {
  344. cluster->cl_has_local = tmp;
  345. cluster->cl_local_node = node->nd_num;
  346. }
  347. return count;
  348. }
  349. struct o2nm_node_attribute {
  350. struct configfs_attribute attr;
  351. ssize_t (*show)(struct o2nm_node *, char *);
  352. ssize_t (*store)(struct o2nm_node *, const char *, size_t);
  353. };
  354. static struct o2nm_node_attribute o2nm_node_attr_num = {
  355. .attr = { .ca_owner = THIS_MODULE,
  356. .ca_name = "num",
  357. .ca_mode = S_IRUGO | S_IWUSR },
  358. .show = o2nm_node_num_read,
  359. .store = o2nm_node_num_write,
  360. };
  361. static struct o2nm_node_attribute o2nm_node_attr_ipv4_port = {
  362. .attr = { .ca_owner = THIS_MODULE,
  363. .ca_name = "ipv4_port",
  364. .ca_mode = S_IRUGO | S_IWUSR },
  365. .show = o2nm_node_ipv4_port_read,
  366. .store = o2nm_node_ipv4_port_write,
  367. };
  368. static struct o2nm_node_attribute o2nm_node_attr_ipv4_address = {
  369. .attr = { .ca_owner = THIS_MODULE,
  370. .ca_name = "ipv4_address",
  371. .ca_mode = S_IRUGO | S_IWUSR },
  372. .show = o2nm_node_ipv4_address_read,
  373. .store = o2nm_node_ipv4_address_write,
  374. };
  375. static struct o2nm_node_attribute o2nm_node_attr_local = {
  376. .attr = { .ca_owner = THIS_MODULE,
  377. .ca_name = "local",
  378. .ca_mode = S_IRUGO | S_IWUSR },
  379. .show = o2nm_node_local_read,
  380. .store = o2nm_node_local_write,
  381. };
  382. static struct configfs_attribute *o2nm_node_attrs[] = {
  383. [O2NM_NODE_ATTR_NUM] = &o2nm_node_attr_num.attr,
  384. [O2NM_NODE_ATTR_PORT] = &o2nm_node_attr_ipv4_port.attr,
  385. [O2NM_NODE_ATTR_ADDRESS] = &o2nm_node_attr_ipv4_address.attr,
  386. [O2NM_NODE_ATTR_LOCAL] = &o2nm_node_attr_local.attr,
  387. NULL,
  388. };
  389. static int o2nm_attr_index(struct configfs_attribute *attr)
  390. {
  391. int i;
  392. for (i = 0; i < ARRAY_SIZE(o2nm_node_attrs); i++) {
  393. if (attr == o2nm_node_attrs[i])
  394. return i;
  395. }
  396. BUG();
  397. return 0;
  398. }
  399. static ssize_t o2nm_node_show(struct config_item *item,
  400. struct configfs_attribute *attr,
  401. char *page)
  402. {
  403. struct o2nm_node *node = to_o2nm_node(item);
  404. struct o2nm_node_attribute *o2nm_node_attr =
  405. container_of(attr, struct o2nm_node_attribute, attr);
  406. ssize_t ret = 0;
  407. if (o2nm_node_attr->show)
  408. ret = o2nm_node_attr->show(node, page);
  409. return ret;
  410. }
  411. static ssize_t o2nm_node_store(struct config_item *item,
  412. struct configfs_attribute *attr,
  413. const char *page, size_t count)
  414. {
  415. struct o2nm_node *node = to_o2nm_node(item);
  416. struct o2nm_node_attribute *o2nm_node_attr =
  417. container_of(attr, struct o2nm_node_attribute, attr);
  418. ssize_t ret;
  419. int attr_index = o2nm_attr_index(attr);
  420. if (o2nm_node_attr->store == NULL) {
  421. ret = -EINVAL;
  422. goto out;
  423. }
  424. if (test_bit(attr_index, &node->nd_set_attributes))
  425. return -EBUSY;
  426. ret = o2nm_node_attr->store(node, page, count);
  427. if (ret < count)
  428. goto out;
  429. set_bit(attr_index, &node->nd_set_attributes);
  430. out:
  431. return ret;
  432. }
  433. static struct configfs_item_operations o2nm_node_item_ops = {
  434. .release = o2nm_node_release,
  435. .show_attribute = o2nm_node_show,
  436. .store_attribute = o2nm_node_store,
  437. };
  438. static struct config_item_type o2nm_node_type = {
  439. .ct_item_ops = &o2nm_node_item_ops,
  440. .ct_attrs = o2nm_node_attrs,
  441. .ct_owner = THIS_MODULE,
  442. };
  443. /* node set */
  444. struct o2nm_node_group {
  445. struct config_group ns_group;
  446. /* some stuff? */
  447. };
  448. #if 0
  449. static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group)
  450. {
  451. return group ?
  452. container_of(group, struct o2nm_node_group, ns_group)
  453. : NULL;
  454. }
  455. #endif
  456. static struct config_item *o2nm_node_group_make_item(struct config_group *group,
  457. const char *name)
  458. {
  459. struct o2nm_node *node = NULL;
  460. struct config_item *ret = NULL;
  461. if (strlen(name) > O2NM_MAX_NAME_LEN)
  462. goto out; /* ENAMETOOLONG */
  463. node = kcalloc(1, sizeof(struct o2nm_node), GFP_KERNEL);
  464. if (node == NULL)
  465. goto out; /* ENOMEM */
  466. strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
  467. config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
  468. spin_lock_init(&node->nd_lock);
  469. ret = &node->nd_item;
  470. out:
  471. if (ret == NULL)
  472. kfree(node);
  473. return ret;
  474. }
  475. static void o2nm_node_group_drop_item(struct config_group *group,
  476. struct config_item *item)
  477. {
  478. struct o2nm_node *node = to_o2nm_node(item);
  479. struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent);
  480. o2net_disconnect_node(node);
  481. if (cluster->cl_has_local &&
  482. (cluster->cl_local_node == node->nd_num)) {
  483. cluster->cl_has_local = 0;
  484. cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
  485. o2net_stop_listening(node);
  486. }
  487. /* XXX call into net to stop this node from trading messages */
  488. write_lock(&cluster->cl_nodes_lock);
  489. /* XXX sloppy */
  490. if (node->nd_ipv4_address)
  491. rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree);
  492. /* nd_num might be 0 if the node number hasn't been set.. */
  493. if (cluster->cl_nodes[node->nd_num] == node) {
  494. cluster->cl_nodes[node->nd_num] = NULL;
  495. clear_bit(node->nd_num, cluster->cl_nodes_bitmap);
  496. }
  497. write_unlock(&cluster->cl_nodes_lock);
  498. config_item_put(item);
  499. }
  500. static struct configfs_group_operations o2nm_node_group_group_ops = {
  501. .make_item = o2nm_node_group_make_item,
  502. .drop_item = o2nm_node_group_drop_item,
  503. };
  504. static struct config_item_type o2nm_node_group_type = {
  505. .ct_group_ops = &o2nm_node_group_group_ops,
  506. .ct_owner = THIS_MODULE,
  507. };
  508. /* cluster */
  509. static void o2nm_cluster_release(struct config_item *item)
  510. {
  511. struct o2nm_cluster *cluster = to_o2nm_cluster(item);
  512. kfree(cluster->cl_group.default_groups);
  513. kfree(cluster);
  514. }
  515. static struct configfs_item_operations o2nm_cluster_item_ops = {
  516. .release = o2nm_cluster_release,
  517. };
  518. static struct config_item_type o2nm_cluster_type = {
  519. .ct_item_ops = &o2nm_cluster_item_ops,
  520. .ct_owner = THIS_MODULE,
  521. };
  522. /* cluster set */
  523. struct o2nm_cluster_group {
  524. struct configfs_subsystem cs_subsys;
  525. /* some stuff? */
  526. };
  527. #if 0
  528. static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *group)
  529. {
  530. return group ?
  531. container_of(to_configfs_subsystem(group), struct o2nm_cluster_group, cs_subsys)
  532. : NULL;
  533. }
  534. #endif
  535. static struct config_group *o2nm_cluster_group_make_group(struct config_group *group,
  536. const char *name)
  537. {
  538. struct o2nm_cluster *cluster = NULL;
  539. struct o2nm_node_group *ns = NULL;
  540. struct config_group *o2hb_group = NULL, *ret = NULL;
  541. void *defs = NULL;
  542. /* this runs under the parent dir's i_mutex; there can be only
  543. * one caller in here at a time */
  544. if (o2nm_single_cluster)
  545. goto out; /* ENOSPC */
  546. cluster = kcalloc(1, sizeof(struct o2nm_cluster), GFP_KERNEL);
  547. ns = kcalloc(1, sizeof(struct o2nm_node_group), GFP_KERNEL);
  548. defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
  549. o2hb_group = o2hb_alloc_hb_set();
  550. if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL)
  551. goto out;
  552. config_group_init_type_name(&cluster->cl_group, name,
  553. &o2nm_cluster_type);
  554. config_group_init_type_name(&ns->ns_group, "node",
  555. &o2nm_node_group_type);
  556. cluster->cl_group.default_groups = defs;
  557. cluster->cl_group.default_groups[0] = &ns->ns_group;
  558. cluster->cl_group.default_groups[1] = o2hb_group;
  559. cluster->cl_group.default_groups[2] = NULL;
  560. rwlock_init(&cluster->cl_nodes_lock);
  561. cluster->cl_node_ip_tree = RB_ROOT;
  562. ret = &cluster->cl_group;
  563. o2nm_single_cluster = cluster;
  564. out:
  565. if (ret == NULL) {
  566. kfree(cluster);
  567. kfree(ns);
  568. o2hb_free_hb_set(o2hb_group);
  569. kfree(defs);
  570. }
  571. return ret;
  572. }
  573. static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item)
  574. {
  575. struct o2nm_cluster *cluster = to_o2nm_cluster(item);
  576. int i;
  577. struct config_item *killme;
  578. BUG_ON(o2nm_single_cluster != cluster);
  579. o2nm_single_cluster = NULL;
  580. for (i = 0; cluster->cl_group.default_groups[i]; i++) {
  581. killme = &cluster->cl_group.default_groups[i]->cg_item;
  582. cluster->cl_group.default_groups[i] = NULL;
  583. config_item_put(killme);
  584. }
  585. config_item_put(item);
  586. }
  587. static struct configfs_group_operations o2nm_cluster_group_group_ops = {
  588. .make_group = o2nm_cluster_group_make_group,
  589. .drop_item = o2nm_cluster_group_drop_item,
  590. };
  591. static struct config_item_type o2nm_cluster_group_type = {
  592. .ct_group_ops = &o2nm_cluster_group_group_ops,
  593. .ct_owner = THIS_MODULE,
  594. };
  595. static struct o2nm_cluster_group o2nm_cluster_group = {
  596. .cs_subsys = {
  597. .su_group = {
  598. .cg_item = {
  599. .ci_namebuf = "cluster",
  600. .ci_type = &o2nm_cluster_group_type,
  601. },
  602. },
  603. },
  604. };
  605. static void __exit exit_o2nm(void)
  606. {
  607. if (ocfs2_table_header)
  608. unregister_sysctl_table(ocfs2_table_header);
  609. /* XXX sync with hb callbacks and shut down hb? */
  610. o2net_unregister_hb_callbacks();
  611. configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
  612. o2cb_sys_shutdown();
  613. o2net_exit();
  614. }
  615. static int __init init_o2nm(void)
  616. {
  617. int ret = -1;
  618. cluster_print_version();
  619. o2hb_init();
  620. o2net_init();
  621. ocfs2_table_header = register_sysctl_table(ocfs2_root_table, 0);
  622. if (!ocfs2_table_header) {
  623. printk(KERN_ERR "nodemanager: unable to register sysctl\n");
  624. ret = -ENOMEM; /* or something. */
  625. goto out_o2net;
  626. }
  627. ret = o2net_register_hb_callbacks();
  628. if (ret)
  629. goto out_sysctl;
  630. config_group_init(&o2nm_cluster_group.cs_subsys.su_group);
  631. init_MUTEX(&o2nm_cluster_group.cs_subsys.su_sem);
  632. ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys);
  633. if (ret) {
  634. printk(KERN_ERR "nodemanager: Registration returned %d\n", ret);
  635. goto out_callbacks;
  636. }
  637. ret = o2cb_sys_init();
  638. if (!ret)
  639. goto out;
  640. configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
  641. out_callbacks:
  642. o2net_unregister_hb_callbacks();
  643. out_sysctl:
  644. unregister_sysctl_table(ocfs2_table_header);
  645. out_o2net:
  646. o2net_exit();
  647. out:
  648. return ret;
  649. }
  650. MODULE_AUTHOR("Oracle");
  651. MODULE_LICENSE("GPL");
  652. module_init(init_o2nm)
  653. module_exit(exit_o2nm)