pacemaker 2.1.7-2.1.7
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
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
28static 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
38static int
39cib_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
53static gint
54ciblib_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
77static int
78cib_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
114static int
115get_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
131static int
132cib_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
177static gboolean
178cib_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
190static gboolean
191cib_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
239static gboolean
240cib_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
251static int
252cib_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
259static int
260cib_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
267static int
268cib_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
273static int
274cib_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
282static int
283is_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
290static int
291set_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
298static int
299set_all_secondary(cib_t * cib, int call_options)
300{
301 return -EPROTONOSUPPORT;
302}
303
304static int
305set_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
313static int
314cib_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
321static int
322cib_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
329static int
330cib_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
335static int
336cib_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
343static int
344cib_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
351static int
352cib_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
359static int
360cib_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
367static int
368cib_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
375static int
376cib_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
383static int
384cib_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
391static int
392cib_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
420static int
421cib_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
454static void
455cib_client_set_user(cib_t *cib, const char *user)
456{
457 pcmk__str_update(&(cib->user), user);
458}
459
460static void
461cib_destroy_op_callback(gpointer data)
462{
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
477static void
478destroy_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
486char *
487get_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
546cib_t *
547cib_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
573cib_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 */
604cib_t *
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
664cib_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
742void
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
764void
766{
767 cib_free_notify(cib);
768
769 destroy_op_callback_table();
770}
771
777void
779{
781 if (cib) {
782 cib->cmds->free(cib);
783 }
784}
785
786void
787remove_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
797int
799{
800 if (cib_op_callback_table == NULL) {
801 return 0;
802 }
803 return g_hash_table_size(cib_op_callback_table);
804}
805
806static void
807cib_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
815void
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
825cib__lookup_id (int call_id)
826{
827 return pcmk__intkey_table_lookup(cib_op_callback_table, call_id);
828}
#define PCMK__CIB_REQUEST_ABS_DELETE
Definition internal.h:31
void cib_native_callback(cib_t *cib, xmlNode *msg, int call_id, int rc)
Definition cib_utils.c:786
#define PCMK__CIB_REQUEST_SYNC_TO_ALL
Definition internal.h:19
#define PCMK__CIB_REQUEST_PRIMARY
Definition internal.h:18
#define PCMK__CIB_REQUEST_COMMIT_TRANSACT
Definition internal.h:34
#define PCMK__CIB_REQUEST_IS_PRIMARY
Definition internal.h:21
#define PCMK__CIB_REQUEST_SECONDARY
Definition internal.h:17
#define PCMK__CIB_REQUEST_QUERY
Definition internal.h:23
#define PCMK__CIB_REQUEST_REPLACE
Definition internal.h:28
#define PCMK__CIB_REQUEST_DELETE
Definition internal.h:26
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
#define PCMK__CIB_REQUEST_BUMP
Definition internal.h:22
#define PCMK__CIB_REQUEST_CREATE
Definition internal.h:24
#define PCMK__CIB_REQUEST_NOOP
Definition internal.h:32
#define PCMK__CIB_REQUEST_MODIFY
Definition internal.h:25
#define PCMK__CIB_REQUEST_UPGRADE
Definition internal.h:30
#define T_CIB_TRANSACTION
Definition internal.h:70
#define PCMK__CIB_REQUEST_ERASE
Definition internal.h:27
const char * name
Definition cib.c:26
cib_t * cib_remote_new(const char *server, const char *user, const char *passwd, int port, gboolean encrypted)
Definition cib_remote.c:593
cib_t * cib_native_new(void)
Definition cib_native.c:472
cib_t * cib_file_new(const char *filename)
Definition cib_file.c:644
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_new_variant(void)
Definition cib_client.c:665
void cib_delete(cib_t *cib)
Free all memory used by CIB connection.
Definition cib_client.c:778
#define op_common(cib)
Definition cib_client.c:30
cib_t * cib_shadow_new(const char *shadow)
Definition cib_client.c:547
int num_cib_op_callbacks(void)
Definition cib_client.c:798
cib_t * cib_new(void)
Create a new CIB connection object.
Definition cib_client.c:605
char * get_shadow_file(const char *suffix)
Definition cib_client.c:487
void remove_cib_op_callback(int call_id, gboolean all_callbacks)
Definition cib_client.c:787
cib_callback_client_t * cib__lookup_id(int call_id)
Definition cib_client.c:825
void cib_dump_pending_callbacks(void)
Definition cib_client.c:816
void cib_free_callbacks(cib_t *cib)
Free all callbacks for a CIB connection.
Definition cib_client.c:765
void cib_free_notify(cib_t *cib)
Definition cib_client.c:743
@ cib_no_connection
Definition cib_types.h:49
@ cib_scope_local
Definition cib_types.h:82
@ cib_sync_call
Definition cib_types.h:102
@ cib_native
Definition cib_types.h:30
@ cib_undefined
Definition cib_types.h:29
@ cib_remote
Definition cib_types.h:32
@ cib_disconnected
Definition cib_types.h:43
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
gboolean crm_is_true(const char *s)
Definition strings.c:416
#define CRM_DAEMON_USER
Definition config.h:30
#define CRM_CONFIG_DIR
Definition config.h:17
pcmk__cpg_host_t host
Definition cpg.c:4
char data[0]
Definition cpg.c:10
A dumping ground.
#define CRM_OP_PING
Definition crm.h:133
const char * pcmk__get_tmpdir(void)
Definition io.c:547
#define crm_info(fmt, args...)
Definition logging.h:382
#define crm_warn(fmt, args...)
Definition logging.h:380
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition logging.h:323
#define CRM_CHECK(expr, failure_action)
Definition logging.h:238
#define crm_debug(fmt, args...)
Definition logging.h:384
#define crm_err(fmt, args...)
Definition logging.h:379
#define crm_trace(fmt, args...)
Definition logging.h:385
unsigned int timeout
Definition pcmk_fence.c:32
#define ETIME
const char * pcmk_strerror(int rc)
Definition results.c:149
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:501
@ pcmk_rc_no_transaction
Definition results.h:113
@ pcmk_rc_ok
Definition results.h:154
@ pcmk_rc_already
Definition results.h:146
#define pcmk_ok
Definition results.h:68
int pcmk_rc2legacy(int rc)
Definition results.c:546
int pcmk__scan_port(const char *text, int *port)
Definition strings.c:161
void pcmk__str_update(char **str, const char *value)
Definition strings.c:1193
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition strings.c:933
int(* upgrade)(cib_t *cib, int call_options)
Definition cib_types.h:176
int(* create)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:178
int(* set_master)(cib_t *cib, int call_options)
Definition cib_types.h:165
int(* noop)(cib_t *cib, int call_options)
Definition cib_types.h:153
int(* delete_absolute)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:194
int(* erase)(cib_t *cib, xmlNode **output_data, int call_options)
Definition cib_types.h:191
int(* del_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
Definition cib_types.h:143
int(* add_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
Definition cib_types.h:140
int(* bump_epoch)(cib_t *cib, int call_options)
Definition cib_types.h:177
int(* is_master)(cib_t *cib)
Definition cib_types.h:162
int(* set_slave_all)(cib_t *cib, int call_options)
Definition cib_types.h:171
int(* remove)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:189
int(* set_primary)(cib_t *cib, int call_options)
Set the local CIB manager as the cluster's primary instance.
Definition cib_types.h:222
int(* set_slave)(cib_t *cib, int call_options)
Definition cib_types.h:168
int(* query_from)(cib_t *cib, const char *host, const char *section, xmlNode **output_data, int call_options)
Definition cib_types.h:158
int(* update)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:184
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(* end_transaction)(cib_t *cib, bool commit, int call_options)
End and optionally commit this client's CIB transaction.
Definition cib_types.h:314
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition cib_types.h:156
int(* set_secondary)(cib_t *cib, int call_options)
Set the local CIB manager as a secondary instance.
Definition cib_types.h:232
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_from)(cib_t *cib, const char *host, const char *section, int call_options)
Definition cib_types.h:174
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
int(* ping)(cib_t *cib, xmlNode **output_data, int call_options)
Definition cib_types.h:155
int(* client_id)(const cib_t *cib, const char **async_id, const char **sync_id)
Get the given CIB connection's unique client identifier(s)
Definition cib_types.h:251
int(* register_notification)(cib_t *cib, const char *callback, int enabled)
Definition cib_types.h:200
int(* replace)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:187
int(* init_transaction)(cib_t *cib)
Initiate an atomic CIB transaction for this client.
Definition cib_types.h:288
int(* sync)(cib_t *cib, const char *section, int call_options)
Definition cib_types.h:173
int(* free)(cib_t *cib)
Definition cib_types.h:133
int(* modify)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:180
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
const char * id
Definition internal.h:139
void(* callback)(xmlNode *, int, int, xmlNode *, void *)
Definition internal.h:138
void(* free_func)(void *)
Definition internal.h:143
struct timer_rec_s * timer
Definition internal.h:142
const char * event
Definition internal.h:130
void(* callback)(const char *event, xmlNode *msg)
Definition internal.h:133
enum cib_conn_type type
Definition cib_types.h:331
enum cib_state state
Definition cib_types.h:330
GList * notify_list
Definition cib_types.h:339
xmlNode * transaction
Definition cib_types.h:347
void * variant_opaque
Definition cib_types.h:336
cib_api_operations_t * cmds
Definition cib_types.h:345
enum cib_variant variant
Definition cib_types.h:332
char * user
Definition cib_types.h:349
int call_id
Definition cib_types.h:334
void(* op_callback)(const xmlNode *msg, int call_id, int rc, xmlNode *output)
Definition cib_types.h:342
cib_t * cib
Definition internal.h:150
guint ref
Definition internal.h:149
Wrappers for and extensions to libxml2.
void free_xml(xmlNode *child)
Definition xml.c:783
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition xml.c:638