2 * Copyright (c) 2002-2006 MontaVista Software, Inc.
3 * Copyright (c) 2006-2007 Red Hat, Inc.
4 * Copyright (C) 2006 Sun Microsystems, Inc.
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>
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)
46 #include <sys/ioctl.h>
47 #include <netinet/in.h>
57 #include <netinet/in.h>
58 #include <arpa/inet.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"
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
;
107 if (node_id
== SA_CLM_LOCAL_NODE_ID
) {
108 marshall_from_mar_clm_cluster_node_t (
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 (
117 &cluster_node_entries
[i
]);
118 return (&cluster_node
);
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 (
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
);
166 unsigned char track_flags
;
167 int tracking_enabled
;
168 struct list_head list
;
173 * Executive Handler Definition
175 static struct openais_lib_handler clm_lib_service
[] =
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
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
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
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",
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",
245 .versions_replace
= 0,
246 .versions_replace_count
= 0,
248 .dependency_count
= 0,
255 static struct lcr_comp clm_comp_ver0
= {
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
;
281 const char *iface_string
;
284 totempg_my_nodeid_get (),
289 iface_string
= totemip_print (&interfaces
[0]);
291 sprintf ((char *)my_cluster_node
.node_address
.value
, "%s",
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
;
298 if (totempg_my_family_get () == AF_INET6
) {
299 my_cluster_node
.node_address
.family
= SA_CLM_AF_INET6
;
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
);
322 #define NANOSEC 1000000000
324 #if defined(OPENAIS_LINUX)
325 struct 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
;
344 if ((utp
= getutxid(&ut
)) == NULL
) {
345 my_cluster_node
.boot_timestamp
= ((SaTimeT
)time(NULL
)) * NANOSEC
;
347 my_cluster_node
.boot_timestamp
= ((SaTimeT
)utp
->ut_xtime
) * NANOSEC
;
351 #warning "no bootime support"
355 cluster_node_count
= 1;
357 main_clm_get_by_nodeid
= clm_get_by_nodeid
;
361 static int clm_exec_exit_fn (struct objdb_iface_ver0
*objdb
)
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
);
378 static void library_notification_send (
379 mar_clm_cluster_notification_t
*cluster_notification_entries
,
382 struct res_lib_clm_clustertrack res_lib_clm_clustertrack
;
383 struct clm_pd
*clm_pd
;
384 struct list_head
*list
;
387 if (notify_count
== 0) {
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
;
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
);
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 (
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 (¬ification
.cluster_node
, cluster_node
,
454 sizeof (mar_clm_cluster_node_t
));
455 library_notification_send (¬ification
, 1);
458 static void lib_notification_leave (unsigned int *nodes
, int nodes_entries
)
460 mar_clm_cluster_notification_t cluster_notification
[PROCESSOR_COUNT_MAX
];
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;
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
));
492 * next cluster_node entry
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
;
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
);
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
)
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)
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)
597 * This is a noop for this service
599 static void clm_sync_abort (void)
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 (
617 struct req_exec_clm_nodejoin
*req_exec_clm_nodejoin
= (struct req_exec_clm_nodejoin
*)message
;
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
) {
634 * If not received, add to internal list
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
);
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
);
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;
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;
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];
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
];
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
;
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
;
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];
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
];
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
));