pacemaker  2.1.7-0f7f88312f
Scalable High-Availability cluster resource manager
cib_client.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2023 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <pwd.h>
17 
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 
21 #include <glib.h>
22 
23 #include <crm/crm.h>
24 #include <crm/cib/internal.h>
25 #include <crm/msg_xml.h>
26 #include <crm/common/xml.h>
27 
28 static GHashTable *cib_op_callback_table = NULL;
29 
30 #define op_common(cib) do { \
31  if(cib == NULL) { \
32  return -EINVAL; \
33  } else if(cib->delegate_fn == NULL) { \
34  return -EPROTONOSUPPORT; \
35  } \
36  } while(0)
37 
38 static int
39 cib_client_set_op_callback(cib_t *cib,
40  void (*callback) (const xmlNode * msg, int call_id,
41  int rc, xmlNode * output))
42 {
43  if (callback == NULL) {
44  crm_info("Un-Setting operation callback");
45 
46  } else {
47  crm_trace("Setting operation callback");
48  }
49  cib->op_callback = callback;
50  return pcmk_ok;
51 }
52 
53 static gint
54 ciblib_GCompareFunc(gconstpointer a, gconstpointer b)
55 {
56  int rc = 0;
57  const cib_notify_client_t *a_client = a;
58  const cib_notify_client_t *b_client = b;
59 
60  CRM_CHECK(a_client->event != NULL && b_client->event != NULL, return 0);
61  rc = strcmp(a_client->event, b_client->event);
62  if (rc == 0) {
63  if (a_client->callback == b_client->callback) {
64  return 0;
65  } else if (((long)a_client->callback) < ((long)b_client->callback)) {
66  crm_trace("callbacks for %s are not equal: %p < %p",
67  a_client->event, a_client->callback, b_client->callback);
68  return -1;
69  }
70  crm_trace("callbacks for %s are not equal: %p > %p",
71  a_client->event, a_client->callback, b_client->callback);
72  return 1;
73  }
74  return rc;
75 }
76 
77 static int
78 cib_client_add_notify_callback(cib_t * cib, const char *event,
79  void (*callback) (const char *event,
80  xmlNode * msg))
81 {
82  GList *list_item = NULL;
83  cib_notify_client_t *new_client = NULL;
84 
85  if ((cib->variant != cib_native) && (cib->variant != cib_remote)) {
86  return -EPROTONOSUPPORT;
87  }
88 
89  crm_trace("Adding callback for %s events (%d)",
90  event, g_list_length(cib->notify_list));
91 
92  new_client = calloc(1, sizeof(cib_notify_client_t));
93  new_client->event = event;
94  new_client->callback = callback;
95 
96  list_item = g_list_find_custom(cib->notify_list, new_client,
97  ciblib_GCompareFunc);
98 
99  if (list_item != NULL) {
100  crm_warn("Callback already present");
101  free(new_client);
102  return -EINVAL;
103 
104  } else {
105  cib->notify_list = g_list_append(cib->notify_list, new_client);
106 
107  cib->cmds->register_notification(cib, event, 1);
108 
109  crm_trace("Callback added (%d)", g_list_length(cib->notify_list));
110  }
111  return pcmk_ok;
112 }
113 
114 static int
115 get_notify_list_event_count(cib_t *cib, const char *event)
116 {
117  int count = 0;
118 
119  for (GList *iter = g_list_first(cib->notify_list); iter != NULL;
120  iter = iter->next) {
121  cib_notify_client_t *client = (cib_notify_client_t *) iter->data;
122 
123  if (strcmp(client->event, event) == 0) {
124  count++;
125  }
126  }
127  crm_trace("event(%s) count : %d", event, count);
128  return count;
129 }
130 
131 static int
132 cib_client_del_notify_callback(cib_t *cib, const char *event,
133  void (*callback) (const char *event,
134  xmlNode *msg))
135 {
136  GList *list_item = NULL;
137  cib_notify_client_t *new_client = NULL;
138 
139  if (cib->variant != cib_native && cib->variant != cib_remote) {
140  return -EPROTONOSUPPORT;
141  }
142 
143  if (get_notify_list_event_count(cib, event) == 0) {
144  crm_debug("The callback of the event does not exist(%s)", event);
145  return pcmk_ok;
146  }
147 
148  crm_debug("Removing callback for %s events", event);
149 
150  new_client = calloc(1, sizeof(cib_notify_client_t));
151  new_client->event = event;
152  new_client->callback = callback;
153 
154  list_item = g_list_find_custom(cib->notify_list, new_client, ciblib_GCompareFunc);
155 
156  if (list_item != NULL) {
157  cib_notify_client_t *list_client = list_item->data;
158 
159  cib->notify_list = g_list_remove(cib->notify_list, list_client);
160  free(list_client);
161 
162  crm_trace("Removed callback");
163 
164  } else {
165  crm_trace("Callback not present");
166  }
167 
168  if (get_notify_list_event_count(cib, event) == 0) {
169  /* When there is not the registration of the event, the processing turns off a notice. */
170  cib->cmds->register_notification(cib, event, 0);
171  }
172 
173  free(new_client);
174  return pcmk_ok;
175 }
176 
177 static gboolean
178 cib_async_timeout_handler(gpointer data)
179 {
180  struct timer_rec_s *timer = data;
181 
182  crm_debug("Async call %d timed out after %ds",
183  timer->call_id, timer->timeout);
184  cib_native_callback(timer->cib, NULL, timer->call_id, -ETIME);
185 
186  // We remove the handler in remove_cib_op_callback()
187  return G_SOURCE_CONTINUE;
188 }
189 
190 static gboolean
191 cib_client_register_callback_full(cib_t *cib, int call_id, int timeout,
192  gboolean only_success, void *user_data,
193  const char *callback_name,
194  void (*callback)(xmlNode *, int, int,
195  xmlNode *, void *),
196  void (*free_func)(void *))
197 {
198  cib_callback_client_t *blob = NULL;
199 
200  if (call_id < 0) {
201  if (only_success == FALSE) {
202  callback(NULL, call_id, call_id, NULL, user_data);
203  } else {
204  crm_warn("CIB call failed: %s", pcmk_strerror(call_id));
205  }
206  if (user_data && free_func) {
207  free_func(user_data);
208  }
209  return FALSE;
210  }
211 
212  blob = calloc(1, sizeof(cib_callback_client_t));
213  blob->id = callback_name;
214  blob->only_success = only_success;
215  blob->user_data = user_data;
216  blob->callback = callback;
217  blob->free_func = free_func;
218 
219  if (timeout > 0) {
220  struct timer_rec_s *async_timer = NULL;
221 
222  async_timer = calloc(1, sizeof(struct timer_rec_s));
223  blob->timer = async_timer;
224 
225  async_timer->cib = cib;
226  async_timer->call_id = call_id;
227  async_timer->timeout = timeout * 1000;
228  async_timer->ref = g_timeout_add(async_timer->timeout,
229  cib_async_timeout_handler,
230  async_timer);
231  }
232 
233  crm_trace("Adding callback %s for call %d", callback_name, call_id);
234  pcmk__intkey_table_insert(cib_op_callback_table, call_id, blob);
235 
236  return TRUE;
237 }
238 
239 static gboolean
240 cib_client_register_callback(cib_t *cib, int call_id, int timeout,
241  gboolean only_success, void *user_data,
242  const char *callback_name,
243  void (*callback) (xmlNode *, int, int, xmlNode *,
244  void *))
245 {
246  return cib_client_register_callback_full(cib, call_id, timeout,
247  only_success, user_data,
248  callback_name, callback, NULL);
249 }
250 
251 static int
252 cib_client_noop(cib_t * cib, int call_options)
253 {
254  op_common(cib);
255  return cib_internal_op(cib, PCMK__CIB_REQUEST_NOOP, NULL, NULL, NULL, NULL,
256  call_options, cib->user);
257 }
258 
259 static int
260 cib_client_ping(cib_t * cib, xmlNode ** output_data, int call_options)
261 {
262  op_common(cib);
263  return cib_internal_op(cib, CRM_OP_PING, NULL, NULL, NULL, output_data,
264  call_options, cib->user);
265 }
266 
267 static int
268 cib_client_query(cib_t * cib, const char *section, xmlNode ** output_data, int call_options)
269 {
270  return cib->cmds->query_from(cib, NULL, section, output_data, call_options);
271 }
272 
273 static int
274 cib_client_query_from(cib_t * cib, const char *host, const char *section,
275  xmlNode ** output_data, int call_options)
276 {
277  op_common(cib);
278  return cib_internal_op(cib, PCMK__CIB_REQUEST_QUERY, host, section, NULL,
279  output_data, call_options, cib->user);
280 }
281 
282 static int
283 is_primary(cib_t *cib)
284 {
285  op_common(cib);
286  return cib_internal_op(cib, PCMK__CIB_REQUEST_IS_PRIMARY, NULL, NULL, NULL,
288 }
289 
290 static int
291 set_secondary(cib_t *cib, int call_options)
292 {
293  op_common(cib);
294  return cib_internal_op(cib, PCMK__CIB_REQUEST_SECONDARY, NULL, NULL, NULL,
295  NULL, call_options, cib->user);
296 }
297 
298 static int
299 set_all_secondary(cib_t * cib, int call_options)
300 {
301  return -EPROTONOSUPPORT;
302 }
303 
304 static int
305 set_primary(cib_t *cib, int call_options)
306 {
307  op_common(cib);
308  crm_trace("Adding cib_scope_local to options");
309  return cib_internal_op(cib, PCMK__CIB_REQUEST_PRIMARY, NULL, NULL, NULL,
310  NULL, call_options|cib_scope_local, cib->user);
311 }
312 
313 static int
314 cib_client_bump_epoch(cib_t * cib, int call_options)
315 {
316  op_common(cib);
317  return cib_internal_op(cib, PCMK__CIB_REQUEST_BUMP, NULL, NULL, NULL, NULL,
318  call_options, cib->user);
319 }
320 
321 static int
322 cib_client_upgrade(cib_t * cib, int call_options)
323 {
324  op_common(cib);
325  return cib_internal_op(cib, PCMK__CIB_REQUEST_UPGRADE, NULL, NULL, NULL,
326  NULL, call_options, cib->user);
327 }
328 
329 static int
330 cib_client_sync(cib_t * cib, const char *section, int call_options)
331 {
332  return cib->cmds->sync_from(cib, NULL, section, call_options);
333 }
334 
335 static int
336 cib_client_sync_from(cib_t * cib, const char *host, const char *section, int call_options)
337 {
338  op_common(cib);
340  NULL, NULL, call_options, cib->user);
341 }
342 
343 static int
344 cib_client_create(cib_t * cib, const char *section, xmlNode * data, int call_options)
345 {
346  op_common(cib);
347  return cib_internal_op(cib, PCMK__CIB_REQUEST_CREATE, NULL, section, data,
348  NULL, call_options, cib->user);
349 }
350 
351 static int
352 cib_client_modify(cib_t * cib, const char *section, xmlNode * data, int call_options)
353 {
354  op_common(cib);
355  return cib_internal_op(cib, PCMK__CIB_REQUEST_MODIFY, NULL, section, data,
356  NULL, call_options, cib->user);
357 }
358 
359 static int
360 cib_client_replace(cib_t * cib, const char *section, xmlNode * data, int call_options)
361 {
362  op_common(cib);
363  return cib_internal_op(cib, PCMK__CIB_REQUEST_REPLACE, NULL, section, data,
364  NULL, call_options, cib->user);
365 }
366 
367 static int
368 cib_client_delete(cib_t * cib, const char *section, xmlNode * data, int call_options)
369 {
370  op_common(cib);
371  return cib_internal_op(cib, PCMK__CIB_REQUEST_DELETE, NULL, section, data,
372  NULL, call_options, cib->user);
373 }
374 
375 static int
376 cib_client_delete_absolute(cib_t * cib, const char *section, xmlNode * data, int call_options)
377 {
378  op_common(cib);
379  return cib_internal_op(cib, PCMK__CIB_REQUEST_ABS_DELETE, NULL, section,
380  data, NULL, call_options, cib->user);
381 }
382 
383 static int
384 cib_client_erase(cib_t * cib, xmlNode ** output_data, int call_options)
385 {
386  op_common(cib);
387  return cib_internal_op(cib, PCMK__CIB_REQUEST_ERASE, NULL, NULL, NULL,
388  output_data, call_options, cib->user);
389 }
390 
391 static int
392 cib_client_init_transaction(cib_t *cib)
393 {
394  int rc = pcmk_rc_ok;
395 
396  op_common(cib);
397 
398  if (cib->transaction != NULL) {
399  // A client can have at most one transaction at a time
400  rc = pcmk_rc_already;
401  }
402 
403  if (rc == pcmk_rc_ok) {
405  if (cib->transaction == NULL) {
406  rc = ENOMEM;
407  }
408  }
409 
410  if (rc != pcmk_rc_ok) {
411  const char *client_id = NULL;
412 
413  cib->cmds->client_id(cib, NULL, &client_id);
414  crm_err("Failed to initialize CIB transaction for client %s: %s",
415  client_id, pcmk_rc_str(rc));
416  }
417  return pcmk_rc2legacy(rc);
418 }
419 
420 static int
421 cib_client_end_transaction(cib_t *cib, bool commit, int call_options)
422 {
423  const char *client_id = NULL;
424  int rc = pcmk_ok;
425 
426  op_common(cib);
427  cib->cmds->client_id(cib, NULL, &client_id);
428  client_id = pcmk__s(client_id, "(unidentified)");
429 
430  if (commit) {
431  if (cib->transaction == NULL) {
433 
434  crm_err("Failed to commit transaction for CIB client %s: %s",
435  client_id, pcmk_rc_str(rc));
436  return pcmk_rc2legacy(rc);
437  }
439  cib->transaction, NULL, call_options, cib->user);
440 
441  } else {
442  // Discard always succeeds
443  if (cib->transaction != NULL) {
444  crm_trace("Discarded transaction for CIB client %s", client_id);
445  } else {
446  crm_trace("No transaction found for CIB client %s", client_id);
447  }
448  }
450  cib->transaction = NULL;
451  return rc;
452 }
453 
454 static void
455 cib_client_set_user(cib_t *cib, const char *user)
456 {
457  pcmk__str_update(&(cib->user), user);
458 }
459 
460 static void
461 cib_destroy_op_callback(gpointer data)
462 {
463  cib_callback_client_t *blob = data;
464 
465  if (blob->timer && blob->timer->ref > 0) {
466  g_source_remove(blob->timer->ref);
467  }
468  free(blob->timer);
469 
470  if (blob->user_data && blob->free_func) {
471  blob->free_func(blob->user_data);
472  }
473 
474  free(blob);
475 }
476 
477 static void
478 destroy_op_callback_table(void)
479 {
480  if (cib_op_callback_table != NULL) {
481  g_hash_table_destroy(cib_op_callback_table);
482  cib_op_callback_table = NULL;
483  }
484 }
485 
486 char *
487 get_shadow_file(const char *suffix)
488 {
489  char *cib_home = NULL;
490  char *fullname = NULL;
491  char *name = crm_strdup_printf("shadow.%s", suffix);
492  const char *dir = getenv("CIB_shadow_dir");
493 
494  if (dir == NULL) {
495  uid_t uid = geteuid();
496  struct passwd *pwent = getpwuid(uid);
497  const char *user = NULL;
498 
499  if (pwent) {
500  user = pwent->pw_name;
501  } else {
502  user = getenv("USER");
503  crm_perror(LOG_ERR,
504  "Assuming %s because cannot get user details for user ID %d",
505  (user? user : "unprivileged user"), uid);
506  }
507 
508  if (pcmk__strcase_any_of(user, "root", CRM_DAEMON_USER, NULL)) {
509  dir = CRM_CONFIG_DIR;
510 
511  } else {
512  const char *home = NULL;
513 
514  if ((home = getenv("HOME")) == NULL) {
515  if (pwent) {
516  home = pwent->pw_dir;
517  }
518  }
519 
520  dir = pcmk__get_tmpdir();
521  if (home && home[0] == '/') {
522  int rc = 0;
523 
524  cib_home = crm_strdup_printf("%s/.cib", home);
525 
526  rc = mkdir(cib_home, 0700);
527  if (rc < 0 && errno != EEXIST) {
528  crm_perror(LOG_ERR, "Couldn't create user-specific shadow directory: %s",
529  cib_home);
530  errno = 0;
531 
532  } else {
533  dir = cib_home;
534  }
535  }
536  }
537  }
538 
539  fullname = crm_strdup_printf("%s/%s", dir, name);
540  free(cib_home);
541  free(name);
542 
543  return fullname;
544 }
545 
546 cib_t *
547 cib_shadow_new(const char *shadow)
548 {
549  cib_t *new_cib = NULL;
550  char *shadow_file = NULL;
551 
552  CRM_CHECK(shadow != NULL, return NULL);
553 
554  shadow_file = get_shadow_file(shadow);
555  new_cib = cib_file_new(shadow_file);
556  free(shadow_file);
557 
558  return new_cib;
559 }
560 
573 cib_t *
575 {
576  const char *shadow = getenv("CIB_shadow");
577  cib_t *cib = NULL;
578 
579  unsetenv("CIB_shadow");
580  cib = cib_new();
581 
582  if (shadow != NULL) {
583  setenv("CIB_shadow", shadow, 1);
584  }
585  return cib;
586 }
587 
601 /* @TODO Ensure all APIs support multiple simultaneous CIB connection objects
602  * (at least cib_free_callbacks() currently does not).
603  */
604 cib_t *
605 cib_new(void)
606 {
607  const char *value = getenv("CIB_shadow");
608  int port;
609 
610  if (value && value[0] != 0) {
611  return cib_shadow_new(value);
612  }
613 
614  value = getenv("CIB_file");
615  if (value) {
616  return cib_file_new(value);
617  }
618 
619  value = getenv("CIB_port");
620  if (value) {
621  gboolean encrypted = TRUE;
622  const char *server = getenv("CIB_server");
623  const char *user = getenv("CIB_user");
624  const char *pass = getenv("CIB_passwd");
625 
626  /* We don't ensure port is valid (>= 0) because cib_new() currently
627  * can't return NULL in practice, and introducing a NULL return here
628  * could cause core dumps that would previously just cause signon()
629  * failures.
630  */
631  pcmk__scan_port(value, &port);
632 
633  value = getenv("CIB_encrypted");
634  if (value && crm_is_true(value) == FALSE) {
635  crm_info("Disabling TLS");
636  encrypted = FALSE;
637  }
638 
639  if (user == NULL) {
640  user = CRM_DAEMON_USER;
641  crm_info("Defaulting to user: %s", user);
642  }
643 
644  if (server == NULL) {
645  server = "localhost";
646  crm_info("Defaulting to localhost");
647  }
648 
649  return cib_remote_new(server, user, pass, port, encrypted);
650  }
651 
652  return cib_native_new();
653 }
654 
664 cib_t *
666 {
667  cib_t *new_cib = NULL;
668 
669  new_cib = calloc(1, sizeof(cib_t));
670 
671  if (new_cib == NULL) {
672  return NULL;
673  }
674 
675  remove_cib_op_callback(0, TRUE); /* remove all */
676 
677  new_cib->call_id = 1;
678  new_cib->variant = cib_undefined;
679 
680  new_cib->type = cib_no_connection;
681  new_cib->state = cib_disconnected;
682 
683  new_cib->op_callback = NULL;
684  new_cib->variant_opaque = NULL;
685  new_cib->notify_list = NULL;
686 
687  /* the rest will get filled in by the variant constructor */
688  new_cib->cmds = calloc(1, sizeof(cib_api_operations_t));
689 
690  if (new_cib->cmds == NULL) {
691  free(new_cib);
692  return NULL;
693  }
694 
695  // Deprecated method
696  new_cib->cmds->set_op_callback = cib_client_set_op_callback;
697 
698  new_cib->cmds->add_notify_callback = cib_client_add_notify_callback;
699  new_cib->cmds->del_notify_callback = cib_client_del_notify_callback;
700  new_cib->cmds->register_callback = cib_client_register_callback;
701  new_cib->cmds->register_callback_full = cib_client_register_callback_full;
702 
703  new_cib->cmds->noop = cib_client_noop; // Deprecated method
704  new_cib->cmds->ping = cib_client_ping;
705  new_cib->cmds->query = cib_client_query;
706  new_cib->cmds->sync = cib_client_sync;
707 
708  new_cib->cmds->query_from = cib_client_query_from;
709  new_cib->cmds->sync_from = cib_client_sync_from;
710 
711  new_cib->cmds->is_master = is_primary; // Deprecated method
712 
713  new_cib->cmds->set_primary = set_primary;
714  new_cib->cmds->set_master = set_primary; // Deprecated method
715 
716  new_cib->cmds->set_secondary = set_secondary;
717  new_cib->cmds->set_slave = set_secondary; // Deprecated method
718 
719  new_cib->cmds->set_slave_all = set_all_secondary; // Deprecated method
720 
721  new_cib->cmds->upgrade = cib_client_upgrade;
722  new_cib->cmds->bump_epoch = cib_client_bump_epoch;
723 
724  new_cib->cmds->create = cib_client_create;
725  new_cib->cmds->modify = cib_client_modify;
726  new_cib->cmds->update = cib_client_modify; // Deprecated method
727  new_cib->cmds->replace = cib_client_replace;
728  new_cib->cmds->remove = cib_client_delete;
729  new_cib->cmds->erase = cib_client_erase;
730 
731  // Deprecated method
732  new_cib->cmds->delete_absolute = cib_client_delete_absolute;
733 
734  new_cib->cmds->init_transaction = cib_client_init_transaction;
735  new_cib->cmds->end_transaction = cib_client_end_transaction;
736 
737  new_cib->cmds->set_user = cib_client_set_user;
738 
739  return new_cib;
740 }
741 
742 void
744 {
745 
746  if (cib) {
747  GList *list = cib->notify_list;
748 
749  while (list != NULL) {
750  cib_notify_client_t *client = g_list_nth_data(list, 0);
751 
752  list = g_list_remove(list, client);
753  free(client);
754  }
755  cib->notify_list = NULL;
756  }
757 }
758 
764 void
766 {
767  cib_free_notify(cib);
768 
769  destroy_op_callback_table();
770 }
771 
777 void
779 {
780  cib_free_callbacks(cib);
781  if (cib) {
782  cib->cmds->free(cib);
783  }
784 }
785 
786 void
787 remove_cib_op_callback(int call_id, gboolean all_callbacks)
788 {
789  if (all_callbacks) {
790  destroy_op_callback_table();
791  cib_op_callback_table = pcmk__intkey_table(cib_destroy_op_callback);
792  } else {
793  pcmk__intkey_table_remove(cib_op_callback_table, call_id);
794  }
795 }
796 
797 int
799 {
800  if (cib_op_callback_table == NULL) {
801  return 0;
802  }
803  return g_hash_table_size(cib_op_callback_table);
804 }
805 
806 static void
807 cib_dump_pending_op(gpointer key, gpointer value, gpointer user_data)
808 {
809  int call = GPOINTER_TO_INT(key);
810  cib_callback_client_t *blob = value;
811 
812  crm_debug("Call %d (%s): pending", call, pcmk__s(blob->id, "without ID"));
813 }
814 
815 void
817 {
818  if (cib_op_callback_table == NULL) {
819  return;
820  }
821  return g_hash_table_foreach(cib_op_callback_table, cib_dump_pending_op, NULL);
822 }
823 
825 cib__lookup_id (int call_id)
826 {
827  return pcmk__intkey_table_lookup(cib_op_callback_table, call_id);
828 }
pcmk__cpg_host_t host
Definition: cpg.c:49
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:238
A dumping ground.
const char * pcmk_strerror(int rc)
Definition: results.c:149
#define ETIME
Definition: portability.h:111
gboolean(* register_callback)(cib_t *cib, int call_id, int timeout, gboolean only_success, void *user_data, const char *callback_name, void(*callback)(xmlNode *, int, int, xmlNode *, void *))
Definition: cib_types.h:202
char data[0]
Definition: cpg.c:55
cib_t * cib_remote_new(const char *server, const char *user, const char *passwd, int port, gboolean encrypted)
Definition: cib_remote.c:593
int pcmk_rc2legacy(int rc)
Definition: results.c:546
#define PCMK__CIB_REQUEST_PRIMARY
Definition: internal.h:18
void cib_dump_pending_callbacks(void)
Definition: cib_client.c:816
#define PCMK__CIB_REQUEST_CREATE
Definition: internal.h:24
const char * name
Definition: cib.c:26
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:933
int(* delete_absolute)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:194
gboolean(* register_callback_full)(cib_t *cib, int call_id, int timeout, gboolean only_success, void *user_data, const char *callback_name, void(*callback)(xmlNode *, int, int, xmlNode *, void *), void(*free_func)(void *))
Definition: cib_types.h:207
void(* callback)(const char *event, xmlNode *msg)
Definition: internal.h:133
#define PCMK__CIB_REQUEST_QUERY
Definition: internal.h:23
#define PCMK__CIB_REQUEST_COMMIT_TRANSACT
Definition: internal.h:34
void cib_free_callbacks(cib_t *cib)
Free all callbacks for a CIB connection.
Definition: cib_client.c:765
int call_id
Definition: internal.h:147
gboolean only_success
Definition: internal.h:141
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:501
cib_t * cib_new(void)
Create a new CIB connection object.
Definition: cib_client.c:605
cib_t * cib_shadow_new(const char *shadow)
Definition: cib_client.c:547
int(* set_secondary)(cib_t *cib, int call_options)
Set the local CIB manager as a secondary instance.
Definition: cib_types.h:232
#define PCMK__CIB_REQUEST_ERASE
Definition: internal.h:27
int(* set_op_callback)(cib_t *cib, void(*callback)(const xmlNode *msg, int callid, int rc, xmlNode *output))
Definition: cib_types.h:136
int(* sync)(cib_t *cib, const char *section, int call_options)
Definition: cib_types.h:173
#define PCMK__CIB_REQUEST_ABS_DELETE
Definition: internal.h:31
int timeout
Definition: internal.h:148
#define crm_warn(fmt, args...)
Definition: logging.h:382
struct timer_rec_s * timer
Definition: internal.h:142
int(* query_from)(cib_t *cib, const char *host, const char *section, xmlNode **output_data, int call_options)
Definition: cib_types.h:158
int pcmk__scan_port(const char *text, int *port)
Definition: strings.c:161
cib_api_operations_t * cmds
Definition: cib_types.h:345
#define crm_debug(fmt, args...)
Definition: logging.h:386
int num_cib_op_callbacks(void)
Definition: cib_client.c:798
int(* set_slave)(cib_t *cib, int call_options)
Definition: cib_types.h:168
#define PCMK__CIB_REQUEST_IS_PRIMARY
Definition: internal.h:21
void(* callback)(xmlNode *, int, int, xmlNode *, void *)
Definition: internal.h:138
guint ref
Definition: internal.h:149
#define crm_trace(fmt, args...)
Definition: logging.h:387
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
int(* modify)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:180
void(* op_callback)(const xmlNode *msg, int call_id, int rc, xmlNode *output)
Definition: cib_types.h:342
char * get_shadow_file(const char *suffix)
Definition: cib_client.c:487
int(* create)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:178
void pcmk__str_update(char **str, const char *value)
Definition: strings.c:1193
Wrappers for and extensions to libxml2.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:638
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition: cib_types.h:156
int(* is_master)(cib_t *cib)
Definition: cib_types.h:162
const char * event
Definition: internal.h:130
#define CRM_DAEMON_USER
Definition: config.h:30
xmlNode * transaction
Definition: cib_types.h:347
cib_t * cib_new_no_shadow(void)
Create a new CIB connection object, ignoring any active shadow CIB.
Definition: cib_client.c:574
cib_t * cib_native_new(void)
Definition: cib_native.c:472
int(* replace)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:187
void free_xml(xmlNode *child)
Definition: xml.c:783
int(* add_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
Definition: cib_types.h:140
int(* sync_from)(cib_t *cib, const char *host, const char *section, int call_options)
Definition: cib_types.h:174
#define op_common(cib)
Definition: cib_client.c:30
#define CRM_CONFIG_DIR
Definition: config.h:17
int(* register_notification)(cib_t *cib, const char *callback, int enabled)
Definition: cib_types.h:200
int(* ping)(cib_t *cib, xmlNode **output_data, int call_options)
Definition: cib_types.h:155
int(* update)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:184
void * variant_opaque
Definition: cib_types.h:336
#define PCMK__CIB_REQUEST_UPGRADE
Definition: internal.h:30
cib_t * cib_file_new(const char *filename)
Definition: cib_file.c:646
cib_callback_client_t * cib__lookup_id(int call_id)
Definition: cib_client.c:825
#define PCMK__CIB_REQUEST_BUMP
Definition: internal.h:22
int(* set_primary)(cib_t *cib, int call_options)
Set the local CIB manager as the cluster&#39;s primary instance.
Definition: cib_types.h:222
int(* noop)(cib_t *cib, int call_options)
Definition: cib_types.h:153
char * user
Definition: cib_types.h:349
const char * pcmk__get_tmpdir(void)
Definition: io.c:547
#define T_CIB_TRANSACTION
Definition: internal.h:70
int(* end_transaction)(cib_t *cib, bool commit, int call_options)
End and optionally commit this client&#39;s CIB transaction.
Definition: cib_types.h:314
int(* set_slave_all)(cib_t *cib, int call_options)
Definition: cib_types.h:171
int(* del_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
Definition: cib_types.h:143
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition: logging.h:323
void cib_free_notify(cib_t *cib)
Definition: cib_client.c:743
#define crm_err(fmt, args...)
Definition: logging.h:381
#define PCMK__CIB_REQUEST_REPLACE
Definition: internal.h:28
const char * id
Definition: internal.h:139
int(* set_master)(cib_t *cib, int call_options)
Definition: cib_types.h:165
cib_t * cib
Definition: internal.h:150
#define PCMK__CIB_REQUEST_SYNC_TO_ALL
Definition: internal.h:19
#define PCMK__CIB_REQUEST_SECONDARY
Definition: internal.h:17
#define PCMK__CIB_REQUEST_NOOP
Definition: internal.h:32
enum cib_variant variant
Definition: cib_types.h:332
#define pcmk_ok
Definition: results.h:68
void cib_native_callback(cib_t *cib, xmlNode *msg, int call_id, int rc)
Definition: cib_utils.c:786
void(* set_user)(cib_t *cib, const char *user)
Set the user as whom all CIB requests via methods will be executed.
Definition: cib_types.h:326
int call_id
Definition: cib_types.h:334
cib_t * cib_new_variant(void)
Definition: cib_client.c:665
int(* bump_epoch)(cib_t *cib, int call_options)
Definition: cib_types.h:177
gboolean crm_is_true(const char *s)
Definition: strings.c:416
#define PCMK__CIB_REQUEST_MODIFY
Definition: internal.h:25
int(* remove)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:189
#define CRM_OP_PING
Definition: crm.h:133
int cib_internal_op(cib_t *cib, const char *op, const char *host, const char *section, xmlNode *data, xmlNode **output_data, int call_options, const char *user_name)
Definition: cib_utils.c:943
int(* init_transaction)(cib_t *cib)
Initiate an atomic CIB transaction for this client.
Definition: cib_types.h:288
enum cib_conn_type type
Definition: cib_types.h:331
void cib_delete(cib_t *cib)
Free all memory used by CIB connection.
Definition: cib_client.c:778
enum cib_state state
Definition: cib_types.h:330
GList * notify_list
Definition: cib_types.h:339
int(* free)(cib_t *cib)
Definition: cib_types.h:133
void(* free_func)(void *)
Definition: internal.h:143
unsigned int timeout
Definition: pcmk_fence.c:32
int(* client_id)(const cib_t *cib, const char **async_id, const char **sync_id)
Get the given CIB connection&#39;s unique client identifier(s)
Definition: cib_types.h:251
int(* upgrade)(cib_t *cib, int call_options)
Definition: cib_types.h:176
#define crm_info(fmt, args...)
Definition: logging.h:384
int(* erase)(cib_t *cib, xmlNode **output_data, int call_options)
Definition: cib_types.h:191
void remove_cib_op_callback(int call_id, gboolean all_callbacks)
Definition: cib_client.c:787
#define PCMK__CIB_REQUEST_DELETE
Definition: internal.h:26