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