clm.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. /*
  2. * Copyright (c) 2002-2006 MontaVista Software, Inc.
  3. * Copyright (c) 2006 Red Hat, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. * Author: Steven Dake (sdake@mvista.com)
  8. *
  9. * This software licensed under BSD license, the text of which follows:
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. * - Redistributions in binary form must reproduce the above copyright notice,
  17. * this list of conditions and the following disclaimer in the documentation
  18. * and/or other materials provided with the distribution.
  19. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  20. * contributors may be used to endorse or promote products derived from this
  21. * software without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  33. * THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. #include <sys/types.h>
  36. #include <sys/socket.h>
  37. #include <sys/un.h>
  38. #if defined(OPENAIS_LINUX)
  39. #include <sys/sysinfo.h>
  40. #endif
  41. #if defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
  42. #include <sys/sysctl.h>
  43. #endif
  44. #include <sys/ioctl.h>
  45. #include <netinet/in.h>
  46. #include <sys/uio.h>
  47. #include <unistd.h>
  48. #include <fcntl.h>
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #include <errno.h>
  52. #include <signal.h>
  53. #include <time.h>
  54. #include <unistd.h>
  55. #include <netinet/in.h>
  56. #include <arpa/inet.h>
  57. #include "../include/saAis.h"
  58. #include "../include/saClm.h"
  59. #include "../include/ipc_gen.h"
  60. #include "../include/ipc_clm.h"
  61. #include "../include/list.h"
  62. #include "../include/queue.h"
  63. #include "../lcr/lcr_comp.h"
  64. #include "aispoll.h"
  65. #include "totempg.h"
  66. #include "main.h"
  67. #include "mempool.h"
  68. #include "service.h"
  69. #define LOG_SERVICE LOG_SERVICE_CLM
  70. #include "print.h"
  71. enum clm_message_req_types {
  72. MESSAGE_REQ_EXEC_CLM_NODEJOIN = 0
  73. };
  74. SaClmClusterChangesT thisClusterNodeLastChange = SA_CLM_NODE_JOINED;
  75. SaClmClusterNodeT thisClusterNode;
  76. #define NODE_MAX 16
  77. static SaClmClusterNodeT clusterNodes[NODE_MAX];
  78. static int clusterNodeEntries = 0;
  79. static unsigned long long view_current = 0;
  80. static unsigned long long view_initial = 0;
  81. static DECLARE_LIST_INIT (library_notification_send_listhead);
  82. SaClmClusterNodeT *clm_get_by_nodeid (unsigned int node_id)
  83. {
  84. SaClmClusterNodeT *ret = NULL;
  85. int i;
  86. if (node_id == SA_CLM_LOCAL_NODE_ID) {
  87. return (&clusterNodes[0]);
  88. }
  89. for (i = 0; i < clusterNodeEntries; i++) {
  90. if (clusterNodes[i].nodeId == node_id) {
  91. ret = &clusterNodes[i];
  92. break;
  93. }
  94. }
  95. return (ret);
  96. }
  97. /*
  98. * Service Interfaces required by service_message_handler struct
  99. */
  100. static void clm_confchg_fn (
  101. enum totem_configuration_type configuration_type,
  102. struct totem_ip_address *member_list, int member_list_entries,
  103. struct totem_ip_address *left_list, int left_list_entries,
  104. struct totem_ip_address *joined_list, int joined_list_entries,
  105. struct memb_ring_id *ring_id);
  106. static void clm_sync_init (void);
  107. static int clm_sync_process (void);
  108. static void clm_sync_activate (void);
  109. static void clm_sync_abort (void);
  110. static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb);
  111. static int clm_lib_init_fn (void *conn);
  112. static int clm_lib_exit_fn (void *conn);
  113. static void message_handler_req_exec_clm_nodejoin (
  114. void *message,
  115. struct totem_ip_address *source_addr);
  116. static void exec_clm_nodejoin_endian_convert (void *msg);
  117. static void message_handler_req_lib_clm_clustertrack (void *conn, void *message);
  118. static void message_handler_req_lib_clm_trackstop (void *conn, void *message);
  119. static void message_handler_req_lib_clm_nodeget (void *conn, void *message);
  120. static void message_handler_req_lib_clm_nodegetasync (void *conn, void *message);
  121. struct clm_pd {
  122. SaUint8T trackFlags;
  123. int tracking_enabled;
  124. struct list_head list;
  125. void *conn;
  126. };
  127. /*
  128. * Executive Handler Definition
  129. */
  130. static struct openais_lib_handler clm_lib_service[] =
  131. {
  132. { /* 0 */
  133. .lib_handler_fn = message_handler_req_lib_clm_clustertrack,
  134. .response_size = sizeof (struct res_lib_clm_clustertrack),
  135. .response_id = MESSAGE_RES_CLM_TRACKSTART, // TODO RESPONSE
  136. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  137. },
  138. { /* 1 */
  139. .lib_handler_fn = message_handler_req_lib_clm_trackstop,
  140. .response_size = sizeof (struct res_lib_clm_trackstop),
  141. .response_id = MESSAGE_RES_CLM_TRACKSTOP, // TODO RESPONSE
  142. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  143. },
  144. { /* 2 */
  145. .lib_handler_fn = message_handler_req_lib_clm_nodeget,
  146. .response_size = sizeof (struct res_clm_nodeget),
  147. .response_id = MESSAGE_RES_CLM_NODEGET, // TODO RESPONSE
  148. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  149. },
  150. { /* 3 */
  151. .lib_handler_fn = message_handler_req_lib_clm_nodegetasync,
  152. .response_size = sizeof (struct res_clm_nodegetasync),
  153. .response_id = MESSAGE_RES_CLM_NODEGETCALLBACK, // TODO RESPONSE
  154. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  155. }
  156. };
  157. static struct openais_exec_handler clm_exec_service[] =
  158. {
  159. {
  160. .exec_handler_fn = message_handler_req_exec_clm_nodejoin,
  161. .exec_endian_convert_fn = exec_clm_nodejoin_endian_convert
  162. }
  163. };
  164. struct openais_service_handler clm_service_handler = {
  165. .name = (unsigned char*)"openais cluster membership service B.01.01",
  166. .id = CLM_SERVICE,
  167. .private_data_size = sizeof (struct clm_pd),
  168. .lib_init_fn = clm_lib_init_fn,
  169. .lib_exit_fn = clm_lib_exit_fn,
  170. .lib_service = clm_lib_service,
  171. .lib_service_count = sizeof (clm_lib_service) / sizeof (struct openais_lib_handler),
  172. .exec_init_fn = clm_exec_init_fn,
  173. .exec_dump_fn = NULL,
  174. .exec_service = clm_exec_service,
  175. .exec_service_count = sizeof (clm_exec_service) / sizeof (struct openais_exec_handler),
  176. .confchg_fn = clm_confchg_fn,
  177. .sync_init = clm_sync_init,
  178. .sync_process = clm_sync_process,
  179. .sync_activate = clm_sync_activate,
  180. .sync_abort = clm_sync_abort,
  181. };
  182. /*
  183. * Dynamic loader definition
  184. */
  185. static struct openais_service_handler *clm_get_service_handler_ver0 (void);
  186. static struct openais_service_handler_iface_ver0 clm_service_handler_iface = {
  187. .openais_get_service_handler_ver0 = clm_get_service_handler_ver0
  188. };
  189. static struct lcr_iface openais_clm_ver0[1] = {
  190. {
  191. .name = "openais_clm",
  192. .version = 0,
  193. .versions_replace = 0,
  194. .versions_replace_count = 0,
  195. .dependencies = 0,
  196. .dependency_count = 0,
  197. .constructor = NULL,
  198. .destructor = NULL,
  199. .interfaces = NULL
  200. }
  201. };
  202. static struct lcr_comp clm_comp_ver0 = {
  203. .iface_count = 1,
  204. .ifaces = openais_clm_ver0
  205. };
  206. static struct openais_service_handler *clm_get_service_handler_ver0 (void)
  207. {
  208. return (&clm_service_handler);
  209. }
  210. __attribute__ ((constructor)) static void clm_comp_register (void) {
  211. lcr_interfaces_set (&openais_clm_ver0[0], &clm_service_handler_iface);
  212. lcr_component_register (&clm_comp_ver0);
  213. }
  214. struct req_exec_clm_nodejoin {
  215. struct req_header header;
  216. SaClmClusterNodeT clusterNode;
  217. };
  218. static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb)
  219. {
  220. log_init ("CLM");
  221. memset (clusterNodes, 0, sizeof (SaClmClusterNodeT) * NODE_MAX);
  222. /*
  223. * Build local cluster node data structure
  224. */
  225. sprintf ((char *)thisClusterNode.nodeAddress.value, "%s", totemip_print (this_ip));
  226. thisClusterNode.nodeAddress.length = strlen ((char *)thisClusterNode.nodeAddress.value);
  227. if (this_ip->family == AF_INET) {
  228. thisClusterNode.nodeAddress.family = SA_CLM_AF_INET;
  229. } else
  230. if (this_ip->family == AF_INET6) {
  231. thisClusterNode.nodeAddress.family = SA_CLM_AF_INET6;
  232. } else {
  233. assert (0);
  234. }
  235. strcpy ((char *)thisClusterNode.nodeName.value, (char *)thisClusterNode.nodeAddress.value);
  236. thisClusterNode.nodeName.length = thisClusterNode.nodeAddress.length;
  237. thisClusterNode.nodeId = this_ip->nodeid;
  238. thisClusterNode.member = 1;
  239. {
  240. #if defined(OPENAIS_LINUX)
  241. struct sysinfo s_info;
  242. time_t current_time;
  243. sysinfo (&s_info);
  244. current_time = time (NULL);
  245. /* (currenttime (s) - uptime (s)) * 1 billion (ns) / 1 (s) */
  246. thisClusterNode.bootTimestamp = ((SaTimeT)(current_time - s_info.uptime)) * 1000000000;
  247. #elif defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
  248. int mib[2] = { CTL_KERN, KERN_BOOTTIME };
  249. struct timeval boot_time;
  250. size_t size = sizeof(boot_time);
  251. if ( sysctl(mib, 2, &boot_time, &size, NULL, 0) == -1 )
  252. boot_time.tv_sec = time (NULL);
  253. /* (currenttime (s) - uptime (s)) * 1 billion (ns) / 1 (s) */
  254. thisClusterNode.bootTimestamp = ((SaTimeT)boot_time.tv_sec) * 1000000000;
  255. #else /* defined(CTL_KERN) && defined(KERN_BOOTTIME) */
  256. #warning "no bootime support"
  257. #endif
  258. }
  259. memcpy (&clusterNodes[0], &thisClusterNode, sizeof (SaClmClusterNodeT));
  260. clusterNodeEntries = 1;
  261. main_clm_get_by_nodeid = clm_get_by_nodeid;
  262. return (0);
  263. }
  264. static int clm_lib_exit_fn (void *conn)
  265. {
  266. struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
  267. /*
  268. * Delete track entry if there is one
  269. */
  270. list_del (&clm_pd->list);
  271. clm_pd->conn = conn;
  272. return (0);
  273. }
  274. static void library_notification_send (SaClmClusterNotificationT *cluster_notification_entries,
  275. int notify_entries)
  276. {
  277. struct res_lib_clm_clustertrack res_lib_clm_clustertrack;
  278. struct clm_pd *clm_pd;
  279. struct list_head *list;
  280. int i;
  281. if (notify_entries == 0) {
  282. return;
  283. }
  284. res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack);
  285. res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
  286. res_lib_clm_clustertrack.header.error = SA_AIS_OK;
  287. res_lib_clm_clustertrack.view = view_current;
  288. for (list = library_notification_send_listhead.next;
  289. list != &library_notification_send_listhead;
  290. list = list->next) {
  291. clm_pd = list_entry (list, struct clm_pd, list);
  292. /*
  293. * Track current and changes
  294. */
  295. if (clm_pd->trackFlags & SA_TRACK_CHANGES) {
  296. /*
  297. * Copy all cluster nodes
  298. */
  299. for (i = 0; i < clusterNodeEntries; i++) {
  300. memcpy (&res_lib_clm_clustertrack.notification[i].clusterNode,
  301. &clusterNodes[i], sizeof (SaClmClusterNodeT));
  302. res_lib_clm_clustertrack.notification[i].clusterChange = SA_CLM_NODE_NO_CHANGE;
  303. res_lib_clm_clustertrack.notification[i].clusterNode.member = 1;
  304. }
  305. /*
  306. * Copy change_only notificaiton
  307. */
  308. res_lib_clm_clustertrack.numberOfItems = notify_entries + i;
  309. memcpy (&res_lib_clm_clustertrack.notification[i],
  310. cluster_notification_entries,
  311. sizeof (SaClmClusterNotificationT) * notify_entries);
  312. } else
  313. /*
  314. * Track only changes
  315. */
  316. if (clm_pd->trackFlags & SA_TRACK_CHANGES_ONLY) {
  317. res_lib_clm_clustertrack.numberOfItems = notify_entries;
  318. memcpy (&res_lib_clm_clustertrack.notification,
  319. cluster_notification_entries,
  320. sizeof (SaClmClusterNotificationT) * notify_entries);
  321. }
  322. /*
  323. * Send notifications to all CLM listeners
  324. */
  325. openais_conn_send_response (clm_pd->conn,
  326. &res_lib_clm_clustertrack,
  327. sizeof (struct res_lib_clm_clustertrack));
  328. }
  329. }
  330. static void notification_join (SaClmClusterNodeT *cluster_node)
  331. {
  332. SaClmClusterNotificationT notification;
  333. /*
  334. * Generate notification element
  335. */
  336. notification.clusterChange = SA_CLM_NODE_JOINED;
  337. notification.clusterNode.member = 1;
  338. memcpy (&notification.clusterNode, cluster_node,
  339. sizeof (SaClmClusterNodeT));
  340. library_notification_send (&notification, 1);
  341. }
  342. static void libraryNotificationLeave (SaClmNodeIdT *nodes, int nodes_entries)
  343. {
  344. SaClmClusterNotificationT clusterNotification[NODE_MAX];
  345. int i, j;
  346. int notifyEntries;
  347. /*
  348. * Determine notification list
  349. */
  350. for (notifyEntries = 0, i = 0; i < clusterNodeEntries; i++) {
  351. for (j = 0; j < nodes_entries; j++) {
  352. if (clusterNodes[i].nodeId == nodes[j]) {
  353. memcpy (&clusterNotification[notifyEntries].clusterNode,
  354. &clusterNodes[i],
  355. sizeof (SaClmClusterNodeT));
  356. clusterNotification[notifyEntries].clusterChange = SA_CLM_NODE_LEFT;
  357. clusterNotification[notifyEntries].clusterNode.member = 0;
  358. notifyEntries += 1;
  359. break;
  360. }
  361. }
  362. }
  363. /*
  364. * Remove entries from clusterNodes array
  365. */
  366. for (i = 0; i < nodes_entries; i++) {
  367. for (j = 0; j < clusterNodeEntries;) {
  368. if (nodes[i] == clusterNodes[j].nodeId) {
  369. clusterNodeEntries -= 1;
  370. memmove (&clusterNodes[j], &clusterNodes[j + 1],
  371. (clusterNodeEntries - j) * sizeof (SaClmClusterNodeT));
  372. } else {
  373. /*
  374. * next clusterNode entry
  375. */
  376. j++;
  377. }
  378. }
  379. }
  380. library_notification_send (clusterNotification, notifyEntries);
  381. }
  382. static int clm_nodejoin_send (void)
  383. {
  384. struct req_exec_clm_nodejoin req_exec_clm_nodejoin;
  385. struct iovec req_exec_clm_iovec;
  386. int result;
  387. req_exec_clm_nodejoin.header.size = sizeof (struct req_exec_clm_nodejoin);
  388. req_exec_clm_nodejoin.header.id =
  389. SERVICE_ID_MAKE (CLM_SERVICE, MESSAGE_REQ_EXEC_CLM_NODEJOIN);
  390. // TODO dont use memcpy, use iovecs !!
  391. thisClusterNode.initialViewNumber = view_initial;
  392. memcpy (&req_exec_clm_nodejoin.clusterNode, &thisClusterNode,
  393. sizeof (SaClmClusterNodeT));
  394. req_exec_clm_iovec.iov_base = (char *)&req_exec_clm_nodejoin;
  395. req_exec_clm_iovec.iov_len = sizeof (req_exec_clm_nodejoin);
  396. result = totempg_groups_mcast_joined (openais_group_handle, &req_exec_clm_iovec, 1, TOTEMPG_AGREED);
  397. return (result);
  398. }
  399. static void clm_confchg_fn (
  400. enum totem_configuration_type configuration_type,
  401. struct totem_ip_address *member_list, int member_list_entries,
  402. struct totem_ip_address *left_list, int left_list_entries,
  403. struct totem_ip_address *joined_list, int joined_list_entries,
  404. struct memb_ring_id *ring_id)
  405. {
  406. int i;
  407. SaClmNodeIdT nodes[NODE_MAX];
  408. view_current = ring_id->seq / 4;
  409. if (view_initial == 0) {
  410. view_initial = ring_id->seq / 4;
  411. }
  412. log_printf (LOG_LEVEL_NOTICE, "CLM CONFIGURATION CHANGE\n");
  413. log_printf (LOG_LEVEL_NOTICE, "New Configuration:\n");
  414. for (i = 0; i < member_list_entries; i++) {
  415. log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totemip_print (&member_list[i]));
  416. }
  417. log_printf (LOG_LEVEL_NOTICE, "Members Left:\n");
  418. for (i = 0; i < left_list_entries; i++) {
  419. log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totemip_print (&left_list[i]));
  420. }
  421. log_printf (LOG_LEVEL_NOTICE, "Members Joined:\n");
  422. for (i = 0; i < joined_list_entries; i++) {
  423. log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totemip_print (&joined_list[i]));
  424. }
  425. for (i = 0; i < left_list_entries; i++) {
  426. nodes[i] = left_list[i].nodeid;
  427. }
  428. libraryNotificationLeave (nodes, i);
  429. /*
  430. * Load the thisClusterNode data structure in case we are
  431. * transitioning to network interface up or down
  432. */
  433. sprintf ((char *)thisClusterNode.nodeAddress.value, "%s", totemip_print (this_ip));
  434. thisClusterNode.nodeAddress.length = strlen ((char *)thisClusterNode.nodeAddress.value);
  435. if (this_ip->family == AF_INET) {
  436. thisClusterNode.nodeAddress.family = SA_CLM_AF_INET;
  437. } else
  438. if (this_ip->family == AF_INET6) {
  439. thisClusterNode.nodeAddress.family = SA_CLM_AF_INET6;
  440. } else {
  441. assert (0);
  442. }
  443. strcpy ((char *)thisClusterNode.nodeName.value,
  444. (char *)thisClusterNode.nodeAddress.value);
  445. thisClusterNode.nodeName.length = thisClusterNode.nodeAddress.length;
  446. thisClusterNode.nodeId = this_ip->nodeid;
  447. }
  448. /*
  449. * This is a noop for this service
  450. */
  451. static void clm_sync_init (void)
  452. {
  453. return;
  454. }
  455. /*
  456. * If a processor joined in the configuration change and clm_sync_activate hasn't
  457. * yet been called, issue a node join to share CLM specific data about the processor
  458. */
  459. static int clm_sync_process (void)
  460. {
  461. /*
  462. * Send node information to other nodes
  463. */
  464. return (clm_nodejoin_send ());
  465. }
  466. /*
  467. * This is a noop for this service
  468. */
  469. static void clm_sync_activate (void)
  470. {
  471. return;
  472. }
  473. /*
  474. * This is a noop for this service
  475. */
  476. static void clm_sync_abort (void)
  477. {
  478. return;
  479. }
  480. static void exec_clm_nodejoin_endian_convert (void *msg)
  481. {
  482. }
  483. static void message_handler_req_exec_clm_nodejoin (
  484. void *message,
  485. struct totem_ip_address *source_addr)
  486. {
  487. struct req_exec_clm_nodejoin *req_exec_clm_nodejoin = (struct req_exec_clm_nodejoin *)message;
  488. int found = 0;
  489. int i;
  490. log_printf (LOG_LEVEL_NOTICE, "got nodejoin message %s\n", req_exec_clm_nodejoin->clusterNode.nodeName.value);
  491. /*
  492. * Determine if nodejoin already received
  493. */
  494. for (found = 0, i = 0; i < clusterNodeEntries; i++) {
  495. if (clusterNodes[i].nodeId == req_exec_clm_nodejoin->clusterNode.nodeId) {
  496. found = 1;
  497. }
  498. }
  499. /*
  500. * If not received, add to internal list
  501. */
  502. if (found == 0) {
  503. notification_join (&req_exec_clm_nodejoin->clusterNode);
  504. memcpy (&clusterNodes[clusterNodeEntries],
  505. &req_exec_clm_nodejoin->clusterNode,
  506. sizeof (SaClmClusterNodeT));
  507. clusterNodeEntries += 1;
  508. }
  509. }
  510. static int clm_lib_init_fn (void *conn)
  511. {
  512. log_printf (LOG_LEVEL_DEBUG, "Got request to initalize cluster membership service.\n");
  513. struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
  514. list_init (&clm_pd->list);
  515. return (0);
  516. }
  517. static void message_handler_req_lib_clm_clustertrack (void *conn, void *msg)
  518. {
  519. struct req_lib_clm_clustertrack *req_lib_clm_clustertrack = (struct req_lib_clm_clustertrack *)msg;
  520. struct res_lib_clm_clustertrack res_lib_clm_clustertrack;
  521. struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
  522. int i;
  523. res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack);
  524. res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKSTART;
  525. res_lib_clm_clustertrack.header.error = SA_AIS_OK;
  526. res_lib_clm_clustertrack.view = view_current;
  527. res_lib_clm_clustertrack.numberOfItems = 0;
  528. if (req_lib_clm_clustertrack->trackFlags & SA_TRACK_CURRENT) {
  529. for (i = 0; i < clusterNodeEntries; i++) {
  530. res_lib_clm_clustertrack.notification[i].clusterChange = SA_CLM_NODE_NO_CHANGE;
  531. memcpy (&res_lib_clm_clustertrack.notification[i].clusterNode,
  532. &clusterNodes[i], sizeof (SaClmClusterNodeT));
  533. }
  534. res_lib_clm_clustertrack.numberOfItems = clusterNodeEntries;
  535. }
  536. /*
  537. * Record requests for cluster tracking
  538. */
  539. if (req_lib_clm_clustertrack->trackFlags & SA_TRACK_CHANGES ||
  540. req_lib_clm_clustertrack->trackFlags & SA_TRACK_CHANGES_ONLY) {
  541. clm_pd->trackFlags = req_lib_clm_clustertrack->trackFlags;
  542. clm_pd->tracking_enabled = 1;
  543. list_add (&clm_pd->list, &library_notification_send_listhead);
  544. }
  545. openais_conn_send_response (conn, &res_lib_clm_clustertrack,
  546. sizeof (struct res_lib_clm_clustertrack));
  547. if (req_lib_clm_clustertrack->return_in_callback) {
  548. res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
  549. openais_conn_send_response (
  550. openais_conn_partner_get (conn),
  551. &res_lib_clm_clustertrack,
  552. sizeof (struct res_lib_clm_clustertrack));
  553. }
  554. }
  555. static void message_handler_req_lib_clm_trackstop (void *conn, void *msg)
  556. {
  557. struct res_lib_clm_trackstop res_lib_clm_trackstop;
  558. struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
  559. res_lib_clm_trackstop.header.size = sizeof (struct res_lib_clm_trackstop);
  560. res_lib_clm_trackstop.header.id = MESSAGE_RES_CLM_TRACKSTOP;
  561. if (clm_pd->tracking_enabled) {
  562. res_lib_clm_trackstop.header.error = SA_AIS_OK;
  563. clm_pd->tracking_enabled = 0;
  564. } else {
  565. res_lib_clm_trackstop.header.error = SA_AIS_ERR_NOT_EXIST;
  566. }
  567. list_del (&clm_pd->list);
  568. list_init (&clm_pd->list);
  569. openais_conn_send_response (conn, &res_lib_clm_trackstop,
  570. sizeof (struct res_lib_clm_trackstop));
  571. }
  572. static void message_handler_req_lib_clm_nodeget (void *conn, void *msg)
  573. {
  574. struct req_lib_clm_nodeget *req_lib_clm_nodeget = (struct req_lib_clm_nodeget *)msg;
  575. struct res_clm_nodeget res_clm_nodeget;
  576. SaClmClusterNodeT *clusterNode = 0;
  577. int valid = 0;
  578. int i;
  579. log_printf (LOG_LEVEL_NOTICE, "nodeget: trying to find node %x\n", (int)req_lib_clm_nodeget->nodeId);
  580. if (req_lib_clm_nodeget->nodeId == SA_CLM_LOCAL_NODE_ID) {
  581. clusterNode = &clusterNodes[0];
  582. valid = 1;
  583. } else
  584. for (i = 0; i < clusterNodeEntries; i++) {
  585. if (clusterNodes[i].nodeId == req_lib_clm_nodeget->nodeId) {
  586. log_printf (LOG_LEVEL_DEBUG, "found host that matches one desired in nodeget.\n");
  587. clusterNode = &clusterNodes[i];
  588. valid = 1;
  589. break;
  590. }
  591. }
  592. res_clm_nodeget.header.size = sizeof (struct res_clm_nodeget);
  593. res_clm_nodeget.header.id = MESSAGE_RES_CLM_NODEGET;
  594. res_clm_nodeget.header.error = SA_AIS_OK;
  595. res_clm_nodeget.invocation = req_lib_clm_nodeget->invocation;
  596. res_clm_nodeget.valid = valid;
  597. if (valid) {
  598. memcpy (&res_clm_nodeget.clusterNode, clusterNode, sizeof (SaClmClusterNodeT));
  599. }
  600. openais_conn_send_response (conn, &res_clm_nodeget, sizeof (struct res_clm_nodeget));
  601. }
  602. static void message_handler_req_lib_clm_nodegetasync (void *conn, void *msg)
  603. {
  604. struct req_lib_clm_nodegetasync *req_lib_clm_nodegetasync = (struct req_lib_clm_nodegetasync *)msg;
  605. struct res_clm_nodegetasync res_clm_nodegetasync;
  606. struct res_clm_nodegetcallback res_clm_nodegetcallback;
  607. SaClmClusterNodeT *clusterNode = 0;
  608. int error = SA_AIS_ERR_INVALID_PARAM;
  609. int i;
  610. log_printf (LOG_LEVEL_DEBUG, "nodeget: trying to find node %x\n", (int)req_lib_clm_nodegetasync->nodeId);
  611. if (req_lib_clm_nodegetasync->nodeId == SA_CLM_LOCAL_NODE_ID) {
  612. clusterNode = &clusterNodes[0];
  613. error = SA_AIS_OK;
  614. } else
  615. for (i = 0; i < clusterNodeEntries; i++) {
  616. if (clusterNodes[i].nodeId == req_lib_clm_nodegetasync->nodeId) {
  617. log_printf (LOG_LEVEL_DEBUG, "found host that matches one desired in nodeget.\n");
  618. clusterNode = &clusterNodes[i];
  619. error = SA_AIS_OK;
  620. break;
  621. }
  622. }
  623. /*
  624. * Respond to library request
  625. */
  626. res_clm_nodegetasync.header.size = sizeof (struct res_clm_nodegetasync);
  627. res_clm_nodegetasync.header.id = MESSAGE_RES_CLM_NODEGETASYNC;
  628. res_clm_nodegetasync.header.error = SA_AIS_OK;
  629. openais_conn_send_response (conn, &res_clm_nodegetasync,
  630. sizeof (struct res_clm_nodegetasync));
  631. /*
  632. * Send async response
  633. */
  634. res_clm_nodegetcallback.header.size = sizeof (struct res_clm_nodegetcallback);
  635. res_clm_nodegetcallback.header.id = MESSAGE_RES_CLM_NODEGETCALLBACK;
  636. res_clm_nodegetcallback.header.error = error;
  637. res_clm_nodegetcallback.invocation = req_lib_clm_nodegetasync->invocation;
  638. if (error == SA_AIS_OK) {
  639. memcpy (&res_clm_nodegetcallback.clusterNode, clusterNode,
  640. sizeof (SaClmClusterNodeT));
  641. }
  642. openais_conn_send_response (openais_conn_partner_get (conn),
  643. &res_clm_nodegetcallback,
  644. sizeof (struct res_clm_nodegetcallback));
  645. }