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