config.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. /******************************************************************************
  2. *******************************************************************************
  3. **
  4. ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
  5. ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
  6. **
  7. ** This copyrighted material is made available to anyone wishing to use,
  8. ** modify, copy, or redistribute it subject to the terms and conditions
  9. ** of the GNU General Public License v.2.
  10. **
  11. *******************************************************************************
  12. ******************************************************************************/
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/configfs.h>
  16. #include <linux/slab.h>
  17. #include <linux/in.h>
  18. #include <linux/in6.h>
  19. #include <net/ipv6.h>
  20. #include <net/sock.h>
  21. #include "config.h"
  22. #include "lowcomms.h"
  23. /*
  24. * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid
  25. * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight
  26. * /config/dlm/<cluster>/comms/<comm>/nodeid
  27. * /config/dlm/<cluster>/comms/<comm>/local
  28. * /config/dlm/<cluster>/comms/<comm>/addr (write only)
  29. * /config/dlm/<cluster>/comms/<comm>/addr_list (read only)
  30. * The <cluster> level is useless, but I haven't figured out how to avoid it.
  31. */
  32. static struct config_group *space_list;
  33. static struct config_group *comm_list;
  34. static struct dlm_comm *local_comm;
  35. struct dlm_clusters;
  36. struct dlm_cluster;
  37. struct dlm_spaces;
  38. struct dlm_space;
  39. struct dlm_comms;
  40. struct dlm_comm;
  41. struct dlm_nodes;
  42. struct dlm_node;
  43. static struct config_group *make_cluster(struct config_group *, const char *);
  44. static void drop_cluster(struct config_group *, struct config_item *);
  45. static void release_cluster(struct config_item *);
  46. static struct config_group *make_space(struct config_group *, const char *);
  47. static void drop_space(struct config_group *, struct config_item *);
  48. static void release_space(struct config_item *);
  49. static struct config_item *make_comm(struct config_group *, const char *);
  50. static void drop_comm(struct config_group *, struct config_item *);
  51. static void release_comm(struct config_item *);
  52. static struct config_item *make_node(struct config_group *, const char *);
  53. static void drop_node(struct config_group *, struct config_item *);
  54. static void release_node(struct config_item *);
  55. static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a,
  56. char *buf);
  57. static ssize_t store_cluster(struct config_item *i,
  58. struct configfs_attribute *a,
  59. const char *buf, size_t len);
  60. static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
  61. char *buf);
  62. static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a,
  63. const char *buf, size_t len);
  64. static ssize_t show_node(struct config_item *i, struct configfs_attribute *a,
  65. char *buf);
  66. static ssize_t store_node(struct config_item *i, struct configfs_attribute *a,
  67. const char *buf, size_t len);
  68. static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf);
  69. static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf,
  70. size_t len);
  71. static ssize_t comm_local_read(struct dlm_comm *cm, char *buf);
  72. static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf,
  73. size_t len);
  74. static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf,
  75. size_t len);
  76. static ssize_t comm_addr_list_read(struct dlm_comm *cm, char *buf);
  77. static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf);
  78. static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
  79. size_t len);
  80. static ssize_t node_weight_read(struct dlm_node *nd, char *buf);
  81. static ssize_t node_weight_write(struct dlm_node *nd, const char *buf,
  82. size_t len);
  83. struct dlm_cluster {
  84. struct config_group group;
  85. unsigned int cl_tcp_port;
  86. unsigned int cl_buffer_size;
  87. unsigned int cl_rsbtbl_size;
  88. unsigned int cl_dirtbl_size;
  89. unsigned int cl_recover_timer;
  90. unsigned int cl_toss_secs;
  91. unsigned int cl_scan_secs;
  92. unsigned int cl_log_debug;
  93. unsigned int cl_protocol;
  94. unsigned int cl_timewarn_cs;
  95. unsigned int cl_waitwarn_us;
  96. unsigned int cl_new_rsb_count;
  97. };
  98. enum {
  99. CLUSTER_ATTR_TCP_PORT = 0,
  100. CLUSTER_ATTR_BUFFER_SIZE,
  101. CLUSTER_ATTR_RSBTBL_SIZE,
  102. CLUSTER_ATTR_DIRTBL_SIZE,
  103. CLUSTER_ATTR_RECOVER_TIMER,
  104. CLUSTER_ATTR_TOSS_SECS,
  105. CLUSTER_ATTR_SCAN_SECS,
  106. CLUSTER_ATTR_LOG_DEBUG,
  107. CLUSTER_ATTR_PROTOCOL,
  108. CLUSTER_ATTR_TIMEWARN_CS,
  109. CLUSTER_ATTR_WAITWARN_US,
  110. CLUSTER_ATTR_NEW_RSB_COUNT,
  111. };
  112. struct cluster_attribute {
  113. struct configfs_attribute attr;
  114. ssize_t (*show)(struct dlm_cluster *, char *);
  115. ssize_t (*store)(struct dlm_cluster *, const char *, size_t);
  116. };
  117. static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field,
  118. int *info_field, int check_zero,
  119. const char *buf, size_t len)
  120. {
  121. unsigned int x;
  122. if (!capable(CAP_SYS_ADMIN))
  123. return -EACCES;
  124. x = simple_strtoul(buf, NULL, 0);
  125. if (check_zero && !x)
  126. return -EINVAL;
  127. *cl_field = x;
  128. *info_field = x;
  129. return len;
  130. }
  131. #define CLUSTER_ATTR(name, check_zero) \
  132. static ssize_t name##_write(struct dlm_cluster *cl, const char *buf, size_t len) \
  133. { \
  134. return cluster_set(cl, &cl->cl_##name, &dlm_config.ci_##name, \
  135. check_zero, buf, len); \
  136. } \
  137. static ssize_t name##_read(struct dlm_cluster *cl, char *buf) \
  138. { \
  139. return snprintf(buf, PAGE_SIZE, "%u\n", cl->cl_##name); \
  140. } \
  141. static struct cluster_attribute cluster_attr_##name = \
  142. __CONFIGFS_ATTR(name, 0644, name##_read, name##_write)
  143. CLUSTER_ATTR(tcp_port, 1);
  144. CLUSTER_ATTR(buffer_size, 1);
  145. CLUSTER_ATTR(rsbtbl_size, 1);
  146. CLUSTER_ATTR(dirtbl_size, 1);
  147. CLUSTER_ATTR(recover_timer, 1);
  148. CLUSTER_ATTR(toss_secs, 1);
  149. CLUSTER_ATTR(scan_secs, 1);
  150. CLUSTER_ATTR(log_debug, 0);
  151. CLUSTER_ATTR(protocol, 0);
  152. CLUSTER_ATTR(timewarn_cs, 1);
  153. CLUSTER_ATTR(waitwarn_us, 0);
  154. CLUSTER_ATTR(new_rsb_count, 0);
  155. static struct configfs_attribute *cluster_attrs[] = {
  156. [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
  157. [CLUSTER_ATTR_BUFFER_SIZE] = &cluster_attr_buffer_size.attr,
  158. [CLUSTER_ATTR_RSBTBL_SIZE] = &cluster_attr_rsbtbl_size.attr,
  159. [CLUSTER_ATTR_DIRTBL_SIZE] = &cluster_attr_dirtbl_size.attr,
  160. [CLUSTER_ATTR_RECOVER_TIMER] = &cluster_attr_recover_timer.attr,
  161. [CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs.attr,
  162. [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr,
  163. [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
  164. [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr,
  165. [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr,
  166. [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us.attr,
  167. [CLUSTER_ATTR_NEW_RSB_COUNT] = &cluster_attr_new_rsb_count.attr,
  168. NULL,
  169. };
  170. enum {
  171. COMM_ATTR_NODEID = 0,
  172. COMM_ATTR_LOCAL,
  173. COMM_ATTR_ADDR,
  174. COMM_ATTR_ADDR_LIST,
  175. };
  176. struct comm_attribute {
  177. struct configfs_attribute attr;
  178. ssize_t (*show)(struct dlm_comm *, char *);
  179. ssize_t (*store)(struct dlm_comm *, const char *, size_t);
  180. };
  181. static struct comm_attribute comm_attr_nodeid = {
  182. .attr = { .ca_owner = THIS_MODULE,
  183. .ca_name = "nodeid",
  184. .ca_mode = S_IRUGO | S_IWUSR },
  185. .show = comm_nodeid_read,
  186. .store = comm_nodeid_write,
  187. };
  188. static struct comm_attribute comm_attr_local = {
  189. .attr = { .ca_owner = THIS_MODULE,
  190. .ca_name = "local",
  191. .ca_mode = S_IRUGO | S_IWUSR },
  192. .show = comm_local_read,
  193. .store = comm_local_write,
  194. };
  195. static struct comm_attribute comm_attr_addr = {
  196. .attr = { .ca_owner = THIS_MODULE,
  197. .ca_name = "addr",
  198. .ca_mode = S_IWUSR },
  199. .store = comm_addr_write,
  200. };
  201. static struct comm_attribute comm_attr_addr_list = {
  202. .attr = { .ca_owner = THIS_MODULE,
  203. .ca_name = "addr_list",
  204. .ca_mode = S_IRUGO },
  205. .show = comm_addr_list_read,
  206. };
  207. static struct configfs_attribute *comm_attrs[] = {
  208. [COMM_ATTR_NODEID] = &comm_attr_nodeid.attr,
  209. [COMM_ATTR_LOCAL] = &comm_attr_local.attr,
  210. [COMM_ATTR_ADDR] = &comm_attr_addr.attr,
  211. [COMM_ATTR_ADDR_LIST] = &comm_attr_addr_list.attr,
  212. NULL,
  213. };
  214. enum {
  215. NODE_ATTR_NODEID = 0,
  216. NODE_ATTR_WEIGHT,
  217. };
  218. struct node_attribute {
  219. struct configfs_attribute attr;
  220. ssize_t (*show)(struct dlm_node *, char *);
  221. ssize_t (*store)(struct dlm_node *, const char *, size_t);
  222. };
  223. static struct node_attribute node_attr_nodeid = {
  224. .attr = { .ca_owner = THIS_MODULE,
  225. .ca_name = "nodeid",
  226. .ca_mode = S_IRUGO | S_IWUSR },
  227. .show = node_nodeid_read,
  228. .store = node_nodeid_write,
  229. };
  230. static struct node_attribute node_attr_weight = {
  231. .attr = { .ca_owner = THIS_MODULE,
  232. .ca_name = "weight",
  233. .ca_mode = S_IRUGO | S_IWUSR },
  234. .show = node_weight_read,
  235. .store = node_weight_write,
  236. };
  237. static struct configfs_attribute *node_attrs[] = {
  238. [NODE_ATTR_NODEID] = &node_attr_nodeid.attr,
  239. [NODE_ATTR_WEIGHT] = &node_attr_weight.attr,
  240. NULL,
  241. };
  242. struct dlm_clusters {
  243. struct configfs_subsystem subsys;
  244. };
  245. struct dlm_spaces {
  246. struct config_group ss_group;
  247. };
  248. struct dlm_space {
  249. struct config_group group;
  250. struct list_head members;
  251. struct mutex members_lock;
  252. int members_count;
  253. };
  254. struct dlm_comms {
  255. struct config_group cs_group;
  256. };
  257. struct dlm_comm {
  258. struct config_item item;
  259. int nodeid;
  260. int local;
  261. int addr_count;
  262. struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT];
  263. };
  264. struct dlm_nodes {
  265. struct config_group ns_group;
  266. };
  267. struct dlm_node {
  268. struct config_item item;
  269. struct list_head list; /* space->members */
  270. int nodeid;
  271. int weight;
  272. int new;
  273. };
  274. static struct configfs_group_operations clusters_ops = {
  275. .make_group = make_cluster,
  276. .drop_item = drop_cluster,
  277. };
  278. static struct configfs_item_operations cluster_ops = {
  279. .release = release_cluster,
  280. .show_attribute = show_cluster,
  281. .store_attribute = store_cluster,
  282. };
  283. static struct configfs_group_operations spaces_ops = {
  284. .make_group = make_space,
  285. .drop_item = drop_space,
  286. };
  287. static struct configfs_item_operations space_ops = {
  288. .release = release_space,
  289. };
  290. static struct configfs_group_operations comms_ops = {
  291. .make_item = make_comm,
  292. .drop_item = drop_comm,
  293. };
  294. static struct configfs_item_operations comm_ops = {
  295. .release = release_comm,
  296. .show_attribute = show_comm,
  297. .store_attribute = store_comm,
  298. };
  299. static struct configfs_group_operations nodes_ops = {
  300. .make_item = make_node,
  301. .drop_item = drop_node,
  302. };
  303. static struct configfs_item_operations node_ops = {
  304. .release = release_node,
  305. .show_attribute = show_node,
  306. .store_attribute = store_node,
  307. };
  308. static struct config_item_type clusters_type = {
  309. .ct_group_ops = &clusters_ops,
  310. .ct_owner = THIS_MODULE,
  311. };
  312. static struct config_item_type cluster_type = {
  313. .ct_item_ops = &cluster_ops,
  314. .ct_attrs = cluster_attrs,
  315. .ct_owner = THIS_MODULE,
  316. };
  317. static struct config_item_type spaces_type = {
  318. .ct_group_ops = &spaces_ops,
  319. .ct_owner = THIS_MODULE,
  320. };
  321. static struct config_item_type space_type = {
  322. .ct_item_ops = &space_ops,
  323. .ct_owner = THIS_MODULE,
  324. };
  325. static struct config_item_type comms_type = {
  326. .ct_group_ops = &comms_ops,
  327. .ct_owner = THIS_MODULE,
  328. };
  329. static struct config_item_type comm_type = {
  330. .ct_item_ops = &comm_ops,
  331. .ct_attrs = comm_attrs,
  332. .ct_owner = THIS_MODULE,
  333. };
  334. static struct config_item_type nodes_type = {
  335. .ct_group_ops = &nodes_ops,
  336. .ct_owner = THIS_MODULE,
  337. };
  338. static struct config_item_type node_type = {
  339. .ct_item_ops = &node_ops,
  340. .ct_attrs = node_attrs,
  341. .ct_owner = THIS_MODULE,
  342. };
  343. static struct dlm_cluster *config_item_to_cluster(struct config_item *i)
  344. {
  345. return i ? container_of(to_config_group(i), struct dlm_cluster, group) :
  346. NULL;
  347. }
  348. static struct dlm_space *config_item_to_space(struct config_item *i)
  349. {
  350. return i ? container_of(to_config_group(i), struct dlm_space, group) :
  351. NULL;
  352. }
  353. static struct dlm_comm *config_item_to_comm(struct config_item *i)
  354. {
  355. return i ? container_of(i, struct dlm_comm, item) : NULL;
  356. }
  357. static struct dlm_node *config_item_to_node(struct config_item *i)
  358. {
  359. return i ? container_of(i, struct dlm_node, item) : NULL;
  360. }
  361. static struct config_group *make_cluster(struct config_group *g,
  362. const char *name)
  363. {
  364. struct dlm_cluster *cl = NULL;
  365. struct dlm_spaces *sps = NULL;
  366. struct dlm_comms *cms = NULL;
  367. void *gps = NULL;
  368. cl = kzalloc(sizeof(struct dlm_cluster), GFP_NOFS);
  369. gps = kcalloc(3, sizeof(struct config_group *), GFP_NOFS);
  370. sps = kzalloc(sizeof(struct dlm_spaces), GFP_NOFS);
  371. cms = kzalloc(sizeof(struct dlm_comms), GFP_NOFS);
  372. if (!cl || !gps || !sps || !cms)
  373. goto fail;
  374. config_group_init_type_name(&cl->group, name, &cluster_type);
  375. config_group_init_type_name(&sps->ss_group, "spaces", &spaces_type);
  376. config_group_init_type_name(&cms->cs_group, "comms", &comms_type);
  377. cl->group.default_groups = gps;
  378. cl->group.default_groups[0] = &sps->ss_group;
  379. cl->group.default_groups[1] = &cms->cs_group;
  380. cl->group.default_groups[2] = NULL;
  381. cl->cl_tcp_port = dlm_config.ci_tcp_port;
  382. cl->cl_buffer_size = dlm_config.ci_buffer_size;
  383. cl->cl_rsbtbl_size = dlm_config.ci_rsbtbl_size;
  384. cl->cl_dirtbl_size = dlm_config.ci_dirtbl_size;
  385. cl->cl_recover_timer = dlm_config.ci_recover_timer;
  386. cl->cl_toss_secs = dlm_config.ci_toss_secs;
  387. cl->cl_scan_secs = dlm_config.ci_scan_secs;
  388. cl->cl_log_debug = dlm_config.ci_log_debug;
  389. cl->cl_protocol = dlm_config.ci_protocol;
  390. cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs;
  391. cl->cl_waitwarn_us = dlm_config.ci_waitwarn_us;
  392. cl->cl_new_rsb_count = dlm_config.ci_new_rsb_count;
  393. space_list = &sps->ss_group;
  394. comm_list = &cms->cs_group;
  395. return &cl->group;
  396. fail:
  397. kfree(cl);
  398. kfree(gps);
  399. kfree(sps);
  400. kfree(cms);
  401. return ERR_PTR(-ENOMEM);
  402. }
  403. static void drop_cluster(struct config_group *g, struct config_item *i)
  404. {
  405. struct dlm_cluster *cl = config_item_to_cluster(i);
  406. struct config_item *tmp;
  407. int j;
  408. for (j = 0; cl->group.default_groups[j]; j++) {
  409. tmp = &cl->group.default_groups[j]->cg_item;
  410. cl->group.default_groups[j] = NULL;
  411. config_item_put(tmp);
  412. }
  413. space_list = NULL;
  414. comm_list = NULL;
  415. config_item_put(i);
  416. }
  417. static void release_cluster(struct config_item *i)
  418. {
  419. struct dlm_cluster *cl = config_item_to_cluster(i);
  420. kfree(cl->group.default_groups);
  421. kfree(cl);
  422. }
  423. static struct config_group *make_space(struct config_group *g, const char *name)
  424. {
  425. struct dlm_space *sp = NULL;
  426. struct dlm_nodes *nds = NULL;
  427. void *gps = NULL;
  428. sp = kzalloc(sizeof(struct dlm_space), GFP_NOFS);
  429. gps = kcalloc(2, sizeof(struct config_group *), GFP_NOFS);
  430. nds = kzalloc(sizeof(struct dlm_nodes), GFP_NOFS);
  431. if (!sp || !gps || !nds)
  432. goto fail;
  433. config_group_init_type_name(&sp->group, name, &space_type);
  434. config_group_init_type_name(&nds->ns_group, "nodes", &nodes_type);
  435. sp->group.default_groups = gps;
  436. sp->group.default_groups[0] = &nds->ns_group;
  437. sp->group.default_groups[1] = NULL;
  438. INIT_LIST_HEAD(&sp->members);
  439. mutex_init(&sp->members_lock);
  440. sp->members_count = 0;
  441. return &sp->group;
  442. fail:
  443. kfree(sp);
  444. kfree(gps);
  445. kfree(nds);
  446. return ERR_PTR(-ENOMEM);
  447. }
  448. static void drop_space(struct config_group *g, struct config_item *i)
  449. {
  450. struct dlm_space *sp = config_item_to_space(i);
  451. struct config_item *tmp;
  452. int j;
  453. /* assert list_empty(&sp->members) */
  454. for (j = 0; sp->group.default_groups[j]; j++) {
  455. tmp = &sp->group.default_groups[j]->cg_item;
  456. sp->group.default_groups[j] = NULL;
  457. config_item_put(tmp);
  458. }
  459. config_item_put(i);
  460. }
  461. static void release_space(struct config_item *i)
  462. {
  463. struct dlm_space *sp = config_item_to_space(i);
  464. kfree(sp->group.default_groups);
  465. kfree(sp);
  466. }
  467. static struct config_item *make_comm(struct config_group *g, const char *name)
  468. {
  469. struct dlm_comm *cm;
  470. cm = kzalloc(sizeof(struct dlm_comm), GFP_NOFS);
  471. if (!cm)
  472. return ERR_PTR(-ENOMEM);
  473. config_item_init_type_name(&cm->item, name, &comm_type);
  474. cm->nodeid = -1;
  475. cm->local = 0;
  476. cm->addr_count = 0;
  477. return &cm->item;
  478. }
  479. static void drop_comm(struct config_group *g, struct config_item *i)
  480. {
  481. struct dlm_comm *cm = config_item_to_comm(i);
  482. if (local_comm == cm)
  483. local_comm = NULL;
  484. dlm_lowcomms_close(cm->nodeid);
  485. while (cm->addr_count--)
  486. kfree(cm->addr[cm->addr_count]);
  487. config_item_put(i);
  488. }
  489. static void release_comm(struct config_item *i)
  490. {
  491. struct dlm_comm *cm = config_item_to_comm(i);
  492. kfree(cm);
  493. }
  494. static struct config_item *make_node(struct config_group *g, const char *name)
  495. {
  496. struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
  497. struct dlm_node *nd;
  498. nd = kzalloc(sizeof(struct dlm_node), GFP_NOFS);
  499. if (!nd)
  500. return ERR_PTR(-ENOMEM);
  501. config_item_init_type_name(&nd->item, name, &node_type);
  502. nd->nodeid = -1;
  503. nd->weight = 1; /* default weight of 1 if none is set */
  504. nd->new = 1; /* set to 0 once it's been read by dlm_nodeid_list() */
  505. mutex_lock(&sp->members_lock);
  506. list_add(&nd->list, &sp->members);
  507. sp->members_count++;
  508. mutex_unlock(&sp->members_lock);
  509. return &nd->item;
  510. }
  511. static void drop_node(struct config_group *g, struct config_item *i)
  512. {
  513. struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
  514. struct dlm_node *nd = config_item_to_node(i);
  515. mutex_lock(&sp->members_lock);
  516. list_del(&nd->list);
  517. sp->members_count--;
  518. mutex_unlock(&sp->members_lock);
  519. config_item_put(i);
  520. }
  521. static void release_node(struct config_item *i)
  522. {
  523. struct dlm_node *nd = config_item_to_node(i);
  524. kfree(nd);
  525. }
  526. static struct dlm_clusters clusters_root = {
  527. .subsys = {
  528. .su_group = {
  529. .cg_item = {
  530. .ci_namebuf = "dlm",
  531. .ci_type = &clusters_type,
  532. },
  533. },
  534. },
  535. };
  536. int __init dlm_config_init(void)
  537. {
  538. config_group_init(&clusters_root.subsys.su_group);
  539. mutex_init(&clusters_root.subsys.su_mutex);
  540. return configfs_register_subsystem(&clusters_root.subsys);
  541. }
  542. void dlm_config_exit(void)
  543. {
  544. configfs_unregister_subsystem(&clusters_root.subsys);
  545. }
  546. /*
  547. * Functions for user space to read/write attributes
  548. */
  549. static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a,
  550. char *buf)
  551. {
  552. struct dlm_cluster *cl = config_item_to_cluster(i);
  553. struct cluster_attribute *cla =
  554. container_of(a, struct cluster_attribute, attr);
  555. return cla->show ? cla->show(cl, buf) : 0;
  556. }
  557. static ssize_t store_cluster(struct config_item *i,
  558. struct configfs_attribute *a,
  559. const char *buf, size_t len)
  560. {
  561. struct dlm_cluster *cl = config_item_to_cluster(i);
  562. struct cluster_attribute *cla =
  563. container_of(a, struct cluster_attribute, attr);
  564. return cla->store ? cla->store(cl, buf, len) : -EINVAL;
  565. }
  566. static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
  567. char *buf)
  568. {
  569. struct dlm_comm *cm = config_item_to_comm(i);
  570. struct comm_attribute *cma =
  571. container_of(a, struct comm_attribute, attr);
  572. return cma->show ? cma->show(cm, buf) : 0;
  573. }
  574. static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a,
  575. const char *buf, size_t len)
  576. {
  577. struct dlm_comm *cm = config_item_to_comm(i);
  578. struct comm_attribute *cma =
  579. container_of(a, struct comm_attribute, attr);
  580. return cma->store ? cma->store(cm, buf, len) : -EINVAL;
  581. }
  582. static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf)
  583. {
  584. return sprintf(buf, "%d\n", cm->nodeid);
  585. }
  586. static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf,
  587. size_t len)
  588. {
  589. cm->nodeid = simple_strtol(buf, NULL, 0);
  590. return len;
  591. }
  592. static ssize_t comm_local_read(struct dlm_comm *cm, char *buf)
  593. {
  594. return sprintf(buf, "%d\n", cm->local);
  595. }
  596. static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf,
  597. size_t len)
  598. {
  599. cm->local= simple_strtol(buf, NULL, 0);
  600. if (cm->local && !local_comm)
  601. local_comm = cm;
  602. return len;
  603. }
  604. static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len)
  605. {
  606. struct sockaddr_storage *addr;
  607. if (len != sizeof(struct sockaddr_storage))
  608. return -EINVAL;
  609. if (cm->addr_count >= DLM_MAX_ADDR_COUNT)
  610. return -ENOSPC;
  611. addr = kzalloc(sizeof(*addr), GFP_NOFS);
  612. if (!addr)
  613. return -ENOMEM;
  614. memcpy(addr, buf, len);
  615. cm->addr[cm->addr_count++] = addr;
  616. return len;
  617. }
  618. static ssize_t comm_addr_list_read(struct dlm_comm *cm, char *buf)
  619. {
  620. ssize_t s;
  621. ssize_t allowance;
  622. int i;
  623. struct sockaddr_storage *addr;
  624. struct sockaddr_in *addr_in;
  625. struct sockaddr_in6 *addr_in6;
  626. /* Taken from ip6_addr_string() defined in lib/vsprintf.c */
  627. char buf0[sizeof("AF_INET6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255\n")];
  628. /* Derived from SIMPLE_ATTR_SIZE of fs/configfs/file.c */
  629. allowance = 4096;
  630. buf[0] = '\0';
  631. for (i = 0; i < cm->addr_count; i++) {
  632. addr = cm->addr[i];
  633. switch(addr->ss_family) {
  634. case AF_INET:
  635. addr_in = (struct sockaddr_in *)addr;
  636. s = sprintf(buf0, "AF_INET %pI4\n", &addr_in->sin_addr.s_addr);
  637. break;
  638. case AF_INET6:
  639. addr_in6 = (struct sockaddr_in6 *)addr;
  640. s = sprintf(buf0, "AF_INET6 %pI6\n", &addr_in6->sin6_addr);
  641. break;
  642. default:
  643. s = sprintf(buf0, "%s\n", "<UNKNOWN>");
  644. break;
  645. }
  646. allowance -= s;
  647. if (allowance >= 0)
  648. strcat(buf, buf0);
  649. else {
  650. allowance += s;
  651. break;
  652. }
  653. }
  654. return 4096 - allowance;
  655. }
  656. static ssize_t show_node(struct config_item *i, struct configfs_attribute *a,
  657. char *buf)
  658. {
  659. struct dlm_node *nd = config_item_to_node(i);
  660. struct node_attribute *nda =
  661. container_of(a, struct node_attribute, attr);
  662. return nda->show ? nda->show(nd, buf) : 0;
  663. }
  664. static ssize_t store_node(struct config_item *i, struct configfs_attribute *a,
  665. const char *buf, size_t len)
  666. {
  667. struct dlm_node *nd = config_item_to_node(i);
  668. struct node_attribute *nda =
  669. container_of(a, struct node_attribute, attr);
  670. return nda->store ? nda->store(nd, buf, len) : -EINVAL;
  671. }
  672. static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf)
  673. {
  674. return sprintf(buf, "%d\n", nd->nodeid);
  675. }
  676. static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
  677. size_t len)
  678. {
  679. nd->nodeid = simple_strtol(buf, NULL, 0);
  680. return len;
  681. }
  682. static ssize_t node_weight_read(struct dlm_node *nd, char *buf)
  683. {
  684. return sprintf(buf, "%d\n", nd->weight);
  685. }
  686. static ssize_t node_weight_write(struct dlm_node *nd, const char *buf,
  687. size_t len)
  688. {
  689. nd->weight = simple_strtol(buf, NULL, 0);
  690. return len;
  691. }
  692. /*
  693. * Functions for the dlm to get the info that's been configured
  694. */
  695. static struct dlm_space *get_space(char *name)
  696. {
  697. struct config_item *i;
  698. if (!space_list)
  699. return NULL;
  700. mutex_lock(&space_list->cg_subsys->su_mutex);
  701. i = config_group_find_item(space_list, name);
  702. mutex_unlock(&space_list->cg_subsys->su_mutex);
  703. return config_item_to_space(i);
  704. }
  705. static void put_space(struct dlm_space *sp)
  706. {
  707. config_item_put(&sp->group.cg_item);
  708. }
  709. static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y)
  710. {
  711. switch (x->ss_family) {
  712. case AF_INET: {
  713. struct sockaddr_in *sinx = (struct sockaddr_in *)x;
  714. struct sockaddr_in *siny = (struct sockaddr_in *)y;
  715. if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr)
  716. return 0;
  717. if (sinx->sin_port != siny->sin_port)
  718. return 0;
  719. break;
  720. }
  721. case AF_INET6: {
  722. struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x;
  723. struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y;
  724. if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr))
  725. return 0;
  726. if (sinx->sin6_port != siny->sin6_port)
  727. return 0;
  728. break;
  729. }
  730. default:
  731. return 0;
  732. }
  733. return 1;
  734. }
  735. static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr)
  736. {
  737. struct config_item *i;
  738. struct dlm_comm *cm = NULL;
  739. int found = 0;
  740. if (!comm_list)
  741. return NULL;
  742. mutex_lock(&clusters_root.subsys.su_mutex);
  743. list_for_each_entry(i, &comm_list->cg_children, ci_entry) {
  744. cm = config_item_to_comm(i);
  745. if (nodeid) {
  746. if (cm->nodeid != nodeid)
  747. continue;
  748. found = 1;
  749. config_item_get(i);
  750. break;
  751. } else {
  752. if (!cm->addr_count || !addr_compare(cm->addr[0], addr))
  753. continue;
  754. found = 1;
  755. config_item_get(i);
  756. break;
  757. }
  758. }
  759. mutex_unlock(&clusters_root.subsys.su_mutex);
  760. if (!found)
  761. cm = NULL;
  762. return cm;
  763. }
  764. static void put_comm(struct dlm_comm *cm)
  765. {
  766. config_item_put(&cm->item);
  767. }
  768. /* caller must free mem */
  769. int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
  770. int **new_out, int *new_count_out)
  771. {
  772. struct dlm_space *sp;
  773. struct dlm_node *nd;
  774. int i = 0, rv = 0, ids_count = 0, new_count = 0;
  775. int *ids, *new;
  776. sp = get_space(lsname);
  777. if (!sp)
  778. return -EEXIST;
  779. mutex_lock(&sp->members_lock);
  780. if (!sp->members_count) {
  781. rv = -EINVAL;
  782. printk(KERN_ERR "dlm: zero members_count\n");
  783. goto out;
  784. }
  785. ids_count = sp->members_count;
  786. ids = kcalloc(ids_count, sizeof(int), GFP_NOFS);
  787. if (!ids) {
  788. rv = -ENOMEM;
  789. goto out;
  790. }
  791. list_for_each_entry(nd, &sp->members, list) {
  792. ids[i++] = nd->nodeid;
  793. if (nd->new)
  794. new_count++;
  795. }
  796. if (ids_count != i)
  797. printk(KERN_ERR "dlm: bad nodeid count %d %d\n", ids_count, i);
  798. if (!new_count)
  799. goto out_ids;
  800. new = kcalloc(new_count, sizeof(int), GFP_NOFS);
  801. if (!new) {
  802. kfree(ids);
  803. rv = -ENOMEM;
  804. goto out;
  805. }
  806. i = 0;
  807. list_for_each_entry(nd, &sp->members, list) {
  808. if (nd->new) {
  809. new[i++] = nd->nodeid;
  810. nd->new = 0;
  811. }
  812. }
  813. *new_count_out = new_count;
  814. *new_out = new;
  815. out_ids:
  816. *ids_count_out = ids_count;
  817. *ids_out = ids;
  818. out:
  819. mutex_unlock(&sp->members_lock);
  820. put_space(sp);
  821. return rv;
  822. }
  823. int dlm_node_weight(char *lsname, int nodeid)
  824. {
  825. struct dlm_space *sp;
  826. struct dlm_node *nd;
  827. int w = -EEXIST;
  828. sp = get_space(lsname);
  829. if (!sp)
  830. goto out;
  831. mutex_lock(&sp->members_lock);
  832. list_for_each_entry(nd, &sp->members, list) {
  833. if (nd->nodeid != nodeid)
  834. continue;
  835. w = nd->weight;
  836. break;
  837. }
  838. mutex_unlock(&sp->members_lock);
  839. put_space(sp);
  840. out:
  841. return w;
  842. }
  843. int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr)
  844. {
  845. struct dlm_comm *cm = get_comm(nodeid, NULL);
  846. if (!cm)
  847. return -EEXIST;
  848. if (!cm->addr_count)
  849. return -ENOENT;
  850. memcpy(addr, cm->addr[0], sizeof(*addr));
  851. put_comm(cm);
  852. return 0;
  853. }
  854. int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid)
  855. {
  856. struct dlm_comm *cm = get_comm(0, addr);
  857. if (!cm)
  858. return -EEXIST;
  859. *nodeid = cm->nodeid;
  860. put_comm(cm);
  861. return 0;
  862. }
  863. int dlm_our_nodeid(void)
  864. {
  865. return local_comm ? local_comm->nodeid : 0;
  866. }
  867. /* num 0 is first addr, num 1 is second addr */
  868. int dlm_our_addr(struct sockaddr_storage *addr, int num)
  869. {
  870. if (!local_comm)
  871. return -1;
  872. if (num + 1 > local_comm->addr_count)
  873. return -1;
  874. memcpy(addr, local_comm->addr[num], sizeof(*addr));
  875. return 0;
  876. }
  877. /* Config file defaults */
  878. #define DEFAULT_TCP_PORT 21064
  879. #define DEFAULT_BUFFER_SIZE 4096
  880. #define DEFAULT_RSBTBL_SIZE 1024
  881. #define DEFAULT_DIRTBL_SIZE 1024
  882. #define DEFAULT_RECOVER_TIMER 5
  883. #define DEFAULT_TOSS_SECS 10
  884. #define DEFAULT_SCAN_SECS 5
  885. #define DEFAULT_LOG_DEBUG 0
  886. #define DEFAULT_PROTOCOL 0
  887. #define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */
  888. #define DEFAULT_WAITWARN_US 0
  889. #define DEFAULT_NEW_RSB_COUNT 128
  890. struct dlm_config_info dlm_config = {
  891. .ci_tcp_port = DEFAULT_TCP_PORT,
  892. .ci_buffer_size = DEFAULT_BUFFER_SIZE,
  893. .ci_rsbtbl_size = DEFAULT_RSBTBL_SIZE,
  894. .ci_dirtbl_size = DEFAULT_DIRTBL_SIZE,
  895. .ci_recover_timer = DEFAULT_RECOVER_TIMER,
  896. .ci_toss_secs = DEFAULT_TOSS_SECS,
  897. .ci_scan_secs = DEFAULT_SCAN_SECS,
  898. .ci_log_debug = DEFAULT_LOG_DEBUG,
  899. .ci_protocol = DEFAULT_PROTOCOL,
  900. .ci_timewarn_cs = DEFAULT_TIMEWARN_CS,
  901. .ci_waitwarn_us = DEFAULT_WAITWARN_US,
  902. .ci_new_rsb_count = DEFAULT_NEW_RSB_COUNT
  903. };