2 * Copyright (c) 2002-2005 MontaVista Software, Inc.
3 * Copyright (c) 2006 Red Hat, Inc.
7 * Author: Steven Dake (sdake@mvista.com)
9 * This software licensed under BSD license, the text of which follows:
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
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.
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.
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <sys/select.h>
49 #include "../exec/totem.h"
60 mar_res_header_t header
;
67 SaClmCallbacksT callbacks
;
69 pthread_mutex_t response_mutex
;
70 pthread_mutex_t dispatch_mutex
;
73 static void clmHandleInstanceDestructor (void *);
75 static struct saHandleDatabase clmHandleDatabase
= {
78 .mutex
= PTHREAD_MUTEX_INITIALIZER
,
79 .handleInstanceDestructor
= clmHandleInstanceDestructor
85 static SaVersionT clmVersionsSupported
[] = {
89 static struct saVersionDatabase clmVersionDatabase
= {
90 sizeof (clmVersionsSupported
) / sizeof (SaVersionT
),
94 void clmHandleInstanceDestructor (void *instance
)
96 struct clmInstance
*clmInstance
= instance
;
98 pthread_mutex_destroy (&clmInstance
->response_mutex
);
99 pthread_mutex_destroy (&clmInstance
->dispatch_mutex
);
104 * @defgroup saClm SAF AIS Cluster Membership API
110 * This function initializes the Cluster Membership Service for the invoking
111 * process and registers the various callback functions. This function must
112 * be invoked prior to the invocation of any other Cluster Membership Service
113 * functionality. The handle clmHandle is returned as the reference to this
114 * association between the process and the Cluster Membership Service. The
115 * process uses this handle in subsequent communication with the Cluster
116 * Membership Service.
118 * @param clmHandle A pointer to the handle designating this particular
119 * initialization of the Cluster Membership Service that is to be
120 * returned by the Cluster Membership Service.
121 * @param clmCallbacks If clmCallbacks is set to NULL, no callback is
122 * registered; otherise, it is a pointer to an SaClmCallbacksT structure,
123 * containing the callback functions of the process that the Cluster
124 * Membership Service may invoke. Only non-NULL callback functions
125 * in this structure will be registered.
126 * @param version The version requested from the application is passed into
127 * this parameter and the version supported is returned.
129 * @returns SA_AIS_OK if the function completed successfully.
130 * @returns SA_AIS_ERR_LIBRARY if an unexpected problem occurred in
132 * @returns SA_AIS_ERR_TRY_AGAIN if the service cannot be provided at this
134 * @returns SA_AIS_ERR_INVALID_PARAM if a parameter is not set correctly.
135 * @returns SA_AIS_ERR_NO_MEMORY if the Cluster Membership Service is out
136 * of memory and cannot provide the service.
137 * @returns SA_AIS_ERR_VERSION if the version parameter is not compatible with
138 * the version of the Cluster Membership Service implementation.
142 SaClmHandleT
*clmHandle
,
143 const SaClmCallbacksT
*clmCallbacks
,
146 struct clmInstance
*clmInstance
;
147 SaAisErrorT error
= SA_AIS_OK
;
150 if (clmHandle
== NULL
) {
151 return (SA_AIS_ERR_INVALID_PARAM
);
153 if (version
== NULL
) {
154 return (SA_AIS_ERR_INVALID_PARAM
);
157 error
= saVersionVerify (&clmVersionDatabase
, version
);
158 if (error
!= SA_AIS_OK
) {
159 goto error_no_destroy
;
162 error
= saHandleCreate (&clmHandleDatabase
, sizeof (struct clmInstance
),
164 if (error
!= SA_AIS_OK
) {
165 goto error_no_destroy
;
168 error
= saHandleInstanceGet (&clmHandleDatabase
, *clmHandle
,
169 (void *)&clmInstance
);
170 if (error
!= SA_AIS_OK
) {
174 clmInstance
->response_fd
= -1;
176 clmInstance
->dispatch_fd
= -1;
178 error
= saServiceConnect (&clmInstance
->response_fd
,
179 &clmInstance
->dispatch_fd
, CLM_SERVICE
);
180 if (error
!= SA_AIS_OK
) {
181 goto error_put_destroy
;
185 memcpy (&clmInstance
->callbacks
, clmCallbacks
, sizeof (SaClmCallbacksT
));
187 memset (&clmInstance
->callbacks
, 0, sizeof (SaClmCallbacksT
));
190 pthread_mutex_init (&clmInstance
->response_mutex
, NULL
);
192 pthread_mutex_init (&clmInstance
->dispatch_mutex
, NULL
);
194 saHandleInstancePut (&clmHandleDatabase
, *clmHandle
);
199 saHandleInstancePut (&clmHandleDatabase
, *clmHandle
);
201 saHandleDestroy (&clmHandleDatabase
, *clmHandle
);
207 * This function returns the operating system handle, selectionObject,
208 * assocated with the handle clmHandle. The invoking process can use this
209 * handle to detect pending callbacks, instead of repeatedly invoking
210 * saClmDispatch() for this purpose.
212 * In a POSIX environment, the operating system handle is a file descriptor
213 * that is used with the poll() or select() system calls to detect pending
216 * The selectionObject returned by saClmSelectionObjectGet() is valid until
217 * saClmFinalize() is invoked on the same handle clmHandle.
219 * @param clmHandle The handle, obtained through the saClmInitialize function,
220 * designating this particular initialization of the Cluster Membership
221 * @param selectionObject A pointer to the operating system handle that the
222 * invoking process can use to detect pending callbacks.
224 * @returns SA_AIS_OK if the function completed successfully.
225 * @returns SA_AIS_ERR_BAD_HANDLE if the handle clmHandle is invalid, since it is
226 * corrupted, uninitialized, or has already been finalized.
229 saClmSelectionObjectGet (
230 SaClmHandleT clmHandle
,
231 SaSelectionObjectT
*selectionObject
)
233 struct clmInstance
*clmInstance
;
236 if (selectionObject
== NULL
) {
237 return (SA_AIS_ERR_INVALID_PARAM
);
239 error
= saHandleInstanceGet (&clmHandleDatabase
, clmHandle
,
240 (void *)&clmInstance
);
241 if (error
!= SA_AIS_OK
) {
245 *selectionObject
= clmInstance
->dispatch_fd
;
247 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);
252 * This function invokes, in the context of the calling thread, pending callbacks for
253 * the handle clmhandle in a way that is specified by the dispatchFlags parameter.
255 * @param clmHandle The handle, obtained through the saClmInitialize() function,
256 * designating the particular initialization of the Cluster Membership Service.
257 * @param dispatchFlags Flags that specify the callback exection behavior of
258 * saClmDispatch, which have the values SA_DISPATCH_ONE, SA_DISPATCH_ALL, or
259 * SA_DISPATCH_BLOCKING.
260 * @returns SA_AIS_OK if the function completed successfully.
261 * @returns SA_AIS_ERR_TRY_AGAIN if the service cannot be provided at this time. The
262 * process may retry later.
263 * @returns SA_AIS_ERR_BAD_HANDLE if the handle clmHandle is invalid, since it is
264 * corrupted, uninitialized, or has already been finalized.
265 * @returns SA_AIS_ERR_INVALID_PARAM if the dispatchFlags parameter is valid.
269 SaClmHandleT clmHandle
,
270 SaDispatchFlagsT dispatchFlags
)
275 int cont
= 1; /* always continue do loop except when set to 0 */
277 struct clmInstance
*clmInstance
;
278 struct res_lib_clm_clustertrack
*res_lib_clm_clustertrack
;
279 struct res_clm_nodegetcallback
*res_clm_nodegetcallback
;
280 SaClmCallbacksT callbacks
;
281 struct res_overlay dispatch_data
;
282 SaClmClusterNotificationBufferT notificationBuffer
;
283 SaClmClusterNotificationT notification
[PROCESSOR_COUNT_MAX
];
284 SaClmClusterNodeT clusterNode
;
288 if (dispatchFlags
!= SA_DISPATCH_ONE
&&
289 dispatchFlags
!= SA_DISPATCH_ALL
&&
290 dispatchFlags
!= SA_DISPATCH_BLOCKING
) {
292 return (SA_AIS_ERR_INVALID_PARAM
);
295 error
= saHandleInstanceGet (&clmHandleDatabase
, clmHandle
,
296 (void *)&clmInstance
);
297 if (error
!= SA_AIS_OK
) {
302 * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and
303 * wait indefinately for SA_DISPATCH_BLOCKING
305 if (dispatchFlags
== SA_DISPATCH_ALL
) {
310 ufds
.fd
= clmInstance
->dispatch_fd
;
311 ufds
.events
= POLLIN
;
314 pthread_mutex_lock (&clmInstance
->dispatch_mutex
);
316 error
= saPollRetry (&ufds
, 1, timeout
);
317 if (error
!= SA_AIS_OK
) {
322 * Handle has been finalized in another thread
324 if (clmInstance
->finalize
== 1) {
329 if ((ufds
.revents
& (POLLERR
|POLLHUP
|POLLNVAL
)) != 0) {
330 error
= SA_AIS_ERR_BAD_HANDLE
;
334 dispatch_avail
= ufds
.revents
& POLLIN
;
335 if (dispatch_avail
== 0 && dispatchFlags
== SA_DISPATCH_ALL
) {
336 pthread_mutex_unlock (&clmInstance
->dispatch_mutex
);
337 break; /* exit do while cont is 1 loop */
339 if (dispatch_avail
== 0) {
340 pthread_mutex_unlock (&clmInstance
->dispatch_mutex
);
341 continue; /* next poll */
344 if (ufds
.revents
& POLLIN
) {
345 error
= saRecvRetry (clmInstance
->dispatch_fd
, &dispatch_data
.header
,
346 sizeof (mar_res_header_t
));
347 if (error
!= SA_AIS_OK
) {
350 if (dispatch_data
.header
.size
> sizeof (mar_res_header_t
)) {
351 error
= saRecvRetry (clmInstance
->dispatch_fd
, &dispatch_data
.data
,
352 dispatch_data
.header
.size
- sizeof (mar_res_header_t
));
353 if (error
!= SA_AIS_OK
) {
358 pthread_mutex_unlock (&clmInstance
->dispatch_mutex
);
363 * Make copy of callbacks, message data, unlock instance, and call callback
364 * A risk of this dispatch method is that the callback routines may
365 * operate at the same time that clmFinalize has been called in another thread.
367 memcpy (&callbacks
, &clmInstance
->callbacks
, sizeof (SaClmCallbacksT
));
368 pthread_mutex_unlock (&clmInstance
->dispatch_mutex
);
371 * Dispatch incoming message
373 switch (dispatch_data
.header
.id
) {
375 case MESSAGE_RES_CLM_TRACKCALLBACK
:
376 if (callbacks
.saClmClusterTrackCallback
== NULL
) {
379 res_lib_clm_clustertrack
= (struct res_lib_clm_clustertrack
*)&dispatch_data
;
382 notificationBuffer
.notification
= notification
;
384 notificationBuffer
.viewNumber
= res_lib_clm_clustertrack
->view
;
385 notificationBuffer
.notification
= notification
;
386 notificationBuffer
.numberOfItems
=
387 res_lib_clm_clustertrack
->number_of_items
;
389 items_to_copy
= notificationBuffer
.numberOfItems
390 < res_lib_clm_clustertrack
->number_of_items
?
391 notificationBuffer
.numberOfItems
:
392 res_lib_clm_clustertrack
->number_of_items
;
394 for (i
= 0; i
< items_to_copy
; i
++) {
395 marshall_from_mar_clm_cluster_notification_t (
396 ¬ificationBuffer
.notification
[i
],
397 &res_lib_clm_clustertrack
->notification
[i
]);
400 callbacks
.saClmClusterTrackCallback (
401 (const SaClmClusterNotificationBufferT
*)¬ificationBuffer
,
402 res_lib_clm_clustertrack
->number_of_items
, error
);
406 case MESSAGE_RES_CLM_NODEGETCALLBACK
:
407 if (callbacks
.saClmClusterNodeGetCallback
== NULL
) {
410 res_clm_nodegetcallback
= (struct res_clm_nodegetcallback
*)&dispatch_data
;
411 marshall_from_mar_clm_cluster_node_t (
413 &res_clm_nodegetcallback
->cluster_node
);
415 callbacks
.saClmClusterNodeGetCallback (
416 res_clm_nodegetcallback
->invocation
,
418 res_clm_nodegetcallback
->header
.error
);
422 error
= SA_AIS_ERR_LIBRARY
;
428 * Determine if more messages should be processed
430 switch (dispatchFlags
) {
431 case SA_DISPATCH_ONE
:
434 case SA_DISPATCH_ALL
:
436 case SA_DISPATCH_BLOCKING
:
444 pthread_mutex_unlock (&clmInstance
->dispatch_mutex
);
447 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);
453 * The saClmFinalize function closes the assocation, represented by the clmHandle
454 * parameter, between the invoking process and the Cluster Membership Service. The
455 * process must have invoked saClmInitialize before it invokes this function. A
456 * process must invoke this function once for each handle it acquired by invoking
459 * If the saClmFinalize() function returns successfully, the saClmFinalize() function
460 * releases all resources acquired when saClmInitialize(0 was called. Moreover, it
461 * stops any tracking associated with the particular handle. Furthermore, it cancels
462 * all pending callbacks related to the particular handle. Note that because the
463 * callback invocation is asynchronous, it is still possible that some callback calls
464 * are processed after this call returns successfully.
466 * After saClmFinalize() is invoked, the selection object is no longer valid.
468 * @param clmHandle The handle, obtained through the saClmInitialize() function,
469 * designating this particular initialization of the Cluster Membership Service.
471 * @returns SA_AIS_OK if the function completed successfully.
472 * @returns SA_AIS_ERR_BAD_HANDLE if the handle clmHandle is invalid, since it is
473 * corrupted, uninitialized, or has already been finalized.
477 SaClmHandleT clmHandle
)
479 struct clmInstance
*clmInstance
;
482 error
= saHandleInstanceGet (&clmHandleDatabase
, clmHandle
,
483 (void *)&clmInstance
);
484 if (error
!= SA_AIS_OK
) {
488 pthread_mutex_lock (&clmInstance
->response_mutex
);
491 * Another thread has already started finalizing
493 if (clmInstance
->finalize
) {
494 pthread_mutex_unlock (&clmInstance
->response_mutex
);
495 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);
496 return (SA_AIS_ERR_BAD_HANDLE
);
499 clmInstance
->finalize
= 1;
501 pthread_mutex_unlock (&clmInstance
->response_mutex
);
503 saHandleDestroy (&clmHandleDatabase
, clmHandle
);
505 if (clmInstance
->response_fd
!= -1) {
506 shutdown (clmInstance
->response_fd
, 0);
507 close (clmInstance
->response_fd
);
509 if (clmInstance
->dispatch_fd
!= -1) {
510 shutdown (clmInstance
->dispatch_fd
, 0);
511 close (clmInstance
->dispatch_fd
);
514 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);
521 SaClmHandleT clmHandle
,
523 SaClmClusterNotificationBufferT
*notificationBuffer
)
525 struct req_lib_clm_clustertrack req_lib_clm_clustertrack
;
526 struct res_lib_clm_clustertrack res_lib_clm_clustertrack
;
527 struct clmInstance
*clmInstance
;
528 SaAisErrorT error
= SA_AIS_OK
;
532 error
= saHandleInstanceGet (&clmHandleDatabase
, clmHandle
,
533 (void *)&clmInstance
);
534 if (error
!= SA_AIS_OK
) {
538 if ((trackFlags
& SA_TRACK_CHANGES
) && (trackFlags
& SA_TRACK_CHANGES_ONLY
)) {
539 error
= SA_AIS_ERR_BAD_FLAGS
;
543 if (trackFlags
& ~(SA_TRACK_CURRENT
| SA_TRACK_CHANGES
| SA_TRACK_CHANGES_ONLY
)) {
544 error
= SA_AIS_ERR_BAD_FLAGS
;
548 if ((notificationBuffer
!= NULL
) &&
549 (notificationBuffer
->notification
!= NULL
) &&
550 (notificationBuffer
->numberOfItems
== 0)) {
552 error
= SA_AIS_ERR_INVALID_PARAM
;
556 req_lib_clm_clustertrack
.header
.size
= sizeof (struct req_lib_clm_clustertrack
);
557 req_lib_clm_clustertrack
.header
.id
= MESSAGE_REQ_CLM_TRACKSTART
;
558 req_lib_clm_clustertrack
.track_flags
= trackFlags
;
559 req_lib_clm_clustertrack
.return_in_callback
= 0;
560 if ((trackFlags
& SA_TRACK_CURRENT
) && (notificationBuffer
== NULL
)) {
561 req_lib_clm_clustertrack
.return_in_callback
= 1;
564 pthread_mutex_lock (&clmInstance
->response_mutex
);
566 if ((clmInstance
->callbacks
.saClmClusterTrackCallback
== 0) &&
567 ((notificationBuffer
== NULL
) ||
568 (trackFlags
& (SA_TRACK_CHANGES
| SA_TRACK_CHANGES_ONLY
)))) {
570 error
= SA_AIS_ERR_INIT
;
574 error
= saSendReceiveReply (clmInstance
->response_fd
,
575 &req_lib_clm_clustertrack
,
576 sizeof (struct req_lib_clm_clustertrack
),
577 &res_lib_clm_clustertrack
,
578 sizeof (struct res_lib_clm_clustertrack
));
580 if ((trackFlags
& SA_TRACK_CURRENT
) && (notificationBuffer
!= NULL
)) {
581 if (notificationBuffer
->notification
== 0) {
582 notificationBuffer
->viewNumber
= res_lib_clm_clustertrack
.view
;
584 notificationBuffer
->notification
=
585 malloc (res_lib_clm_clustertrack
.number_of_items
*
586 sizeof (SaClmClusterNotificationT
));
588 notificationBuffer
->numberOfItems
=
589 res_lib_clm_clustertrack
.number_of_items
;
592 items_to_copy
= notificationBuffer
->numberOfItems
<
593 res_lib_clm_clustertrack
.number_of_items
?
594 notificationBuffer
->numberOfItems
:
595 res_lib_clm_clustertrack
.number_of_items
;
597 for (i
= 0; i
< items_to_copy
; i
++) {
598 marshall_from_mar_clm_cluster_notification_t (
599 ¬ificationBuffer
->notification
[i
],
600 &res_lib_clm_clustertrack
.notification
[i
]);
603 notificationBuffer
->viewNumber
= res_lib_clm_clustertrack
.view
;
604 notificationBuffer
->numberOfItems
= items_to_copy
;
608 pthread_mutex_unlock (&clmInstance
->response_mutex
);
611 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);
613 return (error
== SA_AIS_OK
? res_lib_clm_clustertrack
.header
.error
: error
);
617 saClmClusterTrackStop (
618 SaClmHandleT clmHandle
)
620 struct clmInstance
*clmInstance
;
621 struct req_lib_clm_trackstop req_lib_clm_trackstop
;
622 struct res_lib_clm_trackstop res_lib_clm_trackstop
;
623 SaAisErrorT error
= SA_AIS_OK
;
625 req_lib_clm_trackstop
.header
.size
= sizeof (struct req_lib_clm_trackstop
);
626 req_lib_clm_trackstop
.header
.id
= MESSAGE_REQ_CLM_TRACKSTOP
;
627 error
= saHandleInstanceGet (&clmHandleDatabase
, clmHandle
,
628 (void *)&clmInstance
);
629 if (error
!= SA_AIS_OK
) {
633 pthread_mutex_lock (&clmInstance
->response_mutex
);
635 error
= saSendReceiveReply (clmInstance
->response_fd
,
636 &req_lib_clm_trackstop
,
637 sizeof (struct req_lib_clm_trackstop
),
638 &res_lib_clm_trackstop
,
639 sizeof (struct res_lib_clm_trackstop
));
641 pthread_mutex_unlock (&clmInstance
->response_mutex
);
643 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);
645 return (error
== SA_AIS_OK
? res_lib_clm_trackstop
.header
.error
: error
);
649 saClmClusterNodeGet (
650 SaClmHandleT clmHandle
,
653 SaClmClusterNodeT
*clusterNode
)
655 struct clmInstance
*clmInstance
;
656 struct req_lib_clm_nodeget req_lib_clm_nodeget
;
657 struct res_clm_nodeget res_clm_nodeget
;
658 SaAisErrorT error
= SA_AIS_OK
;
660 if (clusterNode
== NULL
) {
661 return (SA_AIS_ERR_INVALID_PARAM
);
665 return (SA_AIS_ERR_TIMEOUT
);
668 error
= saHandleInstanceGet (&clmHandleDatabase
, clmHandle
,
669 (void *)&clmInstance
);
670 if (error
!= SA_AIS_OK
) {
674 pthread_mutex_lock (&clmInstance
->response_mutex
);
677 * Send request message
679 req_lib_clm_nodeget
.header
.size
= sizeof (struct req_lib_clm_nodeget
);
680 req_lib_clm_nodeget
.header
.id
= MESSAGE_REQ_CLM_NODEGET
;
681 req_lib_clm_nodeget
.node_id
= nodeId
;
683 error
= saSendReceiveReply (clmInstance
->response_fd
, &req_lib_clm_nodeget
,
684 sizeof (struct req_lib_clm_nodeget
), &res_clm_nodeget
, sizeof (res_clm_nodeget
));
685 if (error
!= SA_AIS_OK
) {
689 error
= res_clm_nodeget
.header
.error
;
691 marshall_from_mar_clm_cluster_node_t (clusterNode
,
692 &res_clm_nodeget
.cluster_node
);
695 pthread_mutex_unlock (&clmInstance
->response_mutex
);
697 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);
703 saClmClusterNodeGetAsync (
704 SaClmHandleT clmHandle
,
705 SaInvocationT invocation
,
708 struct clmInstance
*clmInstance
;
709 struct req_lib_clm_nodegetasync req_lib_clm_nodegetasync
;
710 struct res_clm_nodegetasync res_clm_nodegetasync
;
711 SaAisErrorT error
= SA_AIS_OK
;
713 req_lib_clm_nodegetasync
.header
.size
= sizeof (struct req_lib_clm_nodegetasync
);
714 req_lib_clm_nodegetasync
.header
.id
= MESSAGE_REQ_CLM_NODEGETASYNC
;
715 req_lib_clm_nodegetasync
.invocation
= invocation
;
716 req_lib_clm_nodegetasync
.node_id
= nodeId
;
718 error
= saHandleInstanceGet (&clmHandleDatabase
, clmHandle
,
719 (void *)&clmInstance
);
720 if (error
!= SA_AIS_OK
) {
724 pthread_mutex_lock (&clmInstance
->response_mutex
);
726 if (clmInstance
->callbacks
.saClmClusterNodeGetCallback
== NULL
) {
727 error
= SA_AIS_ERR_INIT
;
731 error
= saSendReceiveReply (clmInstance
->response_fd
, &req_lib_clm_nodegetasync
,
732 sizeof (struct req_lib_clm_nodegetasync
),
733 &res_clm_nodegetasync
, sizeof (struct res_clm_nodegetasync
));
734 if (error
!= SA_AIS_OK
) {
738 error
= res_clm_nodegetasync
.header
.error
;
741 pthread_mutex_unlock (&clmInstance
->response_mutex
);
743 saHandleInstancePut (&clmHandleDatabase
, clmHandle
);