corosync  2.3.4
lib/cpg.c
Go to the documentation of this file.
1 /*
2  * vi: set autoindent tabstop=4 shiftwidth=4 :
3  *
4  * Copyright (c) 2006-2012 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/qbdefs.h>
56 #include <qb/qbipcc.h>
57 #include <qb/qblog.h>
58 
59 #include <corosync/hdb.h>
60 #include <corosync/list.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  * ZCB files have following umask (umask is same as used in libqb)
74  */
75 #define CPG_MEMORY_MAP_UMASK 077
76 
77 struct cpg_inst {
78  qb_ipcc_connection_t *c;
79  int finalize;
80  void *context;
81  union {
84  };
86 };
87 static void cpg_inst_free (void *inst);
88 
89 DECLARE_HDB_DATABASE(cpg_handle_t_db, cpg_inst_free);
90 
93  qb_ipcc_connection_t *conn;
95  struct list_head list;
96 };
97 
98 DECLARE_HDB_DATABASE(cpg_iteration_handle_t_db,NULL);
99 
100 
101 /*
102  * Internal (not visible by API) functions
103  */
104 
105 static cs_error_t
106 coroipcc_msg_send_reply_receive (
107  qb_ipcc_connection_t *c,
108  const struct iovec *iov,
109  unsigned int iov_len,
110  void *res_msg,
111  size_t res_len)
112 {
113  return qb_to_cs_error(qb_ipcc_sendv_recv(c, iov, iov_len, res_msg, res_len,
115 }
116 
117 static void cpg_iteration_instance_finalize (struct cpg_iteration_instance_t *cpg_iteration_instance)
118 {
119  list_del (&cpg_iteration_instance->list);
120  hdb_handle_destroy (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle);
121 }
122 
123 static void cpg_inst_free (void *inst)
124 {
125  struct cpg_inst *cpg_inst = (struct cpg_inst *)inst;
126  qb_ipcc_disconnect(cpg_inst->c);
127 }
128 
129 static void cpg_inst_finalize (struct cpg_inst *cpg_inst, hdb_handle_t handle)
130 {
131  struct list_head *iter, *iter_next;
133 
134  /*
135  * Traverse thru iteration instances and delete them
136  */
137  for (iter = cpg_inst->iteration_list_head.next; iter != &cpg_inst->iteration_list_head;iter = iter_next) {
138  iter_next = iter->next;
139 
140  cpg_iteration_instance = list_entry (iter, struct cpg_iteration_instance_t, list);
141 
142  cpg_iteration_instance_finalize (cpg_iteration_instance);
143  }
144  hdb_handle_destroy (&cpg_handle_t_db, handle);
145 }
146 
155  cpg_handle_t *handle,
156  cpg_callbacks_t *callbacks)
157 {
158  cpg_model_v1_data_t model_v1_data;
159 
160  memset (&model_v1_data, 0, sizeof (cpg_model_v1_data_t));
161 
162  if (callbacks) {
163  model_v1_data.cpg_deliver_fn = callbacks->cpg_deliver_fn;
164  model_v1_data.cpg_confchg_fn = callbacks->cpg_confchg_fn;
165  }
166 
167  return (cpg_model_initialize (handle, CPG_MODEL_V1, (cpg_model_data_t *)&model_v1_data, NULL));
168 }
169 
171  cpg_handle_t *handle,
172  cpg_model_t model,
173  cpg_model_data_t *model_data,
174  void *context)
175 {
176  cs_error_t error;
177  struct cpg_inst *cpg_inst;
178 
179  if (model != CPG_MODEL_V1) {
180  error = CS_ERR_INVALID_PARAM;
181  goto error_no_destroy;
182  }
183 
184  error = hdb_error_to_cs (hdb_handle_create (&cpg_handle_t_db, sizeof (struct cpg_inst), handle));
185  if (error != CS_OK) {
186  goto error_no_destroy;
187  }
188 
189  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, *handle, (void *)&cpg_inst));
190  if (error != CS_OK) {
191  goto error_destroy;
192  }
193 
194  cpg_inst->c = qb_ipcc_connect ("cpg", IPC_REQUEST_SIZE);
195  if (cpg_inst->c == NULL) {
196  error = qb_to_cs_error(-errno);
197  goto error_put_destroy;
198  }
199 
200  if (model_data != NULL) {
201  switch (model) {
202  case CPG_MODEL_V1:
203  memcpy (&cpg_inst->model_v1_data, model_data, sizeof (cpg_model_v1_data_t));
204  if ((cpg_inst->model_v1_data.flags & ~(CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF)) != 0) {
205  error = CS_ERR_INVALID_PARAM;
206 
207  goto error_destroy;
208  }
209  break;
210  }
211  }
212 
213  cpg_inst->model_data.model = model;
214  cpg_inst->context = context;
215 
216  list_init(&cpg_inst->iteration_list_head);
217 
218  hdb_handle_put (&cpg_handle_t_db, *handle);
219 
220  return (CS_OK);
221 
222 error_put_destroy:
223  hdb_handle_put (&cpg_handle_t_db, *handle);
224 error_destroy:
225  hdb_handle_destroy (&cpg_handle_t_db, *handle);
226 error_no_destroy:
227  return (error);
228 }
229 
231  cpg_handle_t handle)
232 {
233  struct cpg_inst *cpg_inst;
234  struct iovec iov;
235  struct req_lib_cpg_finalize req_lib_cpg_finalize;
236  struct res_lib_cpg_finalize res_lib_cpg_finalize;
237  cs_error_t error;
238 
239  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
240  if (error != CS_OK) {
241  return (error);
242  }
243 
244  /*
245  * Another thread has already started finalizing
246  */
247  if (cpg_inst->finalize) {
248  hdb_handle_put (&cpg_handle_t_db, handle);
249  return (CS_ERR_BAD_HANDLE);
250  }
251 
252  cpg_inst->finalize = 1;
253 
254  /*
255  * Send service request
256  */
257  req_lib_cpg_finalize.header.size = sizeof (struct req_lib_cpg_finalize);
258  req_lib_cpg_finalize.header.id = MESSAGE_REQ_CPG_FINALIZE;
259 
260  iov.iov_base = (void *)&req_lib_cpg_finalize;
261  iov.iov_len = sizeof (struct req_lib_cpg_finalize);
262 
263  error = coroipcc_msg_send_reply_receive (cpg_inst->c,
264  &iov,
265  1,
266  &res_lib_cpg_finalize,
267  sizeof (struct res_lib_cpg_finalize));
268 
269  cpg_inst_finalize (cpg_inst, handle);
270  hdb_handle_put (&cpg_handle_t_db, handle);
271 
272  return (error);
273 }
274 
276  cpg_handle_t handle,
277  int *fd)
278 {
279  cs_error_t error;
280  struct cpg_inst *cpg_inst;
281 
282  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
283  if (error != CS_OK) {
284  return (error);
285  }
286 
287  error = qb_to_cs_error (qb_ipcc_fd_get (cpg_inst->c, fd));
288 
289  hdb_handle_put (&cpg_handle_t_db, handle);
290 
291  return (error);
292 }
293 
295  cpg_handle_t handle,
296  void **context)
297 {
298  cs_error_t error;
299  struct cpg_inst *cpg_inst;
300 
301  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
302  if (error != CS_OK) {
303  return (error);
304  }
305 
306  *context = cpg_inst->context;
307 
308  hdb_handle_put (&cpg_handle_t_db, handle);
309 
310  return (CS_OK);
311 }
312 
314  cpg_handle_t handle,
315  void *context)
316 {
317  cs_error_t error;
318  struct cpg_inst *cpg_inst;
319 
320  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
321  if (error != CS_OK) {
322  return (error);
323  }
324 
325  cpg_inst->context = context;
326 
327  hdb_handle_put (&cpg_handle_t_db, handle);
328 
329  return (CS_OK);
330 }
331 
333  cpg_handle_t handle,
334  cs_dispatch_flags_t dispatch_types)
335 {
336  int timeout = -1;
337  cs_error_t error;
338  int cont = 1; /* always continue do loop except when set to 0 */
339  struct cpg_inst *cpg_inst;
340  struct res_lib_cpg_confchg_callback *res_cpg_confchg_callback;
341  struct res_lib_cpg_deliver_callback *res_cpg_deliver_callback;
342  struct res_lib_cpg_totem_confchg_callback *res_cpg_totem_confchg_callback;
343  struct cpg_inst cpg_inst_copy;
344  struct qb_ipc_response_header *dispatch_data;
345  struct cpg_address member_list[CPG_MEMBERS_MAX];
346  struct cpg_address left_list[CPG_MEMBERS_MAX];
347  struct cpg_address joined_list[CPG_MEMBERS_MAX];
348  struct cpg_name group_name;
349  mar_cpg_address_t *left_list_start;
350  mar_cpg_address_t *joined_list_start;
351  unsigned int i;
352  struct cpg_ring_id ring_id;
353  uint32_t totem_member_list[CPG_MEMBERS_MAX];
354  int32_t errno_res;
355  char dispatch_buf[IPC_DISPATCH_SIZE];
356 
357  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
358  if (error != CS_OK) {
359  return (error);
360  }
361 
362  /*
363  * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
364  * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
365  */
366  if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
367  timeout = 0;
368  }
369 
370  dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
371  do {
372  errno_res = qb_ipcc_event_recv (
373  cpg_inst->c,
374  dispatch_buf,
376  timeout);
377  error = qb_to_cs_error (errno_res);
378  if (error == CS_ERR_BAD_HANDLE) {
379  error = CS_OK;
380  goto error_put;
381  }
382  if (error == CS_ERR_TRY_AGAIN) {
383  if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
384  /*
385  * Don't mask error
386  */
387  goto error_put;
388  }
389  error = CS_OK;
390  if (dispatch_types == CS_DISPATCH_ALL) {
391  break; /* exit do while cont is 1 loop */
392  } else {
393  continue; /* next poll */
394  }
395  }
396  if (error != CS_OK) {
397  goto error_put;
398  }
399 
400  /*
401  * Make copy of callbacks, message data, unlock instance, and call callback
402  * A risk of this dispatch method is that the callback routines may
403  * operate at the same time that cpgFinalize has been called.
404  */
405  memcpy (&cpg_inst_copy, cpg_inst, sizeof (struct cpg_inst));
406  switch (cpg_inst_copy.model_data.model) {
407  case CPG_MODEL_V1:
408  /*
409  * Dispatch incoming message
410  */
411  switch (dispatch_data->id) {
413  if (cpg_inst_copy.model_v1_data.cpg_deliver_fn == NULL) {
414  break;
415  }
416 
417  res_cpg_deliver_callback = (struct res_lib_cpg_deliver_callback *)dispatch_data;
418 
419  marshall_from_mar_cpg_name_t (
420  &group_name,
421  &res_cpg_deliver_callback->group_name);
422 
423  cpg_inst_copy.model_v1_data.cpg_deliver_fn (handle,
424  &group_name,
425  res_cpg_deliver_callback->nodeid,
426  res_cpg_deliver_callback->pid,
427  &res_cpg_deliver_callback->message,
428  res_cpg_deliver_callback->msglen);
429  break;
430 
432  if (cpg_inst_copy.model_v1_data.cpg_confchg_fn == NULL) {
433  break;
434  }
435 
436  res_cpg_confchg_callback = (struct res_lib_cpg_confchg_callback *)dispatch_data;
437 
438  for (i = 0; i < res_cpg_confchg_callback->member_list_entries; i++) {
439  marshall_from_mar_cpg_address_t (&member_list[i],
440  &res_cpg_confchg_callback->member_list[i]);
441  }
442  left_list_start = res_cpg_confchg_callback->member_list +
443  res_cpg_confchg_callback->member_list_entries;
444  for (i = 0; i < res_cpg_confchg_callback->left_list_entries; i++) {
445  marshall_from_mar_cpg_address_t (&left_list[i],
446  &left_list_start[i]);
447  }
448  joined_list_start = res_cpg_confchg_callback->member_list +
449  res_cpg_confchg_callback->member_list_entries +
450  res_cpg_confchg_callback->left_list_entries;
451  for (i = 0; i < res_cpg_confchg_callback->joined_list_entries; i++) {
452  marshall_from_mar_cpg_address_t (&joined_list[i],
453  &joined_list_start[i]);
454  }
455  marshall_from_mar_cpg_name_t (
456  &group_name,
457  &res_cpg_confchg_callback->group_name);
458 
459  cpg_inst_copy.model_v1_data.cpg_confchg_fn (handle,
460  &group_name,
461  member_list,
462  res_cpg_confchg_callback->member_list_entries,
463  left_list,
464  res_cpg_confchg_callback->left_list_entries,
465  joined_list,
466  res_cpg_confchg_callback->joined_list_entries);
467 
468  break;
470  if (cpg_inst_copy.model_v1_data.cpg_totem_confchg_fn == NULL) {
471  break;
472  }
473 
474  res_cpg_totem_confchg_callback = (struct res_lib_cpg_totem_confchg_callback *)dispatch_data;
475 
476  marshall_from_mar_cpg_ring_id_t (&ring_id, &res_cpg_totem_confchg_callback->ring_id);
477  for (i = 0; i < res_cpg_totem_confchg_callback->member_list_entries; i++) {
478  totem_member_list[i] = res_cpg_totem_confchg_callback->member_list[i];
479  }
480 
481  cpg_inst_copy.model_v1_data.cpg_totem_confchg_fn (handle,
482  ring_id,
483  res_cpg_totem_confchg_callback->member_list_entries,
484  totem_member_list);
485  break;
486  default:
487  error = CS_ERR_LIBRARY;
488  goto error_put;
489  break;
490  } /* - switch (dispatch_data->id) */
491  break; /* case CPG_MODEL_V1 */
492  } /* - switch (cpg_inst_copy.model_data.model) */
493 
494  if (cpg_inst_copy.finalize || cpg_inst->finalize) {
495  /*
496  * If the finalize has been called then get out of the dispatch.
497  */
498  cpg_inst->finalize = 1;
499  error = CS_ERR_BAD_HANDLE;
500  goto error_put;
501  }
502 
503  /*
504  * Determine if more messages should be processed
505  */
506  if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
507  cont = 0;
508  }
509  } while (cont);
510 
511 error_put:
512  hdb_handle_put (&cpg_handle_t_db, handle);
513  return (error);
514 }
515 
517  cpg_handle_t handle,
518  const struct cpg_name *group)
519 {
520  cs_error_t error;
521  struct cpg_inst *cpg_inst;
522  struct iovec iov[2];
523  struct req_lib_cpg_join req_lib_cpg_join;
524  struct res_lib_cpg_join response;
525 
526  if (group->length > CPG_MAX_NAME_LENGTH) {
527  return (CS_ERR_NAME_TOO_LONG);
528  }
529 
530  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
531  if (error != CS_OK) {
532  return (error);
533  }
534 
535  /* Now join */
536  req_lib_cpg_join.header.size = sizeof (struct req_lib_cpg_join);
537  req_lib_cpg_join.header.id = MESSAGE_REQ_CPG_JOIN;
538  req_lib_cpg_join.pid = getpid();
539  req_lib_cpg_join.flags = 0;
540 
541  switch (cpg_inst->model_data.model) {
542  case CPG_MODEL_V1:
543  req_lib_cpg_join.flags = cpg_inst->model_v1_data.flags;
544  break;
545  }
546 
547  marshall_to_mar_cpg_name_t (&req_lib_cpg_join.group_name,
548  group);
549 
550  iov[0].iov_base = (void *)&req_lib_cpg_join;
551  iov[0].iov_len = sizeof (struct req_lib_cpg_join);
552 
553  do {
554  error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 1,
555  &response, sizeof (struct res_lib_cpg_join));
556 
557  if (error != CS_OK) {
558  goto error_exit;
559  }
560  } while (response.header.error == CS_ERR_BUSY);
561 
562  error = response.header.error;
563 
564 error_exit:
565  hdb_handle_put (&cpg_handle_t_db, handle);
566 
567  return (error);
568 }
569 
571  cpg_handle_t handle,
572  const struct cpg_name *group)
573 {
574  cs_error_t error;
575  struct cpg_inst *cpg_inst;
576  struct iovec iov[2];
577  struct req_lib_cpg_leave req_lib_cpg_leave;
578  struct res_lib_cpg_leave res_lib_cpg_leave;
579 
580  if (group->length > CPG_MAX_NAME_LENGTH) {
581  return (CS_ERR_NAME_TOO_LONG);
582  }
583 
584  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
585  if (error != CS_OK) {
586  return (error);
587  }
588 
589  req_lib_cpg_leave.header.size = sizeof (struct req_lib_cpg_leave);
590  req_lib_cpg_leave.header.id = MESSAGE_REQ_CPG_LEAVE;
591  req_lib_cpg_leave.pid = getpid();
592  marshall_to_mar_cpg_name_t (&req_lib_cpg_leave.group_name,
593  group);
594 
595  iov[0].iov_base = (void *)&req_lib_cpg_leave;
596  iov[0].iov_len = sizeof (struct req_lib_cpg_leave);
597 
598  do {
599  error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 1,
600  &res_lib_cpg_leave, sizeof (struct res_lib_cpg_leave));
601 
602  if (error != CS_OK) {
603  goto error_exit;
604  }
605  } while (res_lib_cpg_leave.header.error == CS_ERR_BUSY);
606 
607  error = res_lib_cpg_leave.header.error;
608 
609 error_exit:
610  hdb_handle_put (&cpg_handle_t_db, handle);
611 
612  return (error);
613 }
614 
616  cpg_handle_t handle,
617  struct cpg_name *group_name,
618  struct cpg_address *member_list,
619  int *member_list_entries)
620 {
621  cs_error_t error;
622  struct cpg_inst *cpg_inst;
623  struct iovec iov;
624  struct req_lib_cpg_membership_get req_lib_cpg_membership_get;
625  struct res_lib_cpg_membership_get res_lib_cpg_membership_get;
626  unsigned int i;
627 
628  if (group_name->length > CPG_MAX_NAME_LENGTH) {
629  return (CS_ERR_NAME_TOO_LONG);
630  }
631  if (member_list == NULL) {
632  return (CS_ERR_INVALID_PARAM);
633  }
634  if (member_list_entries == NULL) {
635  return (CS_ERR_INVALID_PARAM);
636  }
637 
638  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
639  if (error != CS_OK) {
640  return (error);
641  }
642 
643  req_lib_cpg_membership_get.header.size = sizeof (struct req_lib_cpg_membership_get);
644  req_lib_cpg_membership_get.header.id = MESSAGE_REQ_CPG_MEMBERSHIP;
645 
646  marshall_to_mar_cpg_name_t (&req_lib_cpg_membership_get.group_name,
647  group_name);
648 
649  iov.iov_base = (void *)&req_lib_cpg_membership_get;
650  iov.iov_len = sizeof (struct req_lib_cpg_membership_get);
651 
652  error = coroipcc_msg_send_reply_receive (cpg_inst->c, &iov, 1,
653  &res_lib_cpg_membership_get, sizeof (res_lib_cpg_membership_get));
654 
655  if (error != CS_OK) {
656  goto error_exit;
657  }
658 
659  error = res_lib_cpg_membership_get.header.error;
660 
661  /*
662  * Copy results to caller
663  */
664  *member_list_entries = res_lib_cpg_membership_get.member_count;
665  if (member_list) {
666  for (i = 0; i < res_lib_cpg_membership_get.member_count; i++) {
667  marshall_from_mar_cpg_address_t (&member_list[i],
668  &res_lib_cpg_membership_get.member_list[i]);
669  }
670  }
671 
672 error_exit:
673  hdb_handle_put (&cpg_handle_t_db, handle);
674 
675  return (error);
676 }
677 
679  cpg_handle_t handle,
680  unsigned int *local_nodeid)
681 {
682  cs_error_t error;
683  struct cpg_inst *cpg_inst;
684  struct iovec iov;
685  struct req_lib_cpg_local_get req_lib_cpg_local_get;
686  struct res_lib_cpg_local_get res_lib_cpg_local_get;
687 
688  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
689  if (error != CS_OK) {
690  return (error);
691  }
692 
693  req_lib_cpg_local_get.header.size = sizeof (struct qb_ipc_request_header);
694  req_lib_cpg_local_get.header.id = MESSAGE_REQ_CPG_LOCAL_GET;
695 
696  iov.iov_base = (void *)&req_lib_cpg_local_get;
697  iov.iov_len = sizeof (struct req_lib_cpg_local_get);
698 
699  error = coroipcc_msg_send_reply_receive (cpg_inst->c, &iov, 1,
700  &res_lib_cpg_local_get, sizeof (res_lib_cpg_local_get));
701 
702  if (error != CS_OK) {
703  goto error_exit;
704  }
705 
706  error = res_lib_cpg_local_get.header.error;
707 
708  *local_nodeid = res_lib_cpg_local_get.local_nodeid;
709 
710 error_exit:
711  hdb_handle_put (&cpg_handle_t_db, handle);
712 
713  return (error);
714 }
715 
717  cpg_handle_t handle,
718  cpg_flow_control_state_t *flow_control_state)
719 {
720  cs_error_t error;
721  struct cpg_inst *cpg_inst;
722 
723  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
724  if (error != CS_OK) {
725  return (error);
726  }
727  *flow_control_state = CPG_FLOW_CONTROL_DISABLED;
728  error = CS_OK;
729 
730  hdb_handle_put (&cpg_handle_t_db, handle);
731 
732  return (error);
733 }
734 
735 static int
736 memory_map (char *path, const char *file, void **buf, size_t bytes)
737 {
738  int32_t fd;
739  void *addr;
740  int32_t res;
741  char *buffer;
742  int32_t i;
743  size_t written;
744  size_t page_size;
745  long int sysconf_page_size;
746  mode_t old_umask;
747 
748  snprintf (path, PATH_MAX, "/dev/shm/%s", file);
749 
750  old_umask = umask(CPG_MEMORY_MAP_UMASK);
751  fd = mkstemp (path);
752  (void)umask(old_umask);
753  if (fd == -1) {
754  snprintf (path, PATH_MAX, LOCALSTATEDIR "/run/%s", file);
755  old_umask = umask(CPG_MEMORY_MAP_UMASK);
756  fd = mkstemp (path);
757  (void)umask(old_umask);
758  if (fd == -1) {
759  return (-1);
760  }
761  }
762 
763  res = ftruncate (fd, bytes);
764  if (res == -1) {
765  goto error_close_unlink;
766  }
767  sysconf_page_size = sysconf(_SC_PAGESIZE);
768  if (sysconf_page_size <= 0) {
769  goto error_close_unlink;
770  }
771  page_size = sysconf_page_size;
772  buffer = malloc (page_size);
773  if (buffer == NULL) {
774  goto error_close_unlink;
775  }
776  memset (buffer, 0, page_size);
777  for (i = 0; i < (bytes / page_size); i++) {
778 retry_write:
779  written = write (fd, buffer, page_size);
780  if (written == -1 && errno == EINTR) {
781  goto retry_write;
782  }
783  if (written != page_size) {
784  free (buffer);
785  goto error_close_unlink;
786  }
787  }
788  free (buffer);
789 
790  addr = mmap (NULL, bytes, PROT_READ | PROT_WRITE,
791  MAP_SHARED, fd, 0);
792 
793  if (addr == MAP_FAILED) {
794  goto error_close_unlink;
795  }
796 #ifdef MADV_NOSYNC
797  madvise(addr, bytes, MADV_NOSYNC);
798 #endif
799 
800  res = close (fd);
801  if (res) {
802  return (-1);
803  }
804  *buf = addr;
805 
806  return 0;
807 
808 error_close_unlink:
809  close (fd);
810  unlink(path);
811  return -1;
812 }
813 
815  cpg_handle_t handle,
816  size_t size,
817  void **buffer)
818 {
819  void *buf = NULL;
820  char path[PATH_MAX];
821  mar_req_coroipcc_zc_alloc_t req_coroipcc_zc_alloc;
822  struct qb_ipc_response_header res_coroipcs_zc_alloc;
823  size_t map_size;
824  struct iovec iovec;
825  struct coroipcs_zc_header *hdr;
826  cs_error_t error;
827  struct cpg_inst *cpg_inst;
828 
829  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
830  if (error != CS_OK) {
831  return (error);
832  }
833 
834  map_size = size + sizeof (struct req_lib_cpg_mcast) + sizeof (struct coroipcs_zc_header);
835  assert(memory_map (path, "corosync_zerocopy-XXXXXX", &buf, map_size) != -1);
836 
837  if (strlen(path) >= CPG_ZC_PATH_LEN) {
838  unlink(path);
839  munmap (buf, map_size);
840  return (CS_ERR_NAME_TOO_LONG);
841  }
842 
843  req_coroipcc_zc_alloc.header.size = sizeof (mar_req_coroipcc_zc_alloc_t);
844  req_coroipcc_zc_alloc.header.id = MESSAGE_REQ_CPG_ZC_ALLOC;
845  req_coroipcc_zc_alloc.map_size = map_size;
846  strcpy (req_coroipcc_zc_alloc.path_to_file, path);
847 
848  iovec.iov_base = (void *)&req_coroipcc_zc_alloc;
849  iovec.iov_len = sizeof (mar_req_coroipcc_zc_alloc_t);
850 
851  error = coroipcc_msg_send_reply_receive (
852  cpg_inst->c,
853  &iovec,
854  1,
855  &res_coroipcs_zc_alloc,
856  sizeof (struct qb_ipc_response_header));
857 
858  hdr = (struct coroipcs_zc_header *)buf;
859  hdr->map_size = map_size;
860  *buffer = ((char *)buf) + sizeof (struct coroipcs_zc_header);
861 
862  hdb_handle_put (&cpg_handle_t_db, handle);
863  *buffer = ((char *)*buffer) + sizeof (struct req_lib_cpg_mcast);
864 
865  return (error);
866 }
867 
869  cpg_handle_t handle,
870  void *buffer)
871 {
872  cs_error_t error;
873  struct cpg_inst *cpg_inst;
874  mar_req_coroipcc_zc_free_t req_coroipcc_zc_free;
875  struct qb_ipc_response_header res_coroipcs_zc_free;
876  struct iovec iovec;
877  struct coroipcs_zc_header *header = (struct coroipcs_zc_header *)((char *)buffer - sizeof (struct coroipcs_zc_header));
878 
879  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
880  if (error != CS_OK) {
881  return (error);
882  }
883 
884  req_coroipcc_zc_free.header.size = sizeof (mar_req_coroipcc_zc_free_t);
885  req_coroipcc_zc_free.header.id = MESSAGE_REQ_CPG_ZC_FREE;
886  req_coroipcc_zc_free.map_size = header->map_size;
887  req_coroipcc_zc_free.server_address = header->server_address;
888 
889  iovec.iov_base = (void *)&req_coroipcc_zc_free;
890  iovec.iov_len = sizeof (mar_req_coroipcc_zc_free_t);
891 
892  error = coroipcc_msg_send_reply_receive (
893  cpg_inst->c,
894  &iovec,
895  1,
896  &res_coroipcs_zc_free,
897  sizeof (struct qb_ipc_response_header));
898 
899  munmap ((void *)header, header->map_size);
900 
901  hdb_handle_put (&cpg_handle_t_db, handle);
902 
903  return (error);
904 }
905 
907  cpg_handle_t handle,
909  void *msg,
910  size_t msg_len)
911 {
912  cs_error_t error;
913  struct cpg_inst *cpg_inst;
915  struct res_lib_cpg_mcast res_lib_cpg_mcast;
916  mar_req_coroipcc_zc_execute_t req_coroipcc_zc_execute;
917  struct coroipcs_zc_header *hdr;
918  struct iovec iovec;
919 
920  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
921  if (error != CS_OK) {
922  return (error);
923  }
924  req_lib_cpg_mcast = (struct req_lib_cpg_mcast *)(((char *)msg) - sizeof (struct req_lib_cpg_mcast));
925  req_lib_cpg_mcast->header.size = sizeof (struct req_lib_cpg_mcast) +
926  msg_len;
927 
928  req_lib_cpg_mcast->header.id = MESSAGE_REQ_CPG_MCAST;
929  req_lib_cpg_mcast->guarantee = guarantee;
930  req_lib_cpg_mcast->msglen = msg_len;
931 
932  hdr = (struct coroipcs_zc_header *)(((char *)req_lib_cpg_mcast) - sizeof (struct coroipcs_zc_header));
933 
934  req_coroipcc_zc_execute.header.size = sizeof (mar_req_coroipcc_zc_execute_t);
935  req_coroipcc_zc_execute.header.id = MESSAGE_REQ_CPG_ZC_EXECUTE;
936  req_coroipcc_zc_execute.server_address = hdr->server_address;
937 
938  iovec.iov_base = (void *)&req_coroipcc_zc_execute;
939  iovec.iov_len = sizeof (mar_req_coroipcc_zc_execute_t);
940 
941  error = coroipcc_msg_send_reply_receive (
942  cpg_inst->c,
943  &iovec,
944  1,
945  &res_lib_cpg_mcast,
946  sizeof(res_lib_cpg_mcast));
947 
948  if (error != CS_OK) {
949  goto error_exit;
950  }
951 
952  error = res_lib_cpg_mcast.header.error;
953 
954 error_exit:
955  hdb_handle_put (&cpg_handle_t_db, handle);
956 
957  return (error);
958 }
959 
961  cpg_handle_t handle,
963  const struct iovec *iovec,
964  unsigned int iov_len)
965 {
966  int i;
967  cs_error_t error;
968  struct cpg_inst *cpg_inst;
969  struct iovec iov[64];
970  struct req_lib_cpg_mcast req_lib_cpg_mcast;
971  size_t msg_len = 0;
972 
973  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
974  if (error != CS_OK) {
975  return (error);
976  }
977 
978  for (i = 0; i < iov_len; i++ ) {
979  msg_len += iovec[i].iov_len;
980  }
981 
982  req_lib_cpg_mcast.header.size = sizeof (struct req_lib_cpg_mcast) +
983  msg_len;
984 
985  req_lib_cpg_mcast.header.id = MESSAGE_REQ_CPG_MCAST;
986  req_lib_cpg_mcast.guarantee = guarantee;
987  req_lib_cpg_mcast.msglen = msg_len;
988 
989  iov[0].iov_base = (void *)&req_lib_cpg_mcast;
990  iov[0].iov_len = sizeof (struct req_lib_cpg_mcast);
991  memcpy (&iov[1], iovec, iov_len * sizeof (struct iovec));
992 
993  qb_ipcc_fc_enable_max_set(cpg_inst->c, 2);
994  error = qb_to_cs_error(qb_ipcc_sendv(cpg_inst->c, iov, iov_len + 1));
995  qb_ipcc_fc_enable_max_set(cpg_inst->c, 1);
996 
997  hdb_handle_put (&cpg_handle_t_db, handle);
998 
999  return (error);
1000 }
1001 
1003  cpg_handle_t handle,
1004  cpg_iteration_type_t iteration_type,
1005  const struct cpg_name *group,
1006  cpg_iteration_handle_t *cpg_iteration_handle)
1007 {
1008  cs_error_t error;
1009  struct iovec iov;
1010  struct cpg_inst *cpg_inst;
1011  struct cpg_iteration_instance_t *cpg_iteration_instance;
1012  struct req_lib_cpg_iterationinitialize req_lib_cpg_iterationinitialize;
1013  struct res_lib_cpg_iterationinitialize res_lib_cpg_iterationinitialize;
1014 
1015  if (group && group->length > CPG_MAX_NAME_LENGTH) {
1016  return (CS_ERR_NAME_TOO_LONG);
1017  }
1018  if (cpg_iteration_handle == NULL) {
1019  return (CS_ERR_INVALID_PARAM);
1020  }
1021 
1022  if ((iteration_type == CPG_ITERATION_ONE_GROUP && group == NULL) ||
1023  (iteration_type != CPG_ITERATION_ONE_GROUP && group != NULL)) {
1024  return (CS_ERR_INVALID_PARAM);
1025  }
1026 
1027  if (iteration_type != CPG_ITERATION_NAME_ONLY && iteration_type != CPG_ITERATION_ONE_GROUP &&
1028  iteration_type != CPG_ITERATION_ALL) {
1029 
1030  return (CS_ERR_INVALID_PARAM);
1031  }
1032 
1033  error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
1034  if (error != CS_OK) {
1035  return (error);
1036  }
1037 
1038  error = hdb_error_to_cs (hdb_handle_create (&cpg_iteration_handle_t_db,
1039  sizeof (struct cpg_iteration_instance_t), cpg_iteration_handle));
1040  if (error != CS_OK) {
1041  goto error_put_cpg_db;
1042  }
1043 
1044  error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, *cpg_iteration_handle,
1045  (void *)&cpg_iteration_instance));
1046  if (error != CS_OK) {
1047  goto error_destroy;
1048  }
1049 
1050  cpg_iteration_instance->conn = cpg_inst->c;
1051 
1052  list_init (&cpg_iteration_instance->list);
1053 
1054  req_lib_cpg_iterationinitialize.header.size = sizeof (struct req_lib_cpg_iterationinitialize);
1055  req_lib_cpg_iterationinitialize.header.id = MESSAGE_REQ_CPG_ITERATIONINITIALIZE;
1056  req_lib_cpg_iterationinitialize.iteration_type = iteration_type;
1057  if (group) {
1058  marshall_to_mar_cpg_name_t (&req_lib_cpg_iterationinitialize.group_name, group);
1059  }
1060 
1061  iov.iov_base = (void *)&req_lib_cpg_iterationinitialize;
1062  iov.iov_len = sizeof (struct req_lib_cpg_iterationinitialize);
1063 
1064  error = coroipcc_msg_send_reply_receive (cpg_inst->c,
1065  &iov,
1066  1,
1067  &res_lib_cpg_iterationinitialize,
1068  sizeof (struct res_lib_cpg_iterationinitialize));
1069 
1070  if (error != CS_OK) {
1071  goto error_put_destroy;
1072  }
1073 
1074  cpg_iteration_instance->executive_iteration_handle =
1075  res_lib_cpg_iterationinitialize.iteration_handle;
1076  cpg_iteration_instance->cpg_iteration_handle = *cpg_iteration_handle;
1077 
1078  list_add (&cpg_iteration_instance->list, &cpg_inst->iteration_list_head);
1079 
1080  hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
1081  hdb_handle_put (&cpg_handle_t_db, handle);
1082 
1083  return (res_lib_cpg_iterationinitialize.header.error);
1084 
1085 error_put_destroy:
1086  hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
1087 error_destroy:
1088  hdb_handle_destroy (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
1089 error_put_cpg_db:
1090  hdb_handle_put (&cpg_handle_t_db, handle);
1091 
1092  return (error);
1093 }
1094 
1096  cpg_iteration_handle_t handle,
1097  struct cpg_iteration_description_t *description)
1098 {
1099  cs_error_t error;
1100  struct cpg_iteration_instance_t *cpg_iteration_instance;
1101  struct req_lib_cpg_iterationnext req_lib_cpg_iterationnext;
1102  struct res_lib_cpg_iterationnext res_lib_cpg_iterationnext;
1103 
1104  if (description == NULL) {
1105  return CS_ERR_INVALID_PARAM;
1106  }
1107 
1108  error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, handle,
1109  (void *)&cpg_iteration_instance));
1110  if (error != CS_OK) {
1111  goto error_exit;
1112  }
1113 
1114  req_lib_cpg_iterationnext.header.size = sizeof (struct req_lib_cpg_iterationnext);
1115  req_lib_cpg_iterationnext.header.id = MESSAGE_REQ_CPG_ITERATIONNEXT;
1116  req_lib_cpg_iterationnext.iteration_handle = cpg_iteration_instance->executive_iteration_handle;
1117 
1118  error = qb_to_cs_error (qb_ipcc_send (cpg_iteration_instance->conn,
1119  &req_lib_cpg_iterationnext,
1120  req_lib_cpg_iterationnext.header.size));
1121  if (error != CS_OK) {
1122  goto error_put;
1123  }
1124 
1125  error = qb_to_cs_error (qb_ipcc_recv (cpg_iteration_instance->conn,
1126  &res_lib_cpg_iterationnext,
1127  sizeof(struct res_lib_cpg_iterationnext), -1));
1128  if (error != CS_OK) {
1129  goto error_put;
1130  }
1131 
1132  marshall_from_mar_cpg_iteration_description_t(
1133  description,
1134  &res_lib_cpg_iterationnext.description);
1135 
1136  error = res_lib_cpg_iterationnext.header.error;
1137 
1138 error_put:
1139  hdb_handle_put (&cpg_iteration_handle_t_db, handle);
1140 
1141 error_exit:
1142  return (error);
1143 }
1144 
1146  cpg_iteration_handle_t handle)
1147 {
1148  cs_error_t error;
1149  struct iovec iov;
1150  struct cpg_iteration_instance_t *cpg_iteration_instance;
1151  struct req_lib_cpg_iterationfinalize req_lib_cpg_iterationfinalize;
1152  struct res_lib_cpg_iterationfinalize res_lib_cpg_iterationfinalize;
1153 
1154  error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, handle,
1155  (void *)&cpg_iteration_instance));
1156  if (error != CS_OK) {
1157  goto error_exit;
1158  }
1159 
1160  req_lib_cpg_iterationfinalize.header.size = sizeof (struct req_lib_cpg_iterationfinalize);
1161  req_lib_cpg_iterationfinalize.header.id = MESSAGE_REQ_CPG_ITERATIONFINALIZE;
1162  req_lib_cpg_iterationfinalize.iteration_handle = cpg_iteration_instance->executive_iteration_handle;
1163 
1164  iov.iov_base = (void *)&req_lib_cpg_iterationfinalize;
1165  iov.iov_len = sizeof (struct req_lib_cpg_iterationfinalize);
1166 
1167  error = coroipcc_msg_send_reply_receive (cpg_iteration_instance->conn,
1168  &iov,
1169  1,
1170  &res_lib_cpg_iterationfinalize,
1171  sizeof (struct req_lib_cpg_iterationfinalize));
1172 
1173  if (error != CS_OK) {
1174  goto error_put;
1175  }
1176 
1177  cpg_iteration_instance_finalize (cpg_iteration_instance);
1178  hdb_handle_put (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle);
1179 
1180  return (res_lib_cpg_iterationfinalize.header.error);
1181 
1182 error_put:
1183  hdb_handle_put (&cpg_iteration_handle_t_db, handle);
1184 error_exit:
1185  return (error);
1186 }
1187 
cs_error_t cpg_iteration_next(cpg_iteration_handle_t handle, struct cpg_iteration_description_t *description)
Definition: lib/cpg.c:1095
cs_error_t cpg_flow_control_state_get(cpg_handle_t handle, cpg_flow_control_state_t *flow_control_state)
Definition: lib/cpg.c:716
mar_cpg_address_t member_list[]
Definition: ipc_cpg.h:248
#define CPG_MAX_NAME_LENGTH
Definition: cpg.h:91
cpg_deliver_fn_t cpg_deliver_fn
Definition: cpg.h:148
cs_error_t hdb_error_to_cs(int res)
cpg_flow_control_state_t
Definition: cpg.h:61
#define CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF
Definition: cpg.h:144
cs_error_t cpg_context_set(cpg_handle_t handle, void *context)
Set contexts for a CPG handle.
Definition: lib/cpg.c:313
cpg_confchg_fn_t cpg_confchg_fn
Definition: cpg.h:137
Definition: cpg.h:92
struct list_head * next
Definition: list.h:47
cs_error_t cpg_local_get(cpg_handle_t handle, unsigned int *local_nodeid)
Definition: lib/cpg.c:678
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:615
struct list_head list
Definition: lib/cpg.c:95
cs_error_t cpg_iteration_finalize(cpg_iteration_handle_t handle)
Definition: lib/cpg.c:1145
cpg_iteration_handle_t cpg_iteration_handle
Definition: lib/cpg.c:92
#define LOCALSTATEDIR
Definition: config.h:346
struct message_header header
Definition: totemsrp.c:60
int guarantee
Definition: totemsrp.c:66
unsigned char addr[TOTEMIP_ADDRLEN]
Definition: coroapi.h:67
#define CPG_MEMBERS_MAX
Definition: cpg.h:97
cpg_guarantee_t
Definition: cpg.h:54
cpg_confchg_fn_t cpg_confchg_fn
Definition: cpg.h:149
qb_ipcc_connection_t * c
Definition: lib/cpg.c:78
Definition: list.h:46
hdb_handle_t executive_iteration_handle
Definition: lib/cpg.c:94
cs_error_t cpg_fd_get(cpg_handle_t handle, int *fd)
Get a file descriptor on which to poll.
Definition: lib/cpg.c:275
uint64_t server_address
Definition: ipc_cpg.h:319
cpg_model_v1_data_t model_v1_data
Definition: lib/cpg.c:83
#define IPC_DISPATCH_SIZE
Definition: lib/util.h:51
cs_error_t cpg_zcb_alloc(cpg_handle_t handle, size_t size, void **buffer)
Definition: lib/cpg.c:814
cpg_totem_confchg_fn_t cpg_totem_confchg_fn
Definition: cpg.h:150
unsigned int flags
Definition: cpg.h:151
cs_error_t cpg_zcb_mcast_joined(cpg_handle_t handle, cpg_guarantee_t guarantee, void *msg, size_t msg_len)
Definition: lib/cpg.c:906
uint64_t cpg_handle_t
Definition: cpg.h:50
struct list_head iteration_list_head
Definition: lib/cpg.c:85
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:960
Linked list API.
#define IPC_REQUEST_SIZE
Definition: lib/util.h:49
cs_error_t
Definition: corotypes.h:78
cs_error_t cpg_dispatch(cpg_handle_t handle, cs_dispatch_flags_t dispatch_types)
Dispatch messages and configuration changes.
Definition: lib/cpg.c:332
mar_cpg_address_t member_list[PROCESSOR_COUNT_MAX]
Definition: ipc_cpg.h:239
void * context
Definition: lib/cpg.c:80
cs_dispatch_flags_t
Definition: corotypes.h:67
cs_error_t cpg_join(cpg_handle_t handle, const struct cpg_name *group)
Join one or more groups.
Definition: lib/cpg.c:516
#define CPG_ZC_PATH_LEN
Definition: ipc_cpg.h:43
cpg_model_data_t model_data
Definition: lib/cpg.c:82
cpg_model_t model
Definition: cpg.h:141
cpg_iteration_type_t
Definition: cpg.h:75
flow control is disabled - new messages may be sent
Definition: cpg.h:62
qb_handle_t hdb_handle_t
Definition: hdb.h:52
qb_ipcc_connection_t * conn
Definition: lib/cpg.c:93
cs_error_t cpg_finalize(cpg_handle_t handle)
Close the cpg handle.
Definition: lib/cpg.c:230
cs_error_t cpg_leave(cpg_handle_t handle, const struct cpg_name *group)
Leave one or more groups.
Definition: lib/cpg.c:570
#define list_entry(ptr, type, member)
Definition: list.h:84
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:170
cs_error_t cpg_context_get(cpg_handle_t handle, void **context)
Get contexts for a CPG handle.
Definition: lib/cpg.c:294
uint64_t cpg_iteration_handle_t
Definition: cpg.h:52
uint32_t length
Definition: cpg.h:93
cs_error_t cpg_initialize(cpg_handle_t *handle, cpg_callbacks_t *callbacks)
Create a new cpg connection.
Definition: lib/cpg.c:154
int finalize
Definition: lib/cpg.c:79
cpg_model_t
Definition: cpg.h:81
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)
Iteration.
Definition: lib/cpg.c:1002
#define CS_IPC_TIMEOUT_MS
Definition: corotypes.h:111
cs_error_t qb_to_cs_error(int result)
#define CPG_MEMORY_MAP_UMASK
Definition: lib/cpg.c:75
cpg_deliver_fn_t cpg_deliver_fn
Definition: cpg.h:136
cs_error_t cpg_zcb_free(cpg_handle_t handle, void *buffer)
Definition: lib/cpg.c:868
Message from another node.
Definition: ipc_cpg.h:217
DECLARE_HDB_DATABASE(cpg_handle_t_db, cpg_inst_free)