Patch to remove segfault on the exiting of a service.
[openais.git] / exec / clm.c
blob16b4ca12547933e1b62c6f6c3cc155a0fc7c4da2
1 /*
2 * Copyright (c) 2002-2006 MontaVista Software, Inc.
3 * Copyright (c) 2006-2007 Red Hat, Inc.
4 * Copyright (C) 2006 Sun Microsystems, Inc.
6 * All rights reserved.
8 * Author: Steven Dake (sdake@redhat.com)
10 * This software licensed under BSD license, the text of which follows:
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * - Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * - Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * - Neither the name of the MontaVista Software, Inc. nor the names of its
21 * contributors may be used to endorse or promote products derived from this
22 * software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 * THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/un.h>
39 #if defined(OPENAIS_LINUX)
40 #include <sys/sysinfo.h>
41 #elif defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
42 #include <sys/sysctl.h>
43 #elif defined(OPENAIS_SOLARIS)
44 #include <utmpx.h>
45 #endif
46 #include <sys/ioctl.h>
47 #include <netinet/in.h>
48 #include <sys/uio.h>
49 #include <unistd.h>
50 #include <fcntl.h>
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <errno.h>
54 #include <signal.h>
55 #include <time.h>
56 #include <unistd.h>
57 #include <netinet/in.h>
58 #include <arpa/inet.h>
60 #include "swab.h"
61 #include "totem.h"
62 #include "../include/saAis.h"
63 #include "../include/saClm.h"
64 #include "../include/ipc_gen.h"
65 #include "../include/ipc_clm.h"
66 #include "../include/mar_gen.h"
67 #include "../include/mar_clm.h"
68 #include "../include/list.h"
69 #include "../include/queue.h"
70 #include "../lcr/lcr_comp.h"
71 #include "totempg.h"
72 #include "main.h"
73 #include "flow.h"
74 #include "tlist.h"
75 #include "ipc.h"
76 #include "mempool.h"
77 #include "objdb.h"
78 #include "service.h"
79 #include "logsys.h"
81 LOGSYS_DECLARE_SUBSYS ("CLM", LOG_INFO);
84 enum clm_message_req_types {
85 MESSAGE_REQ_EXEC_CLM_NODEJOIN = 0
88 mar_clm_cluster_change_t my_cluster_node_last_change = SA_CLM_NODE_JOINED;
90 mar_clm_cluster_node_t my_cluster_node;
92 static mar_clm_cluster_node_t cluster_node_entries[PROCESSOR_COUNT_MAX];
94 static int cluster_node_count = 0;
96 static unsigned long long view_current = 0;
98 static unsigned long long view_initial = 0;
100 static DECLARE_LIST_INIT (library_notification_send_listhead);
102 SaClmClusterNodeT *clm_get_by_nodeid (unsigned int node_id)
104 static SaClmClusterNodeT cluster_node;
105 int i;
107 if (node_id == SA_CLM_LOCAL_NODE_ID) {
108 marshall_from_mar_clm_cluster_node_t (
109 &cluster_node,
110 &cluster_node_entries[0]);
111 return (&cluster_node);
113 for (i = 0; i < cluster_node_count; i++) {
114 if (cluster_node_entries[i].node_id == node_id) {
115 marshall_from_mar_clm_cluster_node_t (
116 &cluster_node,
117 &cluster_node_entries[i]);
118 return (&cluster_node);
119 break;
122 return (NULL);
126 * Service Interfaces required by service_message_handler struct
128 static void clm_confchg_fn (
129 enum totem_configuration_type configuration_type,
130 unsigned int *member_list, int member_list_entries,
131 unsigned int *left_list, int left_list_entries,
132 unsigned int *joined_list, int joined_list_entries,
133 struct memb_ring_id *ring_id);
135 static void clm_sync_init (void);
137 static int clm_sync_process (void);
139 static void clm_sync_activate (void);
141 static void clm_sync_abort (void);
143 static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb);
145 static int clm_exec_exit_fn (struct objdb_iface_ver0 *objdb);
147 static int clm_lib_init_fn (void *conn);
149 static int clm_lib_exit_fn (void *conn);
151 static void message_handler_req_exec_clm_nodejoin (
152 void *message,
153 unsigned int nodeid);
155 static void exec_clm_nodejoin_endian_convert (void *msg);
157 static void message_handler_req_lib_clm_clustertrack (void *conn, void *message);
159 static void message_handler_req_lib_clm_trackstop (void *conn, void *message);
161 static void message_handler_req_lib_clm_nodeget (void *conn, void *message);
163 static void message_handler_req_lib_clm_nodegetasync (void *conn, void *message);
165 struct clm_pd {
166 unsigned char track_flags;
167 int tracking_enabled;
168 struct list_head list;
169 void *conn;
173 * Executive Handler Definition
175 static struct openais_lib_handler clm_lib_service[] =
177 { /* 0 */
178 .lib_handler_fn = message_handler_req_lib_clm_clustertrack,
179 .response_size = sizeof (struct res_lib_clm_clustertrack),
180 .response_id = MESSAGE_RES_CLM_TRACKSTART, // TODO RESPONSE
181 .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
183 { /* 1 */
184 .lib_handler_fn = message_handler_req_lib_clm_trackstop,
185 .response_size = sizeof (struct res_lib_clm_trackstop),
186 .response_id = MESSAGE_RES_CLM_TRACKSTOP, // TODO RESPONSE
187 .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
189 { /* 2 */
190 .lib_handler_fn = message_handler_req_lib_clm_nodeget,
191 .response_size = sizeof (struct res_clm_nodeget),
192 .response_id = MESSAGE_RES_CLM_NODEGET, // TODO RESPONSE
193 .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
195 { /* 3 */
196 .lib_handler_fn = message_handler_req_lib_clm_nodegetasync,
197 .response_size = sizeof (struct res_clm_nodegetasync),
198 .response_id = MESSAGE_RES_CLM_NODEGETCALLBACK, // TODO RESPONSE
199 .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
203 static struct openais_exec_handler clm_exec_service[] =
206 .exec_handler_fn = message_handler_req_exec_clm_nodejoin,
207 .exec_endian_convert_fn = exec_clm_nodejoin_endian_convert
211 struct openais_service_handler clm_service_handler = {
212 .name = "openais cluster membership service B.01.01",
213 .id = CLM_SERVICE,
214 .private_data_size = sizeof (struct clm_pd),
215 .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED,
216 .lib_init_fn = clm_lib_init_fn,
217 .lib_exit_fn = clm_lib_exit_fn,
218 .lib_service = clm_lib_service,
219 .lib_service_count = sizeof (clm_lib_service) / sizeof (struct openais_lib_handler),
220 .exec_init_fn = clm_exec_init_fn,
221 .exec_exit_fn = clm_exec_exit_fn,
222 .exec_dump_fn = NULL,
223 .exec_service = clm_exec_service,
224 .exec_service_count = sizeof (clm_exec_service) / sizeof (struct openais_exec_handler),
225 .confchg_fn = clm_confchg_fn,
226 .sync_init = clm_sync_init,
227 .sync_process = clm_sync_process,
228 .sync_activate = clm_sync_activate,
229 .sync_abort = clm_sync_abort,
233 * Dynamic loader definition
235 static struct openais_service_handler *clm_get_service_handler_ver0 (void);
237 static struct openais_service_handler_iface_ver0 clm_service_handler_iface = {
238 .openais_get_service_handler_ver0 = clm_get_service_handler_ver0
241 static struct lcr_iface openais_clm_ver0[1] = {
243 .name = "openais_clm",
244 .version = 0,
245 .versions_replace = 0,
246 .versions_replace_count = 0,
247 .dependencies = 0,
248 .dependency_count = 0,
249 .constructor = NULL,
250 .destructor = NULL,
251 .interfaces = NULL
255 static struct lcr_comp clm_comp_ver0 = {
256 .iface_count = 1,
257 .ifaces = openais_clm_ver0
260 static struct openais_service_handler *clm_get_service_handler_ver0 (void)
262 return (&clm_service_handler);
265 __attribute__ ((constructor)) static void clm_comp_register (void) {
266 lcr_interfaces_set (&openais_clm_ver0[0], &clm_service_handler_iface);
268 lcr_component_register (&clm_comp_ver0);
271 struct req_exec_clm_nodejoin {
272 mar_req_header_t header __attribute__((aligned(8)));
273 mar_clm_cluster_node_t cluster_node __attribute__((aligned(8)));
276 static void my_cluster_node_load (void)
278 struct totem_ip_address interfaces[INTERFACE_MAX];
279 unsigned int iface_count;
280 char **status;
281 const char *iface_string;
283 totempg_ifaces_get (
284 totempg_my_nodeid_get (),
285 interfaces,
286 &status,
287 &iface_count);
289 iface_string = totemip_print (&interfaces[0]);
291 sprintf ((char *)my_cluster_node.node_address.value, "%s",
292 iface_string);
293 my_cluster_node.node_address.length =
294 strlen ((char *)my_cluster_node.node_address.value);
295 if (totempg_my_family_get () == AF_INET) {
296 my_cluster_node.node_address.family = SA_CLM_AF_INET;
297 } else
298 if (totempg_my_family_get () == AF_INET6) {
299 my_cluster_node.node_address.family = SA_CLM_AF_INET6;
300 } else {
301 assert (0);
304 strcpy ((char *)my_cluster_node.node_name.value,
305 (char *)my_cluster_node.node_address.value);
306 my_cluster_node.node_name.length =
307 my_cluster_node.node_address.length;
308 my_cluster_node.node_id = totempg_my_nodeid_get ();
309 my_cluster_node.member = 1;
311 memcpy (&cluster_node_entries[0], &my_cluster_node,
312 sizeof (mar_clm_cluster_node_t));
315 static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb)
317 memset (cluster_node_entries, 0,
318 sizeof (mar_clm_cluster_node_t) * PROCESSOR_COUNT_MAX);
321 #ifndef NANOSEC
322 #define NANOSEC 1000000000
323 #endif
324 #if defined(OPENAIS_LINUX)
325 struct sysinfo s_info;
326 time_t current_time;
327 sysinfo (&s_info);
328 current_time = time (NULL);
329 /* (currenttime (s) - uptime (s)) * 1 billion (ns) / 1 (s) */
330 my_cluster_node.boot_timestamp = ((SaTimeT)(current_time - s_info.uptime)) * NANOSEC;
331 #elif defined(OPENAIS_BSD) || defined(OPENAIS_DARWIN)
332 int mib[2] = { CTL_KERN, KERN_BOOTTIME };
333 struct timeval boot_time;
334 size_t size = sizeof(boot_time);
336 if ( sysctl(mib, 2, &boot_time, &size, NULL, 0) == -1 )
337 boot_time.tv_sec = time (NULL);
338 /* (currenttime (s) - uptime (s)) * 1 billion (ns) / 1 (s) */
339 my_cluster_node.boot_timestamp = ((SaTimeT)boot_time.tv_sec) * NANOSEC;
340 #elif defined(OPENAIS_SOLARIS)
341 struct utmpx ut, *utp;
342 ut.ut_type = BOOT_TIME;
343 setutxent();
344 if ((utp = getutxid(&ut)) == NULL) {
345 my_cluster_node.boot_timestamp = ((SaTimeT)time(NULL)) * NANOSEC;
346 } else {
347 my_cluster_node.boot_timestamp = ((SaTimeT)utp->ut_xtime) * NANOSEC;
349 endutxent();
350 #else
351 #warning "no bootime support"
352 #endif
355 cluster_node_count = 1;
357 main_clm_get_by_nodeid = clm_get_by_nodeid;
358 return (0);
361 static int clm_exec_exit_fn (struct objdb_iface_ver0 *objdb)
363 return (0);
366 static int clm_lib_exit_fn (void *conn)
368 struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
370 * Delete track entry if there is one
372 list_del (&clm_pd->list);
373 clm_pd->conn = conn;
375 return (0);
378 static void library_notification_send (
379 mar_clm_cluster_notification_t *cluster_notification_entries,
380 int notify_count)
382 struct res_lib_clm_clustertrack res_lib_clm_clustertrack;
383 struct clm_pd *clm_pd;
384 struct list_head *list;
385 int i;
387 if (notify_count == 0) {
388 return;
391 res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack);
392 res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
393 res_lib_clm_clustertrack.header.error = SA_AIS_OK;
394 res_lib_clm_clustertrack.view = view_current;
396 for (list = library_notification_send_listhead.next;
397 list != &library_notification_send_listhead;
398 list = list->next) {
400 clm_pd = list_entry (list, struct clm_pd, list);
403 * Track current and changes
405 if (clm_pd->track_flags & SA_TRACK_CHANGES) {
407 * Copy all cluster nodes
409 for (i = 0; i < cluster_node_count; i++) {
410 memcpy (&res_lib_clm_clustertrack.notification[i].cluster_node,
411 &cluster_node_entries[i], sizeof (mar_clm_cluster_node_t));
412 res_lib_clm_clustertrack.notification[i].cluster_change = SA_CLM_NODE_NO_CHANGE;
413 res_lib_clm_clustertrack.notification[i].cluster_node.member = 1;
416 * Copy change_only notificaiton
418 res_lib_clm_clustertrack.number_of_items = notify_count + i;
419 memcpy (&res_lib_clm_clustertrack.notification[i],
420 cluster_notification_entries,
421 sizeof (mar_clm_cluster_notification_t) * notify_count);
422 } else
425 * Track only changes
427 if (clm_pd->track_flags & SA_TRACK_CHANGES_ONLY) {
428 res_lib_clm_clustertrack.number_of_items = notify_count;
429 memcpy (&res_lib_clm_clustertrack.notification,
430 cluster_notification_entries,
431 sizeof (mar_clm_cluster_notification_t) * notify_count);
435 * Send notifications to all CLM listeners
437 openais_conn_send_response (
438 clm_pd->conn,
439 &res_lib_clm_clustertrack,
440 sizeof (struct res_lib_clm_clustertrack));
444 static void notification_join (mar_clm_cluster_node_t *cluster_node)
446 mar_clm_cluster_notification_t notification;
449 * Generate notification element
451 notification.cluster_change = SA_CLM_NODE_JOINED;
452 notification.cluster_node.member = 1;
453 memcpy (&notification.cluster_node, cluster_node,
454 sizeof (mar_clm_cluster_node_t));
455 library_notification_send (&notification, 1);
458 static void lib_notification_leave (unsigned int *nodes, int nodes_entries)
460 mar_clm_cluster_notification_t cluster_notification[PROCESSOR_COUNT_MAX];
461 int i, j;
462 int notify_count;
465 * Determine notification list
467 for (notify_count = 0, i = 0; i < cluster_node_count; i++) {
468 for (j = 0; j < nodes_entries; j++) {
469 if (cluster_node_entries[i].node_id == nodes[j]) {
470 memcpy (&cluster_notification[notify_count].cluster_node,
471 &cluster_node_entries[i],
472 sizeof (mar_clm_cluster_node_t));
473 cluster_notification[notify_count].cluster_change = SA_CLM_NODE_LEFT;
474 cluster_notification[notify_count].cluster_node.member = 0;
475 notify_count += 1;
476 break;
482 * Remove entries from cluster_node_entries array
484 for (i = 0; i < nodes_entries; i++) {
485 for (j = 0; j < cluster_node_count;) {
486 if (nodes[i] == cluster_node_entries[j].node_id) {
487 cluster_node_count -= 1;
488 memmove (&cluster_node_entries[j], &cluster_node_entries[j + 1],
489 (cluster_node_count - j) * sizeof (mar_clm_cluster_node_t));
490 } else {
492 * next cluster_node entry
494 j++;
499 library_notification_send (cluster_notification, notify_count);
502 static int clm_nodejoin_send (void)
504 struct req_exec_clm_nodejoin req_exec_clm_nodejoin;
505 struct iovec req_exec_clm_iovec;
506 int result;
508 req_exec_clm_nodejoin.header.size = sizeof (struct req_exec_clm_nodejoin);
509 req_exec_clm_nodejoin.header.id =
510 SERVICE_ID_MAKE (CLM_SERVICE, MESSAGE_REQ_EXEC_CLM_NODEJOIN);
512 my_cluster_node.initial_view_number = view_initial;
514 memcpy (&req_exec_clm_nodejoin.cluster_node, &my_cluster_node,
515 sizeof (mar_clm_cluster_node_t));
517 req_exec_clm_iovec.iov_base = (char *)&req_exec_clm_nodejoin;
518 req_exec_clm_iovec.iov_len = sizeof (req_exec_clm_nodejoin);
520 result = totempg_groups_mcast_joined (openais_group_handle, &req_exec_clm_iovec, 1, TOTEMPG_AGREED);
522 return (result);
525 static void clm_confchg_fn (
526 enum totem_configuration_type configuration_type,
527 unsigned int *member_list, int member_list_entries,
528 unsigned int *left_list, int left_list_entries,
529 unsigned int *joined_list, int joined_list_entries,
530 struct memb_ring_id *ring_id)
532 int i;
533 unsigned int node_ids[PROCESSOR_COUNT_MAX];
535 view_current = ring_id->seq / 4;
536 if (view_initial == 0) {
537 view_initial = ring_id->seq / 4;
540 log_printf (LOG_LEVEL_NOTICE, "CLM CONFIGURATION CHANGE\n");
541 log_printf (LOG_LEVEL_NOTICE, "New Configuration:\n");
542 for (i = 0; i < member_list_entries; i++) {
543 log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totempg_ifaces_print (member_list[i]));
545 log_printf (LOG_LEVEL_NOTICE, "Members Left:\n");
546 for (i = 0; i < left_list_entries; i++) {
547 log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totempg_ifaces_print (left_list[i]));
550 log_printf (LOG_LEVEL_NOTICE, "Members Joined:\n");
551 for (i = 0; i < joined_list_entries; i++) {
552 log_printf (LOG_LEVEL_NOTICE, "\t%s\n", totempg_ifaces_print (joined_list[i]));
555 for (i = 0; i < left_list_entries; i++) {
556 node_ids[i] = left_list[i];
559 lib_notification_leave (node_ids, i);
562 * Load the my_cluster_node data structure in case we are
563 * transitioning to network interface up or down
565 my_cluster_node_load ();
569 * This is a noop for this service
571 static void clm_sync_init (void)
573 return;
577 * If a processor joined in the configuration change and clm_sync_activate hasn't
578 * yet been called, issue a node join to share CLM specific data about the processor
580 static int clm_sync_process (void)
583 * Send node information to other nodes
585 return (clm_nodejoin_send ());
589 * This is a noop for this service
591 static void clm_sync_activate (void)
593 return;
597 * This is a noop for this service
599 static void clm_sync_abort (void)
601 return;
605 static void exec_clm_nodejoin_endian_convert (void *msg)
607 struct req_exec_clm_nodejoin *node_join = msg;
609 swab_mar_req_header_t (&node_join->header);
610 swab_mar_clm_cluster_node_t (&node_join->cluster_node);
613 static void message_handler_req_exec_clm_nodejoin (
614 void *message,
615 unsigned int nodeid)
617 struct req_exec_clm_nodejoin *req_exec_clm_nodejoin = (struct req_exec_clm_nodejoin *)message;
618 int found = 0;
619 int i;
621 log_printf (LOG_LEVEL_NOTICE, "got nodejoin message %s\n",
622 req_exec_clm_nodejoin->cluster_node.node_name.value);
625 * Determine if nodejoin already received
627 for (found = 0, i = 0; i < cluster_node_count; i++) {
628 if (cluster_node_entries[i].node_id == req_exec_clm_nodejoin->cluster_node.node_id) {
629 found = 1;
634 * If not received, add to internal list
636 if (found == 0) {
637 notification_join (&req_exec_clm_nodejoin->cluster_node);
638 memcpy (&cluster_node_entries[cluster_node_count],
639 &req_exec_clm_nodejoin->cluster_node,
640 sizeof (mar_clm_cluster_node_t));
642 cluster_node_count += 1;
646 static int clm_lib_init_fn (void *conn)
648 log_printf (LOG_LEVEL_DEBUG, "Got request to initalize cluster membership service.\n");
649 struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
651 list_init (&clm_pd->list);
652 clm_pd->conn = conn;
654 return (0);
657 static void message_handler_req_lib_clm_clustertrack (void *conn, void *msg)
659 struct req_lib_clm_clustertrack *req_lib_clm_clustertrack = (struct req_lib_clm_clustertrack *)msg;
660 struct res_lib_clm_clustertrack res_lib_clm_clustertrack;
661 struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
662 int i;
664 res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack);
665 res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKSTART;
666 res_lib_clm_clustertrack.header.error = SA_AIS_OK;
667 res_lib_clm_clustertrack.view = view_current;
668 res_lib_clm_clustertrack.number_of_items = 0;
671 * If an immediate listing of the current cluster membership
672 * is requested, generate membership list
674 if (req_lib_clm_clustertrack->track_flags & SA_TRACK_CURRENT ||
675 req_lib_clm_clustertrack->track_flags & SA_TRACK_CHANGES) {
676 for (i = 0; i < cluster_node_count; i++) {
677 res_lib_clm_clustertrack.notification[i].cluster_change = SA_CLM_NODE_NO_CHANGE;
679 memcpy (&res_lib_clm_clustertrack.notification[i].cluster_node,
680 &cluster_node_entries[i], sizeof (mar_clm_cluster_node_t));
682 res_lib_clm_clustertrack.number_of_items = cluster_node_count;
686 * Record requests for cluster tracking
688 if (req_lib_clm_clustertrack->track_flags & SA_TRACK_CHANGES ||
689 req_lib_clm_clustertrack->track_flags & SA_TRACK_CHANGES_ONLY) {
691 clm_pd->track_flags = req_lib_clm_clustertrack->track_flags;
692 clm_pd->tracking_enabled = 1;
694 list_add (&clm_pd->list, &library_notification_send_listhead);
697 openais_conn_send_response (conn, &res_lib_clm_clustertrack,
698 sizeof (struct res_lib_clm_clustertrack));
700 if (req_lib_clm_clustertrack->return_in_callback) {
701 res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
703 openais_conn_send_response (
704 openais_conn_partner_get (conn),
705 &res_lib_clm_clustertrack,
706 sizeof (struct res_lib_clm_clustertrack));
711 static void message_handler_req_lib_clm_trackstop (void *conn, void *msg)
713 struct res_lib_clm_trackstop res_lib_clm_trackstop;
714 struct clm_pd *clm_pd = (struct clm_pd *)openais_conn_private_data_get (conn);
716 res_lib_clm_trackstop.header.size = sizeof (struct res_lib_clm_trackstop);
717 res_lib_clm_trackstop.header.id = MESSAGE_RES_CLM_TRACKSTOP;
719 if (clm_pd->tracking_enabled) {
720 res_lib_clm_trackstop.header.error = SA_AIS_OK;
721 clm_pd->tracking_enabled = 0;
722 } else {
723 res_lib_clm_trackstop.header.error = SA_AIS_ERR_NOT_EXIST;
726 list_del (&clm_pd->list);
727 list_init (&clm_pd->list);
729 openais_conn_send_response (conn, &res_lib_clm_trackstop,
730 sizeof (struct res_lib_clm_trackstop));
733 static void message_handler_req_lib_clm_nodeget (void *conn, void *msg)
735 struct req_lib_clm_nodeget *req_lib_clm_nodeget = (struct req_lib_clm_nodeget *)msg;
736 struct res_clm_nodeget res_clm_nodeget;
737 mar_clm_cluster_node_t *cluster_node = 0;
738 int valid = 0;
739 int i;
741 log_printf (LOG_LEVEL_NOTICE, "nodeget: trying to find node %x\n",
742 (int)req_lib_clm_nodeget->node_id);
744 if (req_lib_clm_nodeget->node_id == SA_CLM_LOCAL_NODE_ID) {
745 cluster_node = &cluster_node_entries[0];
746 valid = 1;
747 } else
748 for (i = 0; i < cluster_node_count; i++) {
749 if (cluster_node_entries[i].node_id == req_lib_clm_nodeget->node_id) {
750 log_printf (LOG_LEVEL_DEBUG, "found host that matches one desired in nodeget.\n");
751 cluster_node = &cluster_node_entries[i];
752 valid = 1;
753 break;
757 res_clm_nodeget.header.size = sizeof (struct res_clm_nodeget);
758 res_clm_nodeget.header.id = MESSAGE_RES_CLM_NODEGET;
759 res_clm_nodeget.header.error = SA_AIS_OK;
760 res_clm_nodeget.invocation = req_lib_clm_nodeget->invocation;
761 res_clm_nodeget.valid = valid;
762 if (valid) {
763 memcpy (&res_clm_nodeget.cluster_node, cluster_node, sizeof (mar_clm_cluster_node_t));
765 openais_conn_send_response (conn, &res_clm_nodeget, sizeof (struct res_clm_nodeget));
768 static void message_handler_req_lib_clm_nodegetasync (void *conn, void *msg)
770 struct req_lib_clm_nodegetasync *req_lib_clm_nodegetasync = (struct req_lib_clm_nodegetasync *)msg;
771 struct res_clm_nodegetasync res_clm_nodegetasync;
772 struct res_clm_nodegetcallback res_clm_nodegetcallback;
773 mar_clm_cluster_node_t *cluster_node = 0;
774 int error = SA_AIS_ERR_INVALID_PARAM;
775 int i;
777 log_printf (LOG_LEVEL_DEBUG, "nodeget: trying to find node %x\n",
778 (int)req_lib_clm_nodegetasync->node_id);
780 if (req_lib_clm_nodegetasync->node_id == SA_CLM_LOCAL_NODE_ID) {
781 cluster_node = &cluster_node_entries[0];
782 error = SA_AIS_OK;
783 } else
784 for (i = 0; i < cluster_node_count; i++) {
785 if (cluster_node_entries[i].node_id == req_lib_clm_nodegetasync->node_id) {
786 log_printf (LOG_LEVEL_DEBUG, "found host that matches one desired in nodeget.\n");
787 cluster_node = &cluster_node_entries[i];
788 error = SA_AIS_OK;
789 break;
794 * Respond to library request
796 res_clm_nodegetasync.header.size = sizeof (struct res_clm_nodegetasync);
797 res_clm_nodegetasync.header.id = MESSAGE_RES_CLM_NODEGETASYNC;
798 res_clm_nodegetasync.header.error = SA_AIS_OK;
800 openais_conn_send_response (conn, &res_clm_nodegetasync,
801 sizeof (struct res_clm_nodegetasync));
804 * Send async response
806 res_clm_nodegetcallback.header.size = sizeof (struct res_clm_nodegetcallback);
807 res_clm_nodegetcallback.header.id = MESSAGE_RES_CLM_NODEGETCALLBACK;
808 res_clm_nodegetcallback.header.error = error;
809 res_clm_nodegetcallback.invocation = req_lib_clm_nodegetasync->invocation;
810 if (error == SA_AIS_OK) {
811 memcpy (&res_clm_nodegetcallback.cluster_node, cluster_node,
812 sizeof (mar_clm_cluster_node_t));
814 openais_conn_send_response (openais_conn_partner_get (conn),
815 &res_clm_nodegetcallback,
816 sizeof (struct res_clm_nodegetcallback));