corosync
lib/cpg.c
Go to the documentation of this file.
1/*
2 * vi: set autoindent tabstop=4 shiftwidth=4 :
3 *
4 * Copyright (c) 2006-2015 Red Hat, Inc.
5 *
6 * All rights reserved.
7 *
8 * Author: Christine Caulfield (ccaulfi@redhat.com)
9 * Author: Jan Friesse (jfriesse@redhat.com)
10 *
11 * This software licensed under BSD license, the text of which follows:
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *
16 * - Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 * - Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 * - Neither the name of the MontaVista Software, Inc. nor the names of its
22 * contributors may be used to endorse or promote products derived from this
23 * software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35 * THE POSSIBILITY OF SUCH DAMAGE.
36 */
37/*
38 * Provides a closed process group API using the coroipcc executive
39 */
40
41#include <config.h>
42
43#include <stdlib.h>
44#include <stdio.h>
45#include <string.h>
46#include <unistd.h>
47#include <sys/types.h>
48#include <sys/socket.h>
49#include <sys/mman.h>
50#include <sys/uio.h>
51#include <sys/stat.h>
52#include <errno.h>
53#include <limits.h>
54
55#include <qb/qblist.h>
56#include <qb/qbdefs.h>
57#include <qb/qbipcc.h>
58#include <qb/qblog.h>
59
60#include <corosync/hdb.h>
61#include <corosync/corotypes.h>
62#include <corosync/corodefs.h>
63#include <corosync/cpg.h>
64#include <corosync/ipc_cpg.h>
65
66#include "util.h"
67
68#ifndef MAP_ANONYMOUS
69#define MAP_ANONYMOUS MAP_ANON
70#endif
71
72/*
73 * Maximum number of times to retry a send when transmitting
74 * a large message fragment
75 */
76#define MAX_RETRIES 100
77
86
99static void cpg_inst_free (void *inst);
100
102
109
111
112
113/*
114 * Internal (not visible by API) functions
115 */
116
117static cs_error_t
118coroipcc_msg_send_reply_receive (
120 const struct iovec *iov,
121 unsigned int iov_len,
122 void *res_msg,
123 size_t res_len)
124{
127}
128
129static void cpg_iteration_instance_finalize (struct cpg_iteration_instance_t *cpg_iteration_instance)
130{
132 hdb_handle_destroy (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle);
133}
134
135static void cpg_inst_free (void *inst)
136{
137 struct cpg_inst *cpg_inst = (struct cpg_inst *)inst;
139}
140
141static void cpg_inst_finalize (struct cpg_inst *cpg_inst, hdb_handle_t handle)
142{
143 struct qb_list_head *iter, *tmp_iter;
145
146 /*
147 * Traverse thru iteration instances and delete them
148 */
151
152 cpg_iteration_instance_finalize (cpg_iteration_instance);
153 }
154 hdb_handle_destroy (&cpg_handle_t_db, handle);
155}
156
165 cpg_handle_t *handle,
166 cpg_callbacks_t *callbacks)
167{
168 cpg_model_v1_data_t model_v1_data;
169
170 memset (&model_v1_data, 0, sizeof (cpg_model_v1_data_t));
171
172 if (callbacks) {
173 model_v1_data.cpg_deliver_fn = callbacks->cpg_deliver_fn;
174 model_v1_data.cpg_confchg_fn = callbacks->cpg_confchg_fn;
175 }
176
177 return (cpg_model_initialize (handle, CPG_MODEL_V1, (cpg_model_data_t *)&model_v1_data, NULL));
178}
179
181 cpg_handle_t *handle,
182 cpg_model_t model,
184 void *context)
185{
187 struct cpg_inst *cpg_inst;
188
189 if (model != CPG_MODEL_V1) {
191 goto error_no_destroy;
192 }
193
194 error = hdb_error_to_cs (hdb_handle_create (&cpg_handle_t_db, sizeof (struct cpg_inst), handle));
195 if (error != CS_OK) {
196 goto error_no_destroy;
197 }
198
199 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, *handle, (void *)&cpg_inst));
200 if (error != CS_OK) {
201 goto error_destroy;
202 }
203
205 if (cpg_inst->c == NULL) {
208 }
209
210 if (model_data != NULL) {
211 switch (model) {
212 case CPG_MODEL_V1:
216
217 goto error_destroy;
218 }
219 break;
220 }
221 }
222
223 /* Allow space for corosync internal headers */
227
229
231
232 hdb_handle_put (&cpg_handle_t_db, *handle);
233
234 return (CS_OK);
235
237 hdb_handle_put (&cpg_handle_t_db, *handle);
239 hdb_handle_destroy (&cpg_handle_t_db, *handle);
241 return (error);
242}
243
245 cpg_handle_t handle)
246{
247 struct cpg_inst *cpg_inst;
248 struct iovec iov;
252
253 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
254 if (error != CS_OK) {
255 return (error);
256 }
257
258 /*
259 * Another thread has already started finalizing
260 */
261 if (cpg_inst->finalize) {
262 hdb_handle_put (&cpg_handle_t_db, handle);
263 return (CS_ERR_BAD_HANDLE);
264 }
265
266 cpg_inst->finalize = 1;
267
268 /*
269 * Send service request
270 */
271 req_lib_cpg_finalize.header.size = sizeof (struct req_lib_cpg_finalize);
273
274 iov.iov_base = (void *)&req_lib_cpg_finalize;
275 iov.iov_len = sizeof (struct req_lib_cpg_finalize);
276
277 error = coroipcc_msg_send_reply_receive (cpg_inst->c,
278 &iov,
279 1,
282
283 cpg_inst_finalize (cpg_inst, handle);
284 hdb_handle_put (&cpg_handle_t_db, handle);
285
286 return (error);
287}
288
290 cpg_handle_t handle,
291 int *fd)
292{
294 struct cpg_inst *cpg_inst;
295
296 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
297 if (error != CS_OK) {
298 return (error);
299 }
300
302
303 hdb_handle_put (&cpg_handle_t_db, handle);
304
305 return (error);
306}
307
309 cpg_handle_t handle,
310 uint32_t *size)
311{
313 struct cpg_inst *cpg_inst;
314
315 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
316 if (error != CS_OK) {
317 return (error);
318 }
319
320 *size = cpg_inst->max_msg_size;
321
322 hdb_handle_put (&cpg_handle_t_db, handle);
323
324 return (error);
325}
326
328 cpg_handle_t handle,
329 void **context)
330{
332 struct cpg_inst *cpg_inst;
333
334 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
335 if (error != CS_OK) {
336 return (error);
337 }
338
340
341 hdb_handle_put (&cpg_handle_t_db, handle);
342
343 return (CS_OK);
344}
345
347 cpg_handle_t handle,
348 void *context)
349{
351 struct cpg_inst *cpg_inst;
352
353 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
354 if (error != CS_OK) {
355 return (error);
356 }
357
359
360 hdb_handle_put (&cpg_handle_t_db, handle);
361
362 return (CS_OK);
363}
364
366 cpg_handle_t handle,
368{
369 int timeout = -1;
371 int cont = 1; /* always continue do loop except when set to 0 */
372 struct cpg_inst *cpg_inst;
377 struct cpg_inst cpg_inst_copy;
379 struct cpg_address member_list[CPG_MEMBERS_MAX];
382 struct cpg_name group_name;
384 struct qb_list_head *iter, *tmp_iter;
387 unsigned int i;
388 struct cpg_ring_id ring_id;
392
393 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
394 if (error != CS_OK) {
395 return (error);
396 }
397
398 /*
399 * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
400 * wait indefinitely for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
401 */
403 timeout = 0;
404 }
405
407 do {
409 cpg_inst->c,
412 timeout);
414 if (error == CS_ERR_BAD_HANDLE) {
415 error = CS_OK;
416 goto error_put;
417 }
418 if (error == CS_ERR_TRY_AGAIN) {
420 /*
421 * Don't mask error
422 */
423 goto error_put;
424 }
425 error = CS_OK;
427 break; /* exit do while cont is 1 loop */
428 } else {
429 continue; /* next poll */
430 }
431 }
432 if (error != CS_OK) {
433 goto error_put;
434 }
435
436 /*
437 * Make copy of callbacks, message data, unlock instance, and call callback
438 * A risk of this dispatch method is that the callback routines may
439 * operate at the same time that cpgFinalize has been called.
440 */
441 memcpy (&cpg_inst_copy, cpg_inst, sizeof (struct cpg_inst));
442 switch (cpg_inst_copy.model) {
443 case CPG_MODEL_V1:
444 /*
445 * Dispatch incoming message
446 */
447 switch (dispatch_data->id) {
449 if (cpg_inst_copy.model_v1_data.cpg_deliver_fn == NULL) {
450 break;
451 }
452
454
455 marshall_from_mar_cpg_name_t (
456 &group_name,
457 &res_cpg_deliver_callback->group_name);
458
459 cpg_inst_copy.model_v1_data.cpg_deliver_fn (handle,
460 &group_name,
463 &res_cpg_deliver_callback->message,
465 break;
466
469
470 marshall_from_mar_cpg_name_t (
471 &group_name,
473
474 /*
475 * Search for assembly data for current messages (nodeid, pid) pair in list of assemblies
476 */
482 break;
483 }
484 }
485
487
488 /*
489 * As this is LIBCPG_PARTIAL_FIRST packet, check that there is no ongoing assembly.
490 * Otherwise the sending of packet must have been interrupted and error should have
491 * been reported to sending client. Therefore here last assembly will be dropped.
492 */
493 if (assembly_data) {
494 qb_list_del (&assembly_data->list);
495 free(assembly_data->assembly_buf);
497 // coverity[UNUSED_VALUE:SUPPRESS] defensive programming
499 }
500
501 assembly_data = malloc(sizeof(struct cpg_assembly_data));
502 if (!assembly_data) {
504 goto error_put;
505 }
506
510 if (!assembly_data->assembly_buf) {
513 goto error_put;
514 }
515 assembly_data->assembly_buf_ptr = 0;
517
519 }
520 if (assembly_data) {
521 memcpy(assembly_data->assembly_buf + assembly_data->assembly_buf_ptr,
523 assembly_data->assembly_buf_ptr += res_cpg_partial_deliver_callback->fraglen;
524
526 if (cpg_inst_copy.model_v1_data.cpg_deliver_fn != NULL) {
527 cpg_inst_copy.model_v1_data.cpg_deliver_fn (handle,
528 &group_name,
531 assembly_data->assembly_buf,
533 }
534
535 qb_list_del (&assembly_data->list);
536 free(assembly_data->assembly_buf);
538 }
539 }
540 break;
541
543 if (cpg_inst_copy.model_v1_data.cpg_confchg_fn == NULL) {
544 break;
545 }
546
548
549 for (i = 0; i < res_cpg_confchg_callback->member_list_entries; i++) {
550 marshall_from_mar_cpg_address_t (&member_list[i],
551 &res_cpg_confchg_callback->member_list[i]);
552 }
554 res_cpg_confchg_callback->member_list_entries;
555 for (i = 0; i < res_cpg_confchg_callback->left_list_entries; i++) {
556 marshall_from_mar_cpg_address_t (&left_list[i],
558 }
560 res_cpg_confchg_callback->member_list_entries +
561 res_cpg_confchg_callback->left_list_entries;
562 for (i = 0; i < res_cpg_confchg_callback->joined_list_entries; i++) {
563 marshall_from_mar_cpg_address_t (&joined_list[i],
565 }
566 marshall_from_mar_cpg_name_t (
567 &group_name,
568 &res_cpg_confchg_callback->group_name);
569
570 cpg_inst_copy.model_v1_data.cpg_confchg_fn (handle,
571 &group_name,
573 res_cpg_confchg_callback->member_list_entries,
574 left_list,
575 res_cpg_confchg_callback->left_list_entries,
577 res_cpg_confchg_callback->joined_list_entries);
578
579 /*
580 * If member left while his partial packet was being assembled, assembly data must be removed from list
581 */
582 for (i = 0; i < res_cpg_confchg_callback->left_list_entries; i++) {
585 if (current_assembly_data->nodeid != left_list[i].nodeid || current_assembly_data->pid != left_list[i].pid)
586 continue;
587
589 free(current_assembly_data->assembly_buf);
591 }
592 }
593
594 break;
596 if (cpg_inst_copy.model_v1_data.cpg_totem_confchg_fn == NULL) {
597 break;
598 }
599
601
602 marshall_from_mar_cpg_ring_id_t (&ring_id, &res_cpg_totem_confchg_callback->ring_id);
603 for (i = 0; i < res_cpg_totem_confchg_callback->member_list_entries; i++) {
605 }
606
607 cpg_inst_copy.model_v1_data.cpg_totem_confchg_fn (handle,
608 ring_id,
609 res_cpg_totem_confchg_callback->member_list_entries,
611 break;
612 default:
614 goto error_put;
615 break;
616 } /* - switch (dispatch_data->id) */
617 break; /* case CPG_MODEL_V1 */
618 } /* - switch (cpg_inst_copy.model) */
619
620 if (cpg_inst_copy.finalize || cpg_inst->finalize) {
621 /*
622 * If the finalize has been called then get out of the dispatch.
623 */
624 cpg_inst->finalize = 1;
626 goto error_put;
627 }
628
629 /*
630 * Determine if more messages should be processed
631 */
633 cont = 0;
634 }
635 } while (cont);
636
638 hdb_handle_put (&cpg_handle_t_db, handle);
639 return (error);
640}
641
643 cpg_handle_t handle,
644 const struct cpg_name *group)
645{
647 struct cpg_inst *cpg_inst;
648 struct iovec iov[2];
650 struct res_lib_cpg_join response;
651
652 if (group->length > CPG_MAX_NAME_LENGTH) {
653 return (CS_ERR_NAME_TOO_LONG);
654 }
655
656 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
657 if (error != CS_OK) {
658 return (error);
659 }
660
661 /* Now join */
662 req_lib_cpg_join.header.size = sizeof (struct req_lib_cpg_join);
664 req_lib_cpg_join.pid = getpid();
665 req_lib_cpg_join.flags = 0;
666
667 switch (cpg_inst->model) {
668 case CPG_MODEL_V1:
670 break;
671 }
672
673 marshall_to_mar_cpg_name_t (&req_lib_cpg_join.group_name,
674 group);
675
676 iov[0].iov_base = (void *)&req_lib_cpg_join;
677 iov[0].iov_len = sizeof (struct req_lib_cpg_join);
678
679 do {
680 error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 1,
681 &response, sizeof (struct res_lib_cpg_join));
682
683 if (error != CS_OK) {
684 goto error_exit;
685 }
686 } while (response.header.error == CS_ERR_BUSY);
687
688 error = response.header.error;
689
691 hdb_handle_put (&cpg_handle_t_db, handle);
692
693 return (error);
694}
695
697 cpg_handle_t handle,
698 const struct cpg_name *group)
699{
701 struct cpg_inst *cpg_inst;
702 struct iovec iov[2];
705
706 if (group->length > CPG_MAX_NAME_LENGTH) {
707 return (CS_ERR_NAME_TOO_LONG);
708 }
709
710 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
711 if (error != CS_OK) {
712 return (error);
713 }
714
715 req_lib_cpg_leave.header.size = sizeof (struct req_lib_cpg_leave);
718 marshall_to_mar_cpg_name_t (&req_lib_cpg_leave.group_name,
719 group);
720
721 iov[0].iov_base = (void *)&req_lib_cpg_leave;
722 iov[0].iov_len = sizeof (struct req_lib_cpg_leave);
723
724 do {
725 error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 1,
727
728 if (error != CS_OK) {
729 goto error_exit;
730 }
731 } while (res_lib_cpg_leave.header.error == CS_ERR_BUSY);
732
733 error = res_lib_cpg_leave.header.error;
734
736 hdb_handle_put (&cpg_handle_t_db, handle);
737
738 return (error);
739}
740
742 cpg_handle_t handle,
743 struct cpg_name *group_name,
744 struct cpg_address *member_list,
745 int *member_list_entries)
746{
748 struct cpg_inst *cpg_inst;
749 struct iovec iov;
752 unsigned int i;
753
754 if (group_name->length > CPG_MAX_NAME_LENGTH) {
755 return (CS_ERR_NAME_TOO_LONG);
756 }
757 if (member_list == NULL) {
758 return (CS_ERR_INVALID_PARAM);
759 }
760 if (member_list_entries == NULL) {
761 return (CS_ERR_INVALID_PARAM);
762 }
763
764 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
765 if (error != CS_OK) {
766 return (error);
767 }
768
769 req_lib_cpg_membership_get.header.size = sizeof (struct req_lib_cpg_membership_get);
771
772 marshall_to_mar_cpg_name_t (&req_lib_cpg_membership_get.group_name,
773 group_name);
774
775 iov.iov_base = (void *)&req_lib_cpg_membership_get;
776 iov.iov_len = sizeof (struct req_lib_cpg_membership_get);
777
778 error = coroipcc_msg_send_reply_receive (cpg_inst->c, &iov, 1,
780
781 if (error != CS_OK) {
782 goto error_exit;
783 }
784
785 error = res_lib_cpg_membership_get.header.error;
786
787 /*
788 * Copy results to caller
789 */
790 *member_list_entries = res_lib_cpg_membership_get.member_count;
791 if (member_list) {
792 for (i = 0; i < res_lib_cpg_membership_get.member_count; i++) {
793 marshall_from_mar_cpg_address_t (&member_list[i],
795 }
796 }
797
799 hdb_handle_put (&cpg_handle_t_db, handle);
800
801 return (error);
802}
803
805 cpg_handle_t handle,
806 unsigned int *local_nodeid)
807{
809 struct cpg_inst *cpg_inst;
810 struct iovec iov;
813
814 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
815 if (error != CS_OK) {
816 return (error);
817 }
818
819 req_lib_cpg_local_get.header.size = sizeof (struct qb_ipc_request_header);
821
822 iov.iov_base = (void *)&req_lib_cpg_local_get;
823 iov.iov_len = sizeof (struct req_lib_cpg_local_get);
824
825 error = coroipcc_msg_send_reply_receive (cpg_inst->c, &iov, 1,
827
828 if (error != CS_OK) {
829 goto error_exit;
830 }
831
832 error = res_lib_cpg_local_get.header.error;
833
834 *local_nodeid = res_lib_cpg_local_get.local_nodeid;
835
837 hdb_handle_put (&cpg_handle_t_db, handle);
838
839 return (error);
840}
841
843 cpg_handle_t handle,
845{
847 struct cpg_inst *cpg_inst;
848
849 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
850 if (error != CS_OK) {
851 return (error);
852 }
854 error = CS_OK;
855
856 hdb_handle_put (&cpg_handle_t_db, handle);
857
858 return (error);
859}
860
861/*
862 * Dummy-ish function that just allocates some memory for the user
863 */
865 cpg_handle_t handle,
866 size_t size,
867 void **buffer)
868{
869 int error = CS_OK;
870
871 *buffer = malloc(size);
872 if (*buffer == NULL) {
874 }
875
876 return (error);
877}
878
880 cpg_handle_t handle,
881 void *buffer)
882{
883 free(buffer);
884 return (CS_OK);
885}
886
888 cpg_handle_t handle,
890 void *msg,
891 size_t msg_len)
892{
893 struct iovec iov[1];
894
895 iov[0].iov_base = msg;
896 iov[0].iov_len = msg_len;
897
898 return cpg_mcast_joined(handle, guarantee, iov, 1);
899}
900
901static cs_error_t send_fragments (
902 struct cpg_inst *cpg_inst,
904 size_t msg_len,
905 const struct iovec *iovec,
906 unsigned int iov_len)
907{
908 int i;
910 struct iovec iov[2];
913 size_t sent = 0;
914 size_t iov_sent = 0;
915 int retry_count;
916
918 req_lib_cpg_mcast.guarantee = guarantee;
919 req_lib_cpg_mcast.msglen = msg_len;
920
921 iov[0].iov_base = (void *)&req_lib_cpg_mcast;
922 iov[0].iov_len = sizeof (struct req_lib_cpg_partial_mcast);
923
924 i=0;
925 iov_sent = 0 ;
927
928 while (error == CS_OK && sent < msg_len) {
929
930 retry_count = 0;
932 iov[1].iov_len = cpg_inst->max_msg_size;
933 }
934 else {
935 iov[1].iov_len = iovec[i].iov_len - iov_sent;
936 }
937
938 if (sent == 0) {
940 }
941 else if ((sent + iov[1].iov_len) == msg_len) {
943 }
944 else {
946 }
947
948 req_lib_cpg_mcast.fraglen = iov[1].iov_len;
949 req_lib_cpg_mcast.header.size = sizeof (struct req_lib_cpg_partial_mcast) + iov[1].iov_len;
950 iov[1].iov_base = (char *)iovec[i].iov_base + iov_sent;
951
952 resend:
953 error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 2,
956
957 if (error == CS_ERR_TRY_AGAIN) {
958 fprintf(stderr, "sleep. counter=%d\n", retry_count);
959 if (++retry_count > MAX_RETRIES) {
960 goto error_exit;
961 }
962 usleep(10000);
963 goto resend;
964 }
965
966 iov_sent += iov[1].iov_len;
967 sent += iov[1].iov_len;
968
969 /* Next iovec */
970 if (iov_sent >= iovec[i].iov_len) {
971 i++;
972 iov_sent = 0;
973 }
974 error = res_lib_cpg_partial_send.header.error;
975 }
978
979 return error;
980}
981
982
984 cpg_handle_t handle,
986 const struct iovec *iovec,
987 unsigned int iov_len)
988{
989 int i;
991 struct cpg_inst *cpg_inst;
992 struct iovec iov[64];
994 size_t msg_len = 0;
995
996 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
997 if (error != CS_OK) {
998 return (error);
999 }
1000
1001 for (i = 0; i < iov_len; i++ ) {
1002 msg_len += iovec[i].iov_len;
1003 }
1004
1005 if (msg_len > cpg_inst->max_msg_size) {
1006 error = send_fragments(cpg_inst, guarantee, msg_len, iovec, iov_len);
1007 goto error_exit;
1008 }
1009
1010 req_lib_cpg_mcast.header.size = sizeof (struct req_lib_cpg_mcast) +
1011 msg_len;
1012
1014 req_lib_cpg_mcast.guarantee = guarantee;
1015 req_lib_cpg_mcast.msglen = msg_len;
1016
1017 iov[0].iov_base = (void *)&req_lib_cpg_mcast;
1018 iov[0].iov_len = sizeof (struct req_lib_cpg_mcast);
1019 memcpy (&iov[1], iovec, iov_len * sizeof (struct iovec));
1020
1024
1026 hdb_handle_put (&cpg_handle_t_db, handle);
1027
1028 return (error);
1029}
1030
1032 cpg_handle_t handle,
1034 const struct cpg_name *group,
1035 cpg_iteration_handle_t *cpg_iteration_handle)
1036{
1038 struct iovec iov;
1039 struct cpg_inst *cpg_inst;
1043
1044 if (group && group->length > CPG_MAX_NAME_LENGTH) {
1045 return (CS_ERR_NAME_TOO_LONG);
1046 }
1047 if (cpg_iteration_handle == NULL) {
1048 return (CS_ERR_INVALID_PARAM);
1049 }
1050
1051 if ((iteration_type == CPG_ITERATION_ONE_GROUP && group == NULL) ||
1052 (iteration_type != CPG_ITERATION_ONE_GROUP && group != NULL)) {
1053 return (CS_ERR_INVALID_PARAM);
1054 }
1055
1058
1059 return (CS_ERR_INVALID_PARAM);
1060 }
1061
1062 error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
1063 if (error != CS_OK) {
1064 return (error);
1065 }
1066
1067 error = hdb_error_to_cs (hdb_handle_create (&cpg_iteration_handle_t_db,
1068 sizeof (struct cpg_iteration_instance_t), cpg_iteration_handle));
1069 if (error != CS_OK) {
1070 goto error_put_cpg_db;
1071 }
1072
1073 error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, *cpg_iteration_handle,
1074 (void *)&cpg_iteration_instance));
1075 if (error != CS_OK) {
1076 goto error_destroy;
1077 }
1078
1080
1082
1086 if (group) {
1087 marshall_to_mar_cpg_name_t (&req_lib_cpg_iterationinitialize.group_name, group);
1088 }
1089
1090 iov.iov_base = (void *)&req_lib_cpg_iterationinitialize;
1091 iov.iov_len = sizeof (struct req_lib_cpg_iterationinitialize);
1092
1093 error = coroipcc_msg_send_reply_receive (cpg_inst->c,
1094 &iov,
1095 1,
1098
1099 if (error != CS_OK) {
1100 goto error_put_destroy;
1101 }
1102
1103 cpg_iteration_instance->executive_iteration_handle =
1104 res_lib_cpg_iterationinitialize.iteration_handle;
1105 cpg_iteration_instance->cpg_iteration_handle = *cpg_iteration_handle;
1106
1108
1109 hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
1110 hdb_handle_put (&cpg_handle_t_db, handle);
1111
1112 return (res_lib_cpg_iterationinitialize.header.error);
1113
1115 hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
1117 hdb_handle_destroy (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
1119 hdb_handle_put (&cpg_handle_t_db, handle);
1120
1121 return (error);
1122}
1123
1127{
1132
1133 if (description == NULL) {
1134 return CS_ERR_INVALID_PARAM;
1135 }
1136
1137 error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, handle,
1138 (void *)&cpg_iteration_instance));
1139 if (error != CS_OK) {
1140 goto error_exit;
1141 }
1142
1143 req_lib_cpg_iterationnext.header.size = sizeof (struct req_lib_cpg_iterationnext);
1145 req_lib_cpg_iterationnext.iteration_handle = cpg_iteration_instance->executive_iteration_handle;
1146
1149 req_lib_cpg_iterationnext.header.size));
1150 if (error != CS_OK) {
1151 goto error_put;
1152 }
1153
1156 sizeof(struct res_lib_cpg_iterationnext), -1));
1157 if (error != CS_OK) {
1158 goto error_put;
1159 }
1160
1161 marshall_from_mar_cpg_iteration_description_t(
1163 &res_lib_cpg_iterationnext.description);
1164
1165 error = res_lib_cpg_iterationnext.header.error;
1166
1167error_put:
1168 hdb_handle_put (&cpg_iteration_handle_t_db, handle);
1169
1171 return (error);
1172}
1173
1176{
1178 struct iovec iov;
1182
1183 error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, handle,
1184 (void *)&cpg_iteration_instance));
1185 if (error != CS_OK) {
1186 goto error_exit;
1187 }
1188
1191 req_lib_cpg_iterationfinalize.iteration_handle = cpg_iteration_instance->executive_iteration_handle;
1192
1193 iov.iov_base = (void *)&req_lib_cpg_iterationfinalize;
1194 iov.iov_len = sizeof (struct req_lib_cpg_iterationfinalize);
1195
1196 error = coroipcc_msg_send_reply_receive (cpg_iteration_instance->conn,
1197 &iov,
1198 1,
1201
1202 if (error != CS_OK) {
1203 goto error_put;
1204 }
1205
1206 cpg_iteration_instance_finalize (cpg_iteration_instance);
1207 hdb_handle_put (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle);
1208
1209 return (res_lib_cpg_iterationfinalize.header.error);
1210
1211error_put:
1212 hdb_handle_put (&cpg_iteration_handle_t_db, handle);
1214 return (error);
1215}
1216
unsigned int nodeid
the ID of the node whose info needs updating
Definition coroapi.h:0
cs_dispatch_flags_t
The cs_dispatch_flags_t enum.
Definition corotypes.h:84
@ CS_DISPATCH_ONE
Definition corotypes.h:85
@ CS_DISPATCH_ONE_NONBLOCKING
Definition corotypes.h:88
@ CS_DISPATCH_ALL
Definition corotypes.h:86
cs_error_t qb_to_cs_error(int result)
qb_to_cs_error
cs_error_t
The cs_error_t enum.
Definition corotypes.h:98
@ CS_ERR_NAME_TOO_LONG
Definition corotypes.h:111
@ CS_ERR_NO_MEMORY
Definition corotypes.h:106
@ CS_ERR_BUSY
Definition corotypes.h:108
@ CS_ERR_BAD_HANDLE
Definition corotypes.h:107
@ CS_ERR_TRY_AGAIN
Definition corotypes.h:104
@ CS_OK
Definition corotypes.h:99
@ CS_ERR_INVALID_PARAM
Definition corotypes.h:105
@ CS_ERR_LIBRARY
Definition corotypes.h:100
#define CS_IPC_TIMEOUT_MS
Definition corotypes.h:131
cs_error_t cpg_flow_control_state_get(cpg_handle_t handle, cpg_flow_control_state_t *flow_control_state)
cpg_flow_control_state_get
Definition lib/cpg.c:842
cs_error_t cpg_iteration_next(cpg_iteration_handle_t handle, struct cpg_iteration_description_t *description)
cpg_iteration_next
Definition lib/cpg.c:1124
cs_error_t cpg_model_initialize(cpg_handle_t *handle, cpg_model_t model, cpg_model_data_t *model_data, void *context)
Create a new cpg connection, initialize with model.
Definition lib/cpg.c:180
cs_error_t cpg_max_atomic_msgsize_get(cpg_handle_t handle, uint32_t *size)
Get maximum size of a message that will not be fragmented.
Definition lib/cpg.c:308
cs_error_t cpg_mcast_joined(cpg_handle_t handle, cpg_guarantee_t guarantee, const struct iovec *iovec, unsigned int iov_len)
Multicast to groups joined with cpg_join.
Definition lib/cpg.c:983
cs_error_t cpg_leave(cpg_handle_t handle, const struct cpg_name *group)
Leave one or more groups.
Definition lib/cpg.c:696
cs_error_t cpg_context_get(cpg_handle_t handle, void **context)
Get contexts for a CPG handle.
Definition lib/cpg.c:327
cs_error_t cpg_fd_get(cpg_handle_t handle, int *fd)
Get a file descriptor on which to poll.
Definition lib/cpg.c:289
cs_error_t cpg_join(cpg_handle_t handle, const struct cpg_name *group)
Join one or more groups.
Definition lib/cpg.c:642
cs_error_t cpg_zcb_free(cpg_handle_t handle, void *buffer)
cpg_zcb_free
Definition lib/cpg.c:879
cs_error_t cpg_iteration_finalize(cpg_iteration_handle_t handle)
cpg_iteration_finalize
Definition lib/cpg.c:1174
cs_error_t cpg_zcb_alloc(cpg_handle_t handle, size_t size, void **buffer)
cpg_zcb_alloc
Definition lib/cpg.c:864
cs_error_t cpg_membership_get(cpg_handle_t handle, struct cpg_name *group_name, struct cpg_address *member_list, int *member_list_entries)
Get membership information from cpg.
Definition lib/cpg.c:741
cs_error_t cpg_initialize(cpg_handle_t *handle, cpg_callbacks_t *callbacks)
Create a new cpg connection.
Definition lib/cpg.c:164
cs_error_t cpg_local_get(cpg_handle_t handle, unsigned int *local_nodeid)
cpg_local_get
Definition lib/cpg.c:804
cs_error_t cpg_iteration_initialize(cpg_handle_t handle, cpg_iteration_type_t iteration_type, const struct cpg_name *group, cpg_iteration_handle_t *cpg_iteration_handle)
cpg_iteration_initialize
Definition lib/cpg.c:1031
cs_error_t cpg_context_set(cpg_handle_t handle, void *context)
Set contexts for a CPG handle.
Definition lib/cpg.c:346
cs_error_t cpg_finalize(cpg_handle_t handle)
Close the cpg handle.
Definition lib/cpg.c:244
cs_error_t cpg_dispatch(cpg_handle_t handle, cs_dispatch_flags_t dispatch_types)
Dispatch messages and configuration changes.
Definition lib/cpg.c:365
cs_error_t cpg_zcb_mcast_joined(cpg_handle_t handle, cpg_guarantee_t guarantee, void *msg, size_t msg_len)
cpg_zcb_mcast_joined
Definition lib/cpg.c:887
cpg_flow_control_state_t
The cpg_flow_control_state_t enum.
Definition cpg.h:74
#define CPG_MAX_NAME_LENGTH
Definition cpg.h:117
cpg_guarantee_t
The cpg_guarantee_t enum.
Definition cpg.h:64
cpg_iteration_type_t
The cpg_iteration_type_t enum.
Definition cpg.h:95
uint64_t cpg_handle_t
cpg_handle_t
Definition cpg.h:54
uint64_t cpg_iteration_handle_t
cpg_iteration_handle_t
Definition cpg.h:59
cpg_model_t
The cpg_model_t enum.
Definition cpg.h:104
#define CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF
Definition cpg.h:194
#define CPG_MEMBERS_MAX
Definition cpg.h:126
@ CPG_FLOW_CONTROL_DISABLED
flow control is disabled - new messages may be sent
Definition cpg.h:75
@ CPG_ITERATION_ONE_GROUP
Definition cpg.h:97
@ CPG_ITERATION_ALL
Definition cpg.h:98
@ CPG_ITERATION_NAME_ONLY
Definition cpg.h:96
@ CPG_MODEL_V1
Definition cpg.h:105
#define DECLARE_HDB_DATABASE
Definition hdb.h:98
qb_handle_t hdb_handle_t
Definition hdb.h:52
@ LIBCPG_PARTIAL_FIRST
Definition ipc_cpg.h:102
@ LIBCPG_PARTIAL_LAST
Definition ipc_cpg.h:104
@ LIBCPG_PARTIAL_CONTINUED
Definition ipc_cpg.h:103
@ MESSAGE_REQ_CPG_LOCAL_GET
Definition ipc_cpg.h:51
@ MESSAGE_REQ_CPG_ITERATIONFINALIZE
Definition ipc_cpg.h:54
@ MESSAGE_REQ_CPG_PARTIAL_MCAST
Definition ipc_cpg.h:59
@ MESSAGE_REQ_CPG_JOIN
Definition ipc_cpg.h:47
@ MESSAGE_REQ_CPG_ITERATIONINITIALIZE
Definition ipc_cpg.h:52
@ MESSAGE_REQ_CPG_FINALIZE
Definition ipc_cpg.h:55
@ MESSAGE_REQ_CPG_MEMBERSHIP
Definition ipc_cpg.h:50
@ MESSAGE_REQ_CPG_LEAVE
Definition ipc_cpg.h:48
@ MESSAGE_REQ_CPG_ITERATIONNEXT
Definition ipc_cpg.h:53
@ MESSAGE_REQ_CPG_MCAST
Definition ipc_cpg.h:49
@ MESSAGE_RES_CPG_PARTIAL_DELIVER_CALLBACK
Definition ipc_cpg.h:83
@ MESSAGE_RES_CPG_DELIVER_CALLBACK
Definition ipc_cpg.h:71
@ MESSAGE_RES_CPG_TOTEM_CONFCHG_CALLBACK
Definition ipc_cpg.h:79
@ MESSAGE_RES_CPG_CONFCHG_CALLBACK
Definition ipc_cpg.h:70
#define MAX_RETRIES
Definition lib/cpg.c:76
#define IPC_REQUEST_SIZE
Definition lib/util.h:49
cs_error_t hdb_error_to_cs(int res)
#define IPC_DISPATCH_SIZE
Definition lib/util.h:51
The cpg_address struct.
Definition cpg.h:111
uint32_t nodeid
Definition lib/cpg.c:81
uint32_t assembly_buf_ptr
Definition lib/cpg.c:84
struct qb_list_head list
Definition lib/cpg.c:80
char * assembly_buf
Definition lib/cpg.c:83
uint32_t pid
Definition lib/cpg.c:82
The cpg_callbacks_t struct.
Definition cpg.h:182
cpg_deliver_fn_t cpg_deliver_fn
Definition cpg.h:183
cpg_confchg_fn_t cpg_confchg_fn
Definition cpg.h:184
int finalize
Definition lib/cpg.c:89
void * context
Definition lib/cpg.c:90
uint32_t max_msg_size
Definition lib/cpg.c:96
qb_ipcc_connection_t * c
Definition lib/cpg.c:88
struct qb_list_head assembly_list_head
Definition lib/cpg.c:97
cpg_model_t model
Definition lib/cpg.c:91
struct qb_list_head iteration_list_head
Definition lib/cpg.c:95
cpg_model_v1_data_t model_v1_data
Definition lib/cpg.c:93
The cpg_iteration_description_t struct.
Definition cpg.h:131
qb_ipcc_connection_t * conn
Definition lib/cpg.c:105
struct qb_list_head list
Definition lib/cpg.c:107
cpg_iteration_handle_t cpg_iteration_handle
Definition lib/cpg.c:104
hdb_handle_t executive_iteration_handle
Definition lib/cpg.c:106
struct qb_list_head list
Definition exec/cpg.c:155
The cpg_model_data_t struct.
Definition cpg.h:190
The cpg_model_v1_data_t struct.
Definition cpg.h:199
unsigned int flags
Definition cpg.h:204
cpg_confchg_fn_t cpg_confchg_fn
Definition cpg.h:202
cpg_deliver_fn_t cpg_deliver_fn
Definition cpg.h:201
The cpg_name struct.
Definition cpg.h:121
uint32_t length
Definition cpg.h:122
The cpg_ring_id struct.
Definition cpg.h:140
mar_cpg_address_t struct
Definition ipc_cpg.h:153
The req_lib_cpg_finalize struct.
Definition ipc_cpg.h:266
The req_lib_cpg_iterationfinalize struct.
Definition ipc_cpg.h:462
The req_lib_cpg_iterationinitialize struct.
Definition ipc_cpg.h:429
The req_lib_cpg_iterationnext struct.
Definition ipc_cpg.h:446
The req_lib_cpg_join struct.
Definition ipc_cpg.h:249
The req_lib_cpg_leave struct.
Definition ipc_cpg.h:413
The req_lib_cpg_local_get struct.
Definition ipc_cpg.h:280
The req_lib_cpg_mcast struct.
Definition ipc_cpg.h:309
The req_lib_cpg_membership_get struct.
Definition ipc_cpg.h:372
The req_lib_cpg_partial_mcast struct.
Definition ipc_cpg.h:319
The res_lib_cpg_confchg_callback struct.
Definition ipc_cpg.h:389
mar_cpg_address_t member_list[]
Definition ipc_cpg.h:395
Message from another node.
Definition ipc_cpg.h:338
The res_lib_cpg_finalize struct.
Definition ipc_cpg.h:273
The res_lib_cpg_iterationfinalize struct.
Definition ipc_cpg.h:470
The res_lib_cpg_iterationinitialize struct.
Definition ipc_cpg.h:438
The res_lib_cpg_iterationnext struct.
Definition ipc_cpg.h:454
The res_lib_cpg_join struct.
Definition ipc_cpg.h:259
The res_lib_cpg_leave struct.
Definition ipc_cpg.h:422
The res_lib_cpg_local_get struct.
Definition ipc_cpg.h:294
The res_lib_cpg_membership_get struct.
Definition ipc_cpg.h:380
mar_cpg_address_t member_list[PROCESSOR_COUNT_MAX]
Definition ipc_cpg.h:383
The res_lib_cpg_partial_deliver_callback struct.
Definition ipc_cpg.h:350
The res_lib_cpg_partial_send struct.
Definition ipc_cpg.h:302
The res_lib_cpg_totem_confchg_callback struct.
Definition ipc_cpg.h:403
int guarantee
Definition totemsrp.c:6
struct memb_ring_id ring_id
Definition totemsrp.c:4