pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
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
27static 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
37static int
38cib_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
52static gint
53ciblib_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
76static int
77cib_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
113static int
114get_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
130static int
131cib_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
176static gboolean
177cib_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
189static gboolean
190cib_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
238static gboolean
239cib_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
250static int
251cib_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
258static int
259cib_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
266static int
267cib_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
272static int
273cib_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
281static int
282is_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
289static int
290set_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
297static int
298set_all_secondary(cib_t * cib, int call_options)
299{
300 return -EPROTONOSUPPORT;
301}
302
303static int
304set_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
312static int
313cib_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
320static int
321cib_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
328static int
329cib_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
334static int
335cib_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
342static int
343cib_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
350static int
351cib_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
358static int
359cib_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
366static int
367cib_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
374static int
375cib_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
382static int
383cib_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
390static int
391cib_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
416static int
417cib_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
450static int
451cib_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
465static void
466cib_client_set_user(cib_t *cib, const char *user)
467{
468 pcmk__str_update(&(cib->user), user);
469}
470
471static void
472cib_destroy_op_callback(gpointer data)
473{
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
488static void
489destroy_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
497char *
498get_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
557cib_t *
558cib_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
584cib_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 */
615cib_t *
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
675cib_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
755void
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
777void
779{
780 cib_free_notify(cib);
781
782 destroy_op_callback_table();
783}
784
790void
792{
794 if (cib) {
795 cib->cmds->free(cib);
796 }
797}
798
799void
800remove_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
810int
812{
813 if (cib_op_callback_table == NULL) {
814 return 0;
815 }
816 return g_hash_table_size(cib_op_callback_table);
817}
818
819static void
820cib_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
828void
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
838cib__lookup_id (int call_id)
839{
840 return pcmk__intkey_table_lookup(cib_op_callback_table, call_id);
841}
#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:771
#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:883
#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 PCMK__CIB_REQUEST_SCHEMAS
Definition internal.h:35
#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:601
cib_t * cib_native_new(void)
Definition cib_native.c:475
cib_t * cib_file_new(const char *filename)
Definition cib_file.c:646
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_new_variant(void)
Definition cib_client.c:676
void cib_delete(cib_t *cib)
Free all memory used by CIB connection.
Definition cib_client.c:791
#define op_common(cib)
Definition cib_client.c:29
cib_t * cib_shadow_new(const char *shadow)
Definition cib_client.c:558
int num_cib_op_callbacks(void)
Definition cib_client.c:811
cib_t * cib_new(void)
Create a new CIB connection object.
Definition cib_client.c:616
char * get_shadow_file(const char *suffix)
Definition cib_client.c:498
void remove_cib_op_callback(int call_id, gboolean all_callbacks)
Definition cib_client.c:800
cib_callback_client_t * cib__lookup_id(int call_id)
Definition cib_client.c:838
void cib_dump_pending_callbacks(void)
Definition cib_client.c:829
void cib_free_callbacks(cib_t *cib)
Free all callbacks for a CIB connection.
Definition cib_client.c:778
void cib_free_notify(cib_t *cib)
Definition cib_client.c:756
@ cib_no_connection
Definition cib_types.h:56
@ cib_scope_local
Definition cib_types.h:90
@ cib_sync_call
Definition cib_types.h:133
@ 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:47
#define pcmk__assert_alloc(nmemb, size)
Definition internal.h:297
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
gboolean crm_is_true(const char *s)
Definition strings.c:488
#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:119
const char * pcmk__get_tmpdir(void)
Definition io.c:547
#define crm_info(fmt, args...)
Definition logging.h:397
#define crm_warn(fmt, args...)
Definition logging.h:392
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition logging.h:331
#define CRM_CHECK(expr, failure_action)
Definition logging.h:245
#define crm_debug(fmt, args...)
Definition logging.h:400
#define crm_err(fmt, args...)
Definition logging.h:389
#define crm_trace(fmt, args...)
Definition logging.h:402
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
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:120
@ pcmk_rc_ok
Definition results.h:162
@ pcmk_rc_already
Definition results.h:153
#define pcmk_ok
Definition results.h:69
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:1277
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition strings.c:1026
int(* fetch_schemas)(cib_t *cib, xmlNode **output_data, const char *after_ver, int call_options)
Definition cib_types.h:376
int(* upgrade)(cib_t *cib, int call_options)
Definition cib_types.h:219
int(* create)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:226
int(* set_master)(cib_t *cib, int call_options)
Definition cib_types.h:208
int(* noop)(cib_t *cib, int call_options)
Definition cib_types.h:193
int(* delete_absolute)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:242
int(* erase)(cib_t *cib, xmlNode **output_data, int call_options)
Definition cib_types.h:239
int(* del_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
Definition cib_types.h:181
int(* add_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
Definition cib_types.h:176
int(* bump_epoch)(cib_t *cib, int call_options)
Definition cib_types.h:220
int(* is_master)(cib_t *cib)
Definition cib_types.h:205
int(* set_slave_all)(cib_t *cib, int call_options)
Definition cib_types.h:214
int(* remove)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:237
int(* set_primary)(cib_t *cib, int call_options)
Set the local CIB manager as the cluster's primary instance.
Definition cib_types.h:270
int(* set_slave)(cib_t *cib, int call_options)
Definition cib_types.h:211
int(* query_from)(cib_t *cib, const char *host, const char *section, xmlNode **output_data, int call_options)
Definition cib_types.h:201
int(* update)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:232
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(* end_transaction)(cib_t *cib, bool commit, int call_options)
End and optionally commit this client's CIB transaction.
Definition cib_types.h:362
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition cib_types.h:198
int(* set_secondary)(cib_t *cib, int call_options)
Set the local CIB manager as a secondary instance.
Definition cib_types.h:280
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_from)(cib_t *cib, const char *host, const char *section, int call_options)
Definition cib_types.h:217
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
int(* ping)(cib_t *cib, xmlNode **output_data, int call_options)
Definition cib_types.h:195
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:299
int(* register_notification)(cib_t *cib, const char *callback, int enabled)
Definition cib_types.h:248
int(* replace)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:235
int(* init_transaction)(cib_t *cib)
Initiate an atomic CIB transaction for this client.
Definition cib_types.h:336
int(* sync)(cib_t *cib, const char *section, int call_options)
Definition cib_types.h:216
int(* free)(cib_t *cib)
Definition cib_types.h:168
int(* modify)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition cib_types.h:228
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
const char * id
Definition internal.h:104
void(* callback)(xmlNode *, int, int, xmlNode *, void *)
Definition internal.h:103
void(* free_func)(void *)
Definition internal.h:108
struct timer_rec_s * timer
Definition internal.h:107
const char * event
Definition internal.h:95
void(* callback)(const char *event, xmlNode *msg)
Definition internal.h:98
enum cib_conn_type type
Definition cib_types.h:384
enum cib_state state
Definition cib_types.h:382
GList * notify_list
Definition cib_types.h:392
xmlNode * transaction
Definition cib_types.h:401
void * variant_opaque
Definition cib_types.h:389
cib_api_operations_t * cmds
Definition cib_types.h:399
enum cib_variant variant
Definition cib_types.h:385
char * user
Definition cib_types.h:403
int call_id
Definition cib_types.h:387
void(* op_callback)(const xmlNode *msg, int call_id, int rc, xmlNode *output)
Definition cib_types.h:395
cib_t * cib
Definition internal.h:115
guint ref
Definition internal.h:114
Wrappers for and extensions to libxml2.
void free_xml(xmlNode *child)
Definition xml.c:867
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition xml.c:720
#define PCMK_XA_VERSION
Definition xml_names.h:439
#define PCMK__XE_CIB_TRANSACTION
#define PCMK__XA_SCHEMA