config.c 24 KB

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