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