corosync  3.1.2
exec/cmap.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2017 Red Hat, Inc.
3  *
4  * All rights reserved.
5  *
6  * Author: Jan Friesse (jfriesse@redhat.com)
7  *
8  * This software licensed under BSD license, the text of which follows:
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * - Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  * - Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * - Neither the name of the Red Hat, Inc. nor the names of its
19  * contributors may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <config.h>
36 
37 #include <sys/types.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <stdlib.h>
41 #include <errno.h>
42 #include <poll.h>
43 #include <assert.h>
44 
45 #include <qb/qbloop.h>
46 #include <qb/qblist.h>
47 #include <qb/qbipcs.h>
48 #include <qb/qbipc_common.h>
49 
50 #include <corosync/corotypes.h>
51 #include <corosync/corodefs.h>
52 #include <corosync/mar_gen.h>
53 #include <corosync/ipc_cmap.h>
54 #include <corosync/logsys.h>
55 #include <corosync/coroapi.h>
56 #include <corosync/icmap.h>
57 
58 #include "service.h"
59 #include "ipcs_stats.h"
60 #include "stats.h"
61 
63 
64 #define MAX_REQ_EXEC_CMAP_MCAST_ITEMS 32
65 #define ICMAP_VALUETYPE_NOT_EXIST 0
66 
67 struct cmap_map {
68  cs_error_t (*map_get)(const char *key_name,
69  void *value,
70  size_t *value_len,
72 
73  cs_error_t (*map_set)(const char *key_name,
74  const void *value,
75  size_t value_len,
77 
78  cs_error_t (*map_adjust_int)(const char *key_name, int32_t step);
79 
80  cs_error_t (*map_delete)(const char *key_name);
81 
82  int (*map_is_key_ro)(const char *key_name);
83 
84  icmap_iter_t (*map_iter_init)(const char *prefix);
85  const char * (*map_iter_next)(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type);
87 
88  cs_error_t (*map_track_add)(const char *key_name,
89  int32_t track_type,
90  icmap_notify_fn_t notify_fn,
91  void *user_data,
93 
95  void * (*map_track_get_user_data)(icmap_track_t icmap_track);
96 };
97 
98 struct cmap_map icmap_map = {
99  .map_get = icmap_get,
100  .map_set = icmap_set,
101  .map_adjust_int = icmap_adjust_int,
102  .map_delete = icmap_delete,
103  .map_is_key_ro = icmap_is_key_ro,
104  .map_iter_init = icmap_iter_init,
105  .map_iter_next = icmap_iter_next,
106  .map_iter_finalize = icmap_iter_finalize,
107  .map_track_add = icmap_track_add,
108  .map_track_delete = icmap_track_delete,
109  .map_track_get_user_data = icmap_track_get_user_data,
110 };
111 
112 struct cmap_map stats_map = {
114  .map_set = stats_map_set,
115  .map_adjust_int = stats_map_adjust_int,
116  .map_delete = stats_map_delete,
117  .map_is_key_ro = stats_map_is_key_ro,
118  .map_iter_init = stats_map_iter_init,
119  .map_iter_next = stats_map_iter_next,
120  .map_iter_finalize = stats_map_iter_finalize,
121  .map_track_add = stats_map_track_add,
122  .map_track_delete = stats_map_track_delete,
123  .map_track_get_user_data = stats_map_track_get_user_data,
124 };
125 
129  struct cmap_map map_fns;
130 };
131 
132 typedef uint64_t cmap_iter_handle_t;
133 typedef uint64_t cmap_track_handle_t;
134 
136  void *conn;
139 };
140 
143 };
144 
148 };
149 
150 static struct corosync_api_v1 *api;
151 
152 static char *cmap_exec_init_fn (struct corosync_api_v1 *corosync_api);
153 static int cmap_exec_exit_fn(void);
154 
155 static int cmap_lib_init_fn (void *conn);
156 static int cmap_lib_exit_fn (void *conn);
157 
158 static void message_handler_req_lib_cmap_set(void *conn, const void *message);
159 static void message_handler_req_lib_cmap_delete(void *conn, const void *message);
160 static void message_handler_req_lib_cmap_get(void *conn, const void *message);
161 static void message_handler_req_lib_cmap_adjust_int(void *conn, const void *message);
162 static void message_handler_req_lib_cmap_iter_init(void *conn, const void *message);
163 static void message_handler_req_lib_cmap_iter_next(void *conn, const void *message);
164 static void message_handler_req_lib_cmap_iter_finalize(void *conn, const void *message);
165 static void message_handler_req_lib_cmap_track_add(void *conn, const void *message);
166 static void message_handler_req_lib_cmap_track_delete(void *conn, const void *message);
167 static void message_handler_req_lib_cmap_set_current_map(void *conn, const void *message);
168 
169 static void cmap_notify_fn(int32_t event,
170  const char *key_name,
171  struct icmap_notify_value new_val,
172  struct icmap_notify_value old_val,
173  void *user_data);
174 
175 static void message_handler_req_exec_cmap_mcast(
176  const void *message,
177  unsigned int nodeid);
178 
179 static void exec_cmap_mcast_endian_convert(void *message);
180 
181 /*
182  * Reson is subtype of message. argc is number of items in argv array. Argv is array
183  * of strings (key names) which will be send to wire. There can be maximum
184  * MAX_REQ_EXEC_CMAP_MCAST_ITEMS items (for more items, CS_ERR_TOO_MANY_GROUPS
185  * error is returned). If key is not found, item has type ICMAP_VALUETYPE_NOT_EXIST
186  * and length zero.
187  */
188 static cs_error_t cmap_mcast_send(enum cmap_mcast_reason reason, int argc, char *argv[]);
189 
190 static void cmap_sync_init (
191  const unsigned int *trans_list,
192  size_t trans_list_entries,
193  const unsigned int *member_list,
194  size_t member_list_entries,
195  const struct memb_ring_id *ring_id);
196 
197 static int cmap_sync_process (void);
198 static void cmap_sync_activate (void);
199 static void cmap_sync_abort (void);
200 
201 static void cmap_config_version_track_cb(
202  int32_t event,
203  const char *key_name,
204  struct icmap_notify_value new_value,
205  struct icmap_notify_value old_value,
206  void *user_data);
207 
208 /*
209  * Library Handler Definition
210  */
211 static struct corosync_lib_handler cmap_lib_engine[] =
212 {
213  { /* 0 */
214  .lib_handler_fn = message_handler_req_lib_cmap_set,
215  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
216  },
217  { /* 1 */
218  .lib_handler_fn = message_handler_req_lib_cmap_delete,
219  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
220  },
221  { /* 2 */
222  .lib_handler_fn = message_handler_req_lib_cmap_get,
223  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
224  },
225  { /* 3 */
226  .lib_handler_fn = message_handler_req_lib_cmap_adjust_int,
227  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
228  },
229  { /* 4 */
230  .lib_handler_fn = message_handler_req_lib_cmap_iter_init,
231  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
232  },
233  { /* 5 */
234  .lib_handler_fn = message_handler_req_lib_cmap_iter_next,
235  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
236  },
237  { /* 6 */
238  .lib_handler_fn = message_handler_req_lib_cmap_iter_finalize,
239  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
240  },
241  { /* 7 */
242  .lib_handler_fn = message_handler_req_lib_cmap_track_add,
243  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
244  },
245  { /* 8 */
246  .lib_handler_fn = message_handler_req_lib_cmap_track_delete,
247  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
248  },
249  { /* 9 */
250  .lib_handler_fn = message_handler_req_lib_cmap_set_current_map,
251  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
252  },
253 };
254 
255 static struct corosync_exec_handler cmap_exec_engine[] =
256 {
257  { /* 0 - MESSAGE_REQ_EXEC_CMAP_MCAST */
258  .exec_handler_fn = message_handler_req_exec_cmap_mcast,
259  .exec_endian_convert_fn = exec_cmap_mcast_endian_convert
260  },
261 };
262 
264  .name = "corosync configuration map access",
265  .id = CMAP_SERVICE,
266  .priority = 1,
267  .private_data_size = sizeof(struct cmap_conn_info),
268  .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
269  .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
270  .lib_init_fn = cmap_lib_init_fn,
271  .lib_exit_fn = cmap_lib_exit_fn,
272  .lib_engine = cmap_lib_engine,
273  .lib_engine_count = sizeof (cmap_lib_engine) / sizeof (struct corosync_lib_handler),
274  .exec_init_fn = cmap_exec_init_fn,
275  .exec_exit_fn = cmap_exec_exit_fn,
276  .exec_engine = cmap_exec_engine,
277  .exec_engine_count = sizeof (cmap_exec_engine) / sizeof (struct corosync_exec_handler),
278  .sync_init = cmap_sync_init,
279  .sync_process = cmap_sync_process,
280  .sync_activate = cmap_sync_activate,
281  .sync_abort = cmap_sync_abort
282 };
283 
285 {
286  return (&cmap_service_engine);
287 }
288 
290  mar_name_t key_name __attribute__((aligned(8)));
291  mar_uint8_t value_type __attribute__((aligned(8)));
292  mar_size_t value_len __attribute__((aligned(8)));
293  uint8_t value[] __attribute__((aligned(8)));
294 };
295 
297  struct qb_ipc_request_header header __attribute__((aligned(8)));
298  mar_uint8_t reason __attribute__((aligned(8)));
299  mar_uint8_t no_items __attribute__((aligned(8)));
300  mar_uint8_t reserved1 __attribute__((aligned(8)));
301  mar_uint8_t reserver2 __attribute__((aligned(8)));
302  /*
303  * Following are array of req_exec_cmap_mcast_item alligned to 8 bytes
304  */
305 };
306 
307 static size_t cmap_sync_trans_list_entries = 0;
308 static size_t cmap_sync_member_list_entries = 0;
309 static uint64_t cmap_highest_config_version_received = 0;
310 static uint64_t cmap_my_config_version = 0;
311 static int cmap_first_sync = 1;
312 static icmap_track_t cmap_config_version_track;
313 
314 static void cmap_config_version_track_cb(
315  int32_t event,
316  const char *key_name,
317  struct icmap_notify_value new_value,
318  struct icmap_notify_value old_value,
319  void *user_data)
320 {
321  const char *key = "totem.config_version";
322  cs_error_t ret;
323 
324  ENTER();
325 
326  if (icmap_get_uint64("totem.config_version", &cmap_my_config_version) != CS_OK) {
327  cmap_my_config_version = 0;
328  }
329 
330 
331  ret = cmap_mcast_send(CMAP_MCAST_REASON_NEW_CONFIG_VERSION, 1, (char **)&key);
332  if (ret != CS_OK) {
333  log_printf(LOGSYS_LEVEL_ERROR, "Can't inform other nodes about new config version");
334  }
335 
336  LEAVE();
337 }
338 
339 static int cmap_exec_exit_fn(void)
340 {
341 
342  if (icmap_track_delete(cmap_config_version_track) != CS_OK) {
343  log_printf(LOGSYS_LEVEL_ERROR, "Can't delete config_version icmap tracker");
344  }
345 
346  return 0;
347 }
348 
349 static char *cmap_exec_init_fn (
350  struct corosync_api_v1 *corosync_api)
351 {
352  cs_error_t ret;
353 
354  api = corosync_api;
355 
356  ret = icmap_track_add("totem.config_version",
358  cmap_config_version_track_cb,
359  NULL,
360  &cmap_config_version_track);
361 
362  if (ret != CS_OK) {
363  return ((char *)"Can't add config_version icmap tracker");
364  }
365 
366  return (NULL);
367 }
368 
369 static int cmap_lib_init_fn (void *conn)
370 {
371  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
372 
373  log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p", conn);
374 
375  api->ipc_refcnt_inc(conn);
376 
377  memset(conn_info, 0, sizeof(*conn_info));
378  conn_info->map_fns = icmap_map;
379  hdb_create(&conn_info->iter_db);
380  hdb_create(&conn_info->track_db);
381 
382  return (0);
383 }
384 
385 static int cmap_lib_exit_fn (void *conn)
386 {
387  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
388  hdb_handle_t iter_handle = 0;
389  icmap_iter_t *iter;
390  hdb_handle_t track_handle = 0;
391  icmap_track_t *track;
392 
393  log_printf(LOGSYS_LEVEL_DEBUG, "exit_fn for conn=%p", conn);
394 
395  hdb_iterator_reset(&conn_info->iter_db);
396  while (hdb_iterator_next(&conn_info->iter_db,
397  (void*)&iter, &iter_handle) == 0) {
398 
399  conn_info->map_fns.map_iter_finalize(*iter);
400 
401  (void)hdb_handle_put (&conn_info->iter_db, iter_handle);
402  }
403 
404  hdb_destroy(&conn_info->iter_db);
405 
406  hdb_iterator_reset(&conn_info->track_db);
407  while (hdb_iterator_next(&conn_info->track_db,
408  (void*)&track, &track_handle) == 0) {
409 
410  free(conn_info->map_fns.map_track_get_user_data(*track));
411 
412  conn_info->map_fns.map_track_delete(*track);
413 
414  (void)hdb_handle_put (&conn_info->track_db, track_handle);
415  }
416  hdb_destroy(&conn_info->track_db);
417 
418  api->ipc_refcnt_dec(conn);
419 
420  return (0);
421 }
422 
423 static void cmap_sync_init (
424  const unsigned int *trans_list,
425  size_t trans_list_entries,
426  const unsigned int *member_list,
427  size_t member_list_entries,
428  const struct memb_ring_id *ring_id)
429 {
430 
431  cmap_sync_trans_list_entries = trans_list_entries;
432  cmap_sync_member_list_entries = member_list_entries;
433 
434  if (icmap_get_uint64("totem.config_version", &cmap_my_config_version) != CS_OK) {
435  cmap_my_config_version = 0;
436  }
437 
438  cmap_highest_config_version_received = cmap_my_config_version;
439 }
440 
441 static int cmap_sync_process (void)
442 {
443  const char *key = "totem.config_version";
444  cs_error_t ret;
445 
446  ret = cmap_mcast_send(CMAP_MCAST_REASON_SYNC, 1, (char **)&key);
447 
448  return (ret == CS_OK ? 0 : -1);
449 }
450 
451 static void cmap_sync_activate (void)
452 {
453 
454  if (cmap_sync_trans_list_entries == 0) {
455  log_printf(LOGSYS_LEVEL_DEBUG, "Single node sync -> no action");
456 
457  return ;
458  }
459 
460  if (cmap_first_sync == 1) {
461  cmap_first_sync = 0;
462  } else {
463  log_printf(LOGSYS_LEVEL_DEBUG, "Not first sync -> no action");
464 
465  return ;
466  }
467 
468  if (cmap_my_config_version == 0) {
469  log_printf(LOGSYS_LEVEL_DEBUG, "My config version is 0 -> no action");
470 
471  return ;
472  }
473 
474  if (cmap_highest_config_version_received != cmap_my_config_version) {
476  "Received config version (%"PRIu64") is different than my config version (%"PRIu64")! Exiting",
477  cmap_highest_config_version_received, cmap_my_config_version);
478  api->shutdown_request();
479  return ;
480  }
481 }
482 
483 static void cmap_sync_abort (void)
484 {
485 
486 
487 }
488 
489 static void message_handler_req_lib_cmap_set(void *conn, const void *message)
490 {
491  const struct req_lib_cmap_set *req_lib_cmap_set = message;
492  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
494  cs_error_t ret;
495 
496  if (conn_info->map_fns.map_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
497  ret = CS_ERR_ACCESS;
498  } else {
499  ret = conn_info->map_fns.map_set((char *)req_lib_cmap_set->key_name.value, &req_lib_cmap_set->value,
500  req_lib_cmap_set->value_len, req_lib_cmap_set->type);
501  }
502 
503  memset(&res_lib_cmap_set, 0, sizeof(res_lib_cmap_set));
504  res_lib_cmap_set.header.size = sizeof(res_lib_cmap_set);
506  res_lib_cmap_set.header.error = ret;
507 
509 }
510 
511 static void message_handler_req_lib_cmap_delete(void *conn, const void *message)
512 {
513  const struct req_lib_cmap_set *req_lib_cmap_set = message;
514  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
516  cs_error_t ret;
517 
518  if (conn_info->map_fns.map_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
519  ret = CS_ERR_ACCESS;
520  } else {
521  ret = conn_info->map_fns.map_delete((char *)req_lib_cmap_set->key_name.value);
522  }
523 
524  memset(&res_lib_cmap_delete, 0, sizeof(res_lib_cmap_delete));
525  res_lib_cmap_delete.header.size = sizeof(res_lib_cmap_delete);
527  res_lib_cmap_delete.header.error = ret;
528 
530 }
531 
532 static void message_handler_req_lib_cmap_get(void *conn, const void *message)
533 {
534  const struct req_lib_cmap_get *req_lib_cmap_get = message;
535  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
537  struct res_lib_cmap_get error_res_lib_cmap_get;
538  cs_error_t ret;
539  size_t value_len;
540  size_t res_lib_cmap_get_size;
542  void *value;
543 
544  value_len = req_lib_cmap_get->value_len;
545 
546  res_lib_cmap_get_size = sizeof(*res_lib_cmap_get) + value_len;
547  res_lib_cmap_get = malloc(res_lib_cmap_get_size);
548  if (res_lib_cmap_get == NULL) {
549  ret = CS_ERR_NO_MEMORY;
550  goto error_exit;
551  }
552 
553  memset(res_lib_cmap_get, 0, res_lib_cmap_get_size);
554 
555  if (value_len > 0) {
556  value = res_lib_cmap_get->value;
557  } else {
558  value = NULL;
559  }
560 
561  ret = conn_info->map_fns.map_get((char *)req_lib_cmap_get->key_name.value,
562  value,
563  &value_len,
564  &type);
565 
566  if (ret != CS_OK) {
567  free(res_lib_cmap_get);
568  goto error_exit;
569  }
570 
571  res_lib_cmap_get->header.size = res_lib_cmap_get_size;
573  res_lib_cmap_get->header.error = ret;
574  res_lib_cmap_get->type = type;
575  res_lib_cmap_get->value_len = value_len;
576 
577  api->ipc_response_send(conn, res_lib_cmap_get, res_lib_cmap_get_size);
578  free(res_lib_cmap_get);
579 
580  return ;
581 
582 error_exit:
583  memset(&error_res_lib_cmap_get, 0, sizeof(error_res_lib_cmap_get));
584  error_res_lib_cmap_get.header.size = sizeof(error_res_lib_cmap_get);
585  error_res_lib_cmap_get.header.id = MESSAGE_RES_CMAP_GET;
586  error_res_lib_cmap_get.header.error = ret;
587 
588  api->ipc_response_send(conn, &error_res_lib_cmap_get, sizeof(error_res_lib_cmap_get));
589 }
590 
591 static void message_handler_req_lib_cmap_adjust_int(void *conn, const void *message)
592 {
593  const struct req_lib_cmap_adjust_int *req_lib_cmap_adjust_int = message;
594  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
596  cs_error_t ret;
597 
598  if (conn_info->map_fns.map_is_key_ro((char *)req_lib_cmap_adjust_int->key_name.value)) {
599  ret = CS_ERR_ACCESS;
600  } else {
601  ret = conn_info->map_fns.map_adjust_int((char *)req_lib_cmap_adjust_int->key_name.value,
603 
604  }
605 
607  res_lib_cmap_adjust_int.header.size = sizeof(res_lib_cmap_adjust_int);
609  res_lib_cmap_adjust_int.header.error = ret;
610 
612 }
613 
614 static void message_handler_req_lib_cmap_iter_init(void *conn, const void *message)
615 {
616  const struct req_lib_cmap_iter_init *req_lib_cmap_iter_init = message;
618  cs_error_t ret;
619  icmap_iter_t iter;
620  icmap_iter_t *hdb_iter;
621  cmap_iter_handle_t handle = 0ULL;
622  const char *prefix;
623  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
624 
625  if (req_lib_cmap_iter_init->prefix.length > 0) {
626  prefix = (char *)req_lib_cmap_iter_init->prefix.value;
627  } else {
628  prefix = NULL;
629  }
630 
631  iter = conn_info->map_fns.map_iter_init(prefix);
632  if (iter == NULL) {
633  ret = CS_ERR_NO_SECTIONS;
634  goto reply_send;
635  }
636 
637  ret = hdb_error_to_cs(hdb_handle_create(&conn_info->iter_db, sizeof(iter), &handle));
638  if (ret != CS_OK) {
639  goto reply_send;
640  }
641 
642  ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db, handle, (void *)&hdb_iter));
643  if (ret != CS_OK) {
644  goto reply_send;
645  }
646 
647  *hdb_iter = iter;
648 
649  (void)hdb_handle_put (&conn_info->iter_db, handle);
650 
651 reply_send:
652  memset(&res_lib_cmap_iter_init, 0, sizeof(res_lib_cmap_iter_init));
653  res_lib_cmap_iter_init.header.size = sizeof(res_lib_cmap_iter_init);
655  res_lib_cmap_iter_init.header.error = ret;
656  res_lib_cmap_iter_init.iter_handle = handle;
657 
659 }
660 
661 static void message_handler_req_lib_cmap_iter_next(void *conn, const void *message)
662 {
663  const struct req_lib_cmap_iter_next *req_lib_cmap_iter_next = message;
665  cs_error_t ret;
666  icmap_iter_t *iter;
667  size_t value_len = 0;
669  const char *res = NULL;
670  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
671 
672  ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
673  req_lib_cmap_iter_next->iter_handle, (void *)&iter));
674  if (ret != CS_OK) {
675  goto reply_send;
676  }
677 
678  res = conn_info->map_fns.map_iter_next(*iter, &value_len, &type);
679  if (res == NULL) {
680  ret = CS_ERR_NO_SECTIONS;
681  }
682 
683  (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_next->iter_handle);
684 
685 reply_send:
686  memset(&res_lib_cmap_iter_next, 0, sizeof(res_lib_cmap_iter_next));
687  res_lib_cmap_iter_next.header.size = sizeof(res_lib_cmap_iter_next);
689  res_lib_cmap_iter_next.header.error = ret;
690 
691  if (res != NULL) {
692  res_lib_cmap_iter_next.value_len = value_len;
694 
695  assert(strlen(res) <= sizeof(res_lib_cmap_iter_next.key_name.value));
696 
697  memcpy(res_lib_cmap_iter_next.key_name.value, res, strlen(res));
698  res_lib_cmap_iter_next.key_name.length = strlen(res);
699  }
700 
702 }
703 
704 static void message_handler_req_lib_cmap_iter_finalize(void *conn, const void *message)
705 {
708  cs_error_t ret;
709  icmap_iter_t *iter;
710  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
711 
712  ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
713  req_lib_cmap_iter_finalize->iter_handle, (void *)&iter));
714  if (ret != CS_OK) {
715  goto reply_send;
716  }
717 
718  conn_info->map_fns.map_iter_finalize(*iter);
719 
720  (void)hdb_handle_destroy(&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
721 
722  (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
723 
724 reply_send:
728  res_lib_cmap_iter_finalize.header.error = ret;
729 
731 }
732 
733 static void cmap_notify_fn(int32_t event,
734  const char *key_name,
735  struct icmap_notify_value new_val,
736  struct icmap_notify_value old_val,
737  void *user_data)
738 {
741  struct iovec iov[3];
742 
744 
745  res_lib_cmap_notify_callback.header.size = sizeof(res_lib_cmap_notify_callback) + new_val.len + old_val.len;
747  res_lib_cmap_notify_callback.header.error = CS_OK;
748 
749  res_lib_cmap_notify_callback.new_value_type = new_val.type;
750  res_lib_cmap_notify_callback.old_value_type = old_val.type;
751  res_lib_cmap_notify_callback.new_value_len = new_val.len;
752  res_lib_cmap_notify_callback.old_value_len = old_val.len;
753  res_lib_cmap_notify_callback.event = event;
754  res_lib_cmap_notify_callback.key_name.length = strlen(key_name);
756 
757  assert(strlen(key_name) <= sizeof(res_lib_cmap_notify_callback.key_name.value));
758 
759  memcpy(res_lib_cmap_notify_callback.key_name.value, key_name, strlen(key_name));
760 
761  iov[0].iov_base = (char *)&res_lib_cmap_notify_callback;
762  iov[0].iov_len = sizeof(res_lib_cmap_notify_callback);
763  iov[1].iov_base = (char *)new_val.data;
764  iov[1].iov_len = new_val.len;
765  iov[2].iov_base = (char *)old_val.data;
766  iov[2].iov_len = old_val.len;
767 
769 }
770 
771 static void message_handler_req_lib_cmap_track_add(void *conn, const void *message)
772 {
773  const struct req_lib_cmap_track_add *req_lib_cmap_track_add = message;
775  cs_error_t ret;
776  cmap_track_handle_t handle = 0;
777  icmap_track_t track = NULL;
778  icmap_track_t *hdb_track;
780  const char *key_name;
781 
782  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
783 
784  cmap_track_user_data = malloc(sizeof(*cmap_track_user_data));
785  if (cmap_track_user_data == NULL) {
786  ret = CS_ERR_NO_MEMORY;
787 
788  goto reply_send;
789  }
790  memset(cmap_track_user_data, 0, sizeof(*cmap_track_user_data));
791 
792  if (req_lib_cmap_track_add->key_name.length > 0) {
793  key_name = (char *)req_lib_cmap_track_add->key_name.value;
794  } else {
795  key_name = NULL;
796  }
797 
798  ret = conn_info->map_fns.map_track_add(key_name,
799  req_lib_cmap_track_add->track_type,
800  cmap_notify_fn,
802  &track);
803  if (ret != CS_OK) {
804  free(cmap_track_user_data);
805 
806  goto reply_send;
807  }
808 
809  ret = hdb_error_to_cs(hdb_handle_create(&conn_info->track_db, sizeof(track), &handle));
810  if (ret != CS_OK) {
811  free(cmap_track_user_data);
812 
813  goto reply_send;
814  }
815 
816  ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db, handle, (void *)&hdb_track));
817  if (ret != CS_OK) {
818  free(cmap_track_user_data);
819 
820  goto reply_send;
821  }
822 
823  *hdb_track = track;
824  cmap_track_user_data->conn = conn;
827 
828  (void)hdb_handle_put (&conn_info->track_db, handle);
829 
830 reply_send:
831  memset(&res_lib_cmap_track_add, 0, sizeof(res_lib_cmap_track_add));
832  res_lib_cmap_track_add.header.size = sizeof(res_lib_cmap_track_add);
834  res_lib_cmap_track_add.header.error = ret;
835  res_lib_cmap_track_add.track_handle = handle;
836 
838 }
839 
840 static void message_handler_req_lib_cmap_track_delete(void *conn, const void *message)
841 {
844  cs_error_t ret;
845  icmap_track_t *track;
846  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
847  uint64_t track_inst_handle = 0;
848 
849  ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db,
850  req_lib_cmap_track_delete->track_handle, (void *)&track));
851  if (ret != CS_OK) {
852  goto reply_send;
853  }
854 
855  track_inst_handle = ((struct cmap_track_user_data *)
857 
858  free(conn_info->map_fns.map_track_get_user_data(*track));
859 
860  ret = conn_info->map_fns.map_track_delete(*track);
861 
862  (void)hdb_handle_put (&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
863  (void)hdb_handle_destroy(&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
864 
865 reply_send:
869  res_lib_cmap_track_delete.header.error = ret;
870  res_lib_cmap_track_delete.track_inst_handle = track_inst_handle;
871 
873 }
874 
875 
876 static void message_handler_req_lib_cmap_set_current_map(void *conn, const void *message)
877 {
879  struct qb_ipc_response_header res;
880  cs_error_t ret = CS_OK;
881  struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
882  int handles_open = 0;
883  hdb_handle_t iter_handle = 0;
884  icmap_iter_t *iter;
885  hdb_handle_t track_handle = 0;
886  icmap_track_t *track;
887 
888  /* Cannot switch maps while there are tracks or iterators active */
889  hdb_iterator_reset(&conn_info->iter_db);
890  while (hdb_iterator_next(&conn_info->iter_db,
891  (void*)&iter, &iter_handle) == 0) {
892  handles_open++;
893  }
894 
895  hdb_iterator_reset(&conn_info->track_db);
896  while (hdb_iterator_next(&conn_info->track_db,
897  (void*)&track, &track_handle) == 0) {
898  handles_open++;
899  }
900 
901  if (handles_open) {
902  ret = CS_ERR_BUSY;
903  goto reply_send;
904  }
905 
906  switch (req_lib_cmap_set_current_map->map) {
907  case CMAP_SETMAP_DEFAULT:
908  conn_info->map_fns = icmap_map;
909  break;
910  case CMAP_SETMAP_STATS:
911  conn_info->map_fns = stats_map;
912  break;
913  default:
914  ret = CS_ERR_NOT_EXIST;
915  break;
916  }
917 
918 reply_send:
919  res.size = sizeof(res);
921  res.error = ret;
922 
923  api->ipc_response_send(conn, &res, sizeof(res));
924 }
925 
926 static cs_error_t cmap_mcast_send(enum cmap_mcast_reason reason, int argc, char *argv[])
927 {
928  int i;
929  size_t value_len;
930  icmap_value_types_t value_type;
931  cs_error_t err;
932  size_t item_len;
933  size_t msg_len = 0;
935  struct req_exec_cmap_mcast_item *item = NULL;
936  struct iovec req_exec_cmap_iovec[MAX_REQ_EXEC_CMAP_MCAST_ITEMS + 1];
937 
938  ENTER();
939 
940  if (argc > MAX_REQ_EXEC_CMAP_MCAST_ITEMS) {
941  return (CS_ERR_TOO_MANY_GROUPS);
942  }
943 
944  memset(req_exec_cmap_iovec, 0, sizeof(req_exec_cmap_iovec));
945 
946  for (i = 0; i < argc; i++) {
947  err = icmap_get(argv[i], NULL, &value_len, &value_type);
948  if (err != CS_OK && err != CS_ERR_NOT_EXIST) {
949  goto free_mem;
950  }
951  if (err == CS_ERR_NOT_EXIST) {
952  value_type = ICMAP_VALUETYPE_NOT_EXIST;
953  value_len = 0;
954  }
955 
956  item_len = MAR_ALIGN_UP(sizeof(*item) + value_len, 8);
957 
958  item = malloc(item_len);
959  if (item == NULL) {
960  goto free_mem;
961  }
962  memset(item, 0, item_len);
963 
964  item->value_type = value_type;
965  item->value_len = value_len;
966  item->key_name.length = strlen(argv[i]);
967 
968  assert(strlen(argv[i]) < sizeof(item->key_name.value));
969 
970  strcpy((char *)item->key_name.value, argv[i]);
971 
972  if (value_type != ICMAP_VALUETYPE_NOT_EXIST) {
973  err = icmap_get(argv[i], item->value, &value_len, &value_type);
974  if (err != CS_OK) {
975  goto free_mem;
976  }
977  }
978 
979  req_exec_cmap_iovec[i + 1].iov_base = item;
980  req_exec_cmap_iovec[i + 1].iov_len = item_len;
981  msg_len += item_len;
982 
983  qb_log(LOG_TRACE, "Item %u - type %u, len %zu", i, item->value_type, item->value_len);
984 
985  item = NULL;
986  }
987 
988  memset(&req_exec_cmap_mcast, 0, sizeof(req_exec_cmap_mcast));
989  req_exec_cmap_mcast.header.size = sizeof(req_exec_cmap_mcast) + msg_len;
990  req_exec_cmap_mcast.reason = reason;
991  req_exec_cmap_mcast.no_items = argc;
992  req_exec_cmap_iovec[0].iov_base = &req_exec_cmap_mcast;
993  req_exec_cmap_iovec[0].iov_len = sizeof(req_exec_cmap_mcast);
994 
995  qb_log(LOG_TRACE, "Sending %u items (%u iovec) for reason %u", argc, argc + 1, reason);
996  err = (api->totem_mcast(req_exec_cmap_iovec, argc + 1, TOTEM_AGREED) == 0 ? CS_OK : CS_ERR_MESSAGE_ERROR);
997 
998 free_mem:
999  for (i = 0; i < argc; i++) {
1000  free(req_exec_cmap_iovec[i + 1].iov_base);
1001  }
1002 
1003  free(item);
1004 
1005  LEAVE();
1006  return (err);
1007 }
1008 
1009 static struct req_exec_cmap_mcast_item *cmap_mcast_item_find(
1010  const void *message,
1011  char *key)
1012 {
1013  const struct req_exec_cmap_mcast *req_exec_cmap_mcast = message;
1014  int i;
1015  const char *p;
1016  struct req_exec_cmap_mcast_item *item;
1017  mar_uint16_t key_name_len;
1018 
1019  p = (const char *)message + sizeof(*req_exec_cmap_mcast);
1020 
1021  for (i = 0; i < req_exec_cmap_mcast->no_items; i++) {
1022  item = (struct req_exec_cmap_mcast_item *)p;
1023 
1024  key_name_len = item->key_name.length;
1025  if (strlen(key) == key_name_len && strcmp((char *)item->key_name.value, key) == 0) {
1026  return (item);
1027  }
1028 
1029  p += MAR_ALIGN_UP(sizeof(*item) + item->value_len, 8);
1030  }
1031 
1032  return (NULL);
1033 }
1034 
1035 static void message_handler_req_exec_cmap_mcast_reason_sync_nv(
1036  enum cmap_mcast_reason reason,
1037  const void *message,
1038  unsigned int nodeid)
1039 {
1040  char member_config_version[ICMAP_KEYNAME_MAXLEN];
1041  uint64_t config_version = 0;
1042  struct req_exec_cmap_mcast_item *item;
1043  mar_size_t value_len;
1044 
1045  ENTER();
1046 
1047  item = cmap_mcast_item_find(message, (char *)"totem.config_version");
1048  if (item != NULL) {
1049  value_len = item->value_len;
1050 
1051  if (item->value_type == ICMAP_VALUETYPE_NOT_EXIST) {
1052  config_version = 0;
1053  }
1054 
1055  if (item->value_type == ICMAP_VALUETYPE_UINT64) {
1056  memcpy(&config_version, item->value, value_len);
1057  }
1058  }
1059 
1060  qb_log(LOG_TRACE, "Received config version %"PRIu64" from node " CS_PRI_NODE_ID, config_version, nodeid);
1061 
1062  if (nodeid != api->totem_nodeid_get() &&
1063  config_version > cmap_highest_config_version_received) {
1064  cmap_highest_config_version_received = config_version;
1065  }
1066 
1067  snprintf(member_config_version, ICMAP_KEYNAME_MAXLEN,
1068  "runtime.members.%u.config_version", nodeid);
1069  icmap_set_uint64(member_config_version, config_version);
1070 
1071  LEAVE();
1072 }
1073 
1074 static void message_handler_req_exec_cmap_mcast(
1075  const void *message,
1076  unsigned int nodeid)
1077 {
1078  const struct req_exec_cmap_mcast *req_exec_cmap_mcast = message;
1079 
1080  ENTER();
1081 
1082  switch (req_exec_cmap_mcast->reason) {
1084  message_handler_req_exec_cmap_mcast_reason_sync_nv(req_exec_cmap_mcast->reason,
1085  message, nodeid);
1086 
1087  break;
1089  message_handler_req_exec_cmap_mcast_reason_sync_nv(req_exec_cmap_mcast->reason,
1090  message, nodeid);
1091 
1092  break;
1093  default:
1094  qb_log(LOG_TRACE, "Received mcast with unknown reason %u", req_exec_cmap_mcast->reason);
1095  };
1096 
1097  LEAVE();
1098 }
1099 
1100 static void exec_cmap_mcast_endian_convert(void *message)
1101 {
1102  struct req_exec_cmap_mcast *req_exec_cmap_mcast = message;
1103  const char *p;
1104  int i;
1105  struct req_exec_cmap_mcast_item *item;
1106  uint16_t u16;
1107  uint32_t u32;
1108  uint64_t u64;
1109  float flt;
1110  double dbl;
1111 
1112  swab_coroipc_request_header_t(&req_exec_cmap_mcast->header);
1113 
1114  p = (const char *)message + sizeof(*req_exec_cmap_mcast);
1115 
1116  for (i = 0; i < req_exec_cmap_mcast->no_items; i++) {
1117  item = (struct req_exec_cmap_mcast_item *)p;
1118 
1119  swab_mar_uint16_t(&item->key_name.length);
1120  swab_mar_size_t(&item->value_len);
1121 
1122  switch (item->value_type) {
1123  case ICMAP_VALUETYPE_INT16:
1125  memcpy(&u16, item->value, sizeof(u16));
1126  u16 = swab16(u16);
1127  memcpy(item->value, &u16, sizeof(u16));
1128  break;
1129  case ICMAP_VALUETYPE_INT32:
1131  memcpy(&u32, item->value, sizeof(u32));
1132  u32 = swab32(u32);
1133  memcpy(item->value, &u32, sizeof(u32));
1134  break;
1135  case ICMAP_VALUETYPE_INT64:
1137  memcpy(&u64, item->value, sizeof(u64));
1138  u64 = swab64(u64);
1139  memcpy(item->value, &u64, sizeof(u64));
1140  break;
1141  case ICMAP_VALUETYPE_FLOAT:
1142  memcpy(&flt, item->value, sizeof(flt));
1143  swabflt(&flt);
1144  memcpy(item->value, &flt, sizeof(flt));
1145  break;
1147  memcpy(&dbl, item->value, sizeof(dbl));
1148  swabdbl(&dbl);
1149  memcpy(item->value, &dbl, sizeof(dbl));
1150  break;
1151  }
1152 
1153  p += MAR_ALIGN_UP(sizeof(*item) + item->value_len, 8);
1154  }
1155 }
@ CS_LIB_ALLOW_INQUORATE
Definition: coroapi.h:164
unsigned int nodeid
Definition: coroapi.h:0
@ CS_LIB_FLOW_CONTROL_NOT_REQUIRED
Definition: coroapi.h:153
#define TOTEM_AGREED
Definition: coroapi.h:102
@ CMAP_SERVICE
Definition: corodefs.h:44
#define CS_PRI_NODE_ID
Definition: corotypes.h:59
cs_error_t
The cs_error_t enum.
Definition: corotypes.h:97
@ CS_ERR_NO_SECTIONS
Definition: corotypes.h:124
@ CS_ERR_MESSAGE_ERROR
Definition: corotypes.h:119
@ CS_ERR_ACCESS
Definition: corotypes.h:108
@ CS_ERR_NO_MEMORY
Definition: corotypes.h:105
@ CS_ERR_BUSY
Definition: corotypes.h:107
@ CS_ERR_TOO_MANY_GROUPS
Definition: corotypes.h:126
@ CS_OK
Definition: corotypes.h:98
@ CS_ERR_NOT_EXIST
Definition: corotypes.h:109
LOGSYS_DECLARE_SUBSYS("CMAP")
struct corosync_service_engine * cmap_get_service_engine_ver0(void)
Definition: exec/cmap.c:284
uint64_t cmap_iter_handle_t
Definition: exec/cmap.c:132
struct cmap_map stats_map
Definition: exec/cmap.c:112
#define ICMAP_VALUETYPE_NOT_EXIST
Definition: exec/cmap.c:65
#define MAX_REQ_EXEC_CMAP_MCAST_ITEMS
Definition: exec/cmap.c:64
cmap_message_req_types
Definition: exec/cmap.c:141
@ MESSAGE_REQ_EXEC_CMAP_MCAST
Definition: exec/cmap.c:142
uint64_t cmap_track_handle_t
Definition: exec/cmap.c:133
struct cmap_map icmap_map
Definition: exec/cmap.c:98
cmap_mcast_reason
Definition: exec/cmap.c:145
@ CMAP_MCAST_REASON_SYNC
Definition: exec/cmap.c:146
@ CMAP_MCAST_REASON_NEW_CONFIG_VERSION
Definition: exec/cmap.c:147
struct corosync_service_engine cmap_service_engine
Definition: exec/cmap.c:263
uint32_t value
uint64_t cmap_iter_handle_t
Definition: cmap.h:59
uint64_t cmap_track_handle_t
Definition: cmap.h:64
#define hdb_handle_database
Definition: hdb.h:60
qb_handle_t hdb_handle_t
Definition: hdb.h:52
#define ICMAP_TRACK_MODIFY
Definition: icmap.h:78
cs_error_t icmap_set(const char *key_name, const void *value, size_t value_len, icmap_value_types_t type)
Store value with value_len length and type as key_name name in global icmap.
Definition: icmap.c:487
cs_error_t icmap_adjust_int(const char *key_name, int32_t step)
icmap_adjust_int
Definition: icmap.c:979
cs_error_t icmap_delete(const char *key_name)
Delete key from map.
Definition: icmap.c:653
icmap_value_types_t
Possible types of value.
Definition: icmap.h:58
@ ICMAP_VALUETYPE_UINT64
Definition: icmap.h:66
@ ICMAP_VALUETYPE_INT16
Definition: icmap.h:61
@ ICMAP_VALUETYPE_UINT32
Definition: icmap.h:64
@ ICMAP_VALUETYPE_FLOAT
Definition: icmap.h:67
@ ICMAP_VALUETYPE_INT64
Definition: icmap.h:65
@ ICMAP_VALUETYPE_DOUBLE
Definition: icmap.h:68
@ ICMAP_VALUETYPE_UINT16
Definition: icmap.h:62
@ ICMAP_VALUETYPE_INT32
Definition: icmap.h:63
#define ICMAP_TRACK_DELETE
Definition: icmap.h:77
cs_error_t icmap_track_add(const char *key_name, int32_t track_type, icmap_notify_fn_t notify_fn, void *user_data, icmap_track_t *icmap_track)
Add tracking function for given key_name.
Definition: icmap.c:1159
icmap_iter_t icmap_iter_init(const char *prefix)
Initialize iterator with given prefix.
Definition: icmap.c:1089
void(* icmap_notify_fn_t)(int32_t event, const char *key_name, struct icmap_notify_value new_value, struct icmap_notify_value old_value, void *user_data)
Prototype for notify callback function.
Definition: icmap.h:103
const char * icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
Return next item in iterator iter.
Definition: icmap.c:1095
cs_error_t icmap_get(const char *key_name, void *value, size_t *value_len, icmap_value_types_t *type)
Retrieve value of key key_name and store it in user preallocated value pointer.
Definition: icmap.c:725
qb_map_iter_t * icmap_iter_t
Itterator type.
Definition: icmap.h:123
void icmap_iter_finalize(icmap_iter_t iter)
Finalize iterator.
Definition: icmap.c:1116
void * icmap_track_get_user_data(icmap_track_t icmap_track)
Return user data associated with given track.
Definition: icmap.c:1220
cs_error_t icmap_track_delete(icmap_track_t icmap_track)
Remove previously added track.
Definition: icmap.c:1204
cs_error_t icmap_set_uint64(const char *key_name, uint64_t value)
Definition: icmap.c:609
#define ICMAP_KEYNAME_MAXLEN
Maximum length of key in icmap.
Definition: icmap.h:48
#define ICMAP_TRACK_ADD
Definition: icmap.h:76
cs_error_t icmap_get_uint64(const char *key_name, uint64_t *u64)
Definition: icmap.c:904
int icmap_is_key_ro(const char *key_name)
Check in given key is read only.
Definition: icmap.c:1272
@ CMAP_SETMAP_STATS
Definition: ipc_cmap.h:77
@ CMAP_SETMAP_DEFAULT
Definition: ipc_cmap.h:76
@ MESSAGE_RES_CMAP_ITER_FINALIZE
Definition: ipc_cmap.h:68
@ MESSAGE_RES_CMAP_SET_CURRENT_MAP
Definition: ipc_cmap.h:72
@ MESSAGE_RES_CMAP_SET
Definition: ipc_cmap.h:62
@ MESSAGE_RES_CMAP_ITER_INIT
Definition: ipc_cmap.h:66
@ MESSAGE_RES_CMAP_ITER_NEXT
Definition: ipc_cmap.h:67
@ MESSAGE_RES_CMAP_GET
Definition: ipc_cmap.h:64
@ MESSAGE_RES_CMAP_DELETE
Definition: ipc_cmap.h:63
@ MESSAGE_RES_CMAP_NOTIFY_CALLBACK
Definition: ipc_cmap.h:71
@ MESSAGE_RES_CMAP_TRACK_ADD
Definition: ipc_cmap.h:69
@ MESSAGE_RES_CMAP_TRACK_DELETE
Definition: ipc_cmap.h:70
@ MESSAGE_RES_CMAP_ADJUST_INT
Definition: ipc_cmap.h:65
cs_error_t hdb_error_to_cs(int res)
#define LOGSYS_LEVEL_ERROR
Definition: logsys.h:72
#define LEAVE
Definition: logsys.h:325
#define log_printf(level, format, args...)
Definition: logsys.h:323
#define LOGSYS_LEVEL_DEBUG
Definition: logsys.h:76
#define ENTER
Definition: logsys.h:324
#define MAR_ALIGN_UP(addr, size)
Definition: mar_gen.h:44
mar_uint64_t mar_size_t
mar_size_t
Definition: mar_gen.h:286
uint8_t mar_uint8_t
Definition: mar_gen.h:51
uint16_t mar_uint16_t
Definition: mar_gen.h:52
void * user_data
Definition: sam.c:127
void * stats_map_track_get_user_data(icmap_track_t icmap_track)
Definition: stats.c:722
cs_error_t stats_map_delete(const char *key_name)
Definition: stats.c:520
cs_error_t stats_map_track_delete(icmap_track_t icmap_track)
Definition: stats.c:700
const char * stats_map_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
Definition: stats.c:541
icmap_iter_t stats_map_iter_init(const char *prefix)
Definition: stats.c:535
int stats_map_is_key_ro(const char *key_name)
Definition: stats.c:525
cs_error_t stats_map_set(const char *key_name, const void *value, size_t value_len, icmap_value_types_t type)
Definition: stats.c:480
void stats_map_iter_finalize(icmap_iter_t iter)
Definition: stats.c:555
cs_error_t stats_map_get(const char *key_name, void *value, size_t *value_len, icmap_value_types_t *type)
Definition: stats.c:325
cs_error_t stats_map_adjust_int(const char *key_name, int32_t step)
Definition: stats.c:515
cs_error_t stats_map_track_add(const char *key_name, int32_t track_type, icmap_notify_fn_t notify_fn, void *user_data, icmap_track_t *icmap_track)
Definition: stats.c:637
struct hdb_handle_database iter_db
Definition: exec/cmap.c:127
struct cmap_map map_fns
Definition: exec/cmap.c:129
struct hdb_handle_database track_db
Definition: exec/cmap.c:128
const char *(* map_iter_next)(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
Definition: exec/cmap.c:85
cs_error_t(* map_track_add)(const char *key_name, int32_t track_type, icmap_notify_fn_t notify_fn, void *user_data, icmap_track_t *icmap_track)
Definition: exec/cmap.c:88
cs_error_t(* map_track_delete)(icmap_track_t icmap_track)
Definition: exec/cmap.c:94
void(* map_iter_finalize)(icmap_iter_t iter)
Definition: exec/cmap.c:86
cs_error_t(* map_get)(const char *key_name, void *value, size_t *value_len, icmap_value_types_t *type)
Definition: exec/cmap.c:68
int(* map_is_key_ro)(const char *key_name)
Definition: exec/cmap.c:82
void *(* map_track_get_user_data)(icmap_track_t icmap_track)
Definition: exec/cmap.c:95
cs_error_t(* map_delete)(const char *key_name)
Definition: exec/cmap.c:80
cs_error_t(* map_set)(const char *key_name, const void *value, size_t value_len, icmap_value_types_t type)
Definition: exec/cmap.c:73
cs_error_t(* map_adjust_int)(const char *key_name, int32_t step)
Definition: exec/cmap.c:78
icmap_iter_t(* map_iter_init)(const char *prefix)
Definition: exec/cmap.c:84
cmap_track_handle_t track_handle
Definition: exec/cmap.c:137
uint64_t track_inst_handle
Definition: exec/cmap.c:138
The corosync_api_v1 struct.
Definition: coroapi.h:225
int(* totem_mcast)(const struct iovec *iovec, unsigned int iov_len, unsigned int guarantee)
Definition: coroapi.h:279
unsigned int(* totem_nodeid_get)(void)
Definition: coroapi.h:275
void(* ipc_refcnt_dec)(void *conn)
Definition: coroapi.h:270
void(* shutdown_request)(void)
Definition: coroapi.h:429
void(* ipc_refcnt_inc)(void *conn)
Definition: coroapi.h:268
int(* ipc_response_send)(void *conn, const void *msg, size_t mlen)
Definition: coroapi.h:258
int(* ipc_dispatch_iov_send)(void *conn, const struct iovec *iov, unsigned int iov_len)
Definition: coroapi.h:265
void *(* ipc_private_data_get)(void *conn)
Definition: coroapi.h:256
The corosync_exec_handler struct.
Definition: coroapi.h:475
void(* exec_handler_fn)(const void *msg, unsigned int nodeid)
Definition: coroapi.h:476
The corosync_lib_handler struct.
Definition: coroapi.h:467
void(* lib_handler_fn)(void *conn, const void *msg)
Definition: coroapi.h:468
The corosync_service_engine struct.
Definition: coroapi.h:490
const char * name
Definition: coroapi.h:491
Structure passed as new_value and old_value in change callback.
Definition: icmap.h:91
icmap_value_types_t type
Definition: icmap.h:92
const void * data
Definition: icmap.h:94
size_t len
Definition: icmap.h:93
mar_name_t struct
Definition: mar_gen.h:166
The memb_ring_id struct.
Definition: coroapi.h:122
mar_size_t value_len __attribute__((aligned(8)))
mar_name_t key_name __attribute__((aligned(8)))
mar_uint8_t value_type __attribute__((aligned(8)))
uint8_t value[] __attribute__((aligned(8)))
mar_uint8_t reason __attribute__((aligned(8)))
mar_uint8_t no_items __attribute__((aligned(8)))
mar_uint8_t reserver2 __attribute__((aligned(8)))
mar_uint8_t reserved1 __attribute__((aligned(8)))
struct qb_ipc_request_header header __attribute__((aligned(8)))
The req_lib_cmap_adjust_int struct.
Definition: ipc_cmap.h:135
The req_lib_cmap_get struct.
Definition: ipc_cmap.h:116
The req_lib_cmap_iter_finalize struct.
Definition: ipc_cmap.h:185
The req_lib_cmap_iter_init struct.
Definition: ipc_cmap.h:151
The req_lib_cmap_iter_next struct.
Definition: ipc_cmap.h:167
The req_lib_cmap_set_current_map struct used by cmap_initialize_map()
Definition: ipc_cmap.h:257
The req_lib_cmap_set struct.
Definition: ipc_cmap.h:83
The req_lib_cmap_track_add struct.
Definition: ipc_cmap.h:200
The req_lib_cmap_track_delete struct.
Definition: ipc_cmap.h:218
The res_lib_cmap_adjust_int struct.
Definition: ipc_cmap.h:144
The res_lib_cmap_delete struct.
Definition: ipc_cmap.h:109
The res_lib_cmap_get struct.
Definition: ipc_cmap.h:125
The res_lib_cmap_iter_finalize struct.
Definition: ipc_cmap.h:193
The res_lib_cmap_iter_init struct.
Definition: ipc_cmap.h:159
The res_lib_cmap_iter_next struct.
Definition: ipc_cmap.h:175
The res_lib_cmap_notify_callback struct.
Definition: ipc_cmap.h:234
The res_lib_cmap_set struct.
Definition: ipc_cmap.h:94
The res_lib_cmap_track_add struct.
Definition: ipc_cmap.h:210
The res_lib_cmap_track_delete struct.
Definition: ipc_cmap.h:226
#define swab64(x)
The swab64 macro.
Definition: swab.h:65
#define swab16(x)
The swab16 macro.
Definition: swab.h:39
#define swab32(x)
The swab32 macro.
Definition: swab.h:51
char type
Definition: totem.h:2
struct memb_ring_id ring_id
Definition: totemsrp.c:4
struct totem_message_header header
Definition: totemsrp.c:0