pacemaker  2.1.3-ea053b43a
Scalable High-Availability cluster resource manager
cib_remote.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2022 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 
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <stdarg.h>
16 #include <string.h>
17 #include <netdb.h>
18 #include <termios.h>
19 #include <sys/socket.h>
20 
21 #include <glib.h>
22 
23 #include <crm/crm.h>
24 #include <crm/cib/internal.h>
25 #include <crm/msg_xml.h>
27 #include <crm/common/mainloop.h>
30 
31 #ifdef HAVE_GNUTLS_GNUTLS_H
32 
33 # include <gnutls/gnutls.h>
34 
35 # define TLS_HANDSHAKE_TIMEOUT_MS 5000
36 
37 static gnutls_anon_client_credentials_t anon_cred_c;
38 static gboolean remote_gnutls_credentials_init = FALSE;
39 
40 #else
41 
42 typedef void gnutls_session_t;
43 
44 #endif // HAVE_GNUTLS_GNUTLS_H
45 
46 #include <arpa/inet.h>
47 
48 #define DH_BITS 1024
49 
50 typedef struct cib_remote_opaque_s {
51  int flags;
52  int socket;
53  int port;
54  char *server;
55  char *user;
56  char *passwd;
57  gboolean encrypted;
58  pcmk__remote_t command;
59  pcmk__remote_t callback;
60  pcmk__output_t *out;
61 
63 
64 void cib_remote_connection_destroy(gpointer user_data);
65 int cib_remote_callback_dispatch(gpointer user_data);
66 int cib_remote_command_dispatch(gpointer user_data);
67 int cib_remote_signon(cib_t * cib, const char *name, enum cib_conn_type type);
68 int cib_remote_signoff(cib_t * cib);
69 int cib_remote_free(cib_t * cib);
70 
71 int cib_remote_perform_op(cib_t * cib, const char *op, const char *host, const char *section,
72  xmlNode * data, xmlNode ** output_data, int call_options,
73  const char *name);
74 
75 static int
76 cib_remote_inputfd(cib_t * cib)
77 {
78  cib_remote_opaque_t *private = cib->variant_opaque;
79 
80  return private->callback.tcp_socket;
81 }
82 
83 static int
84 cib_remote_set_connection_dnotify(cib_t * cib, void (*dnotify) (gpointer user_data))
85 {
86  return -EPROTONOSUPPORT;
87 }
88 
89 static int
90 cib_remote_register_notification(cib_t * cib, const char *callback, int enabled)
91 {
92  xmlNode *notify_msg = create_xml_node(NULL, "cib_command");
93  cib_remote_opaque_t *private = cib->variant_opaque;
94 
96  crm_xml_add(notify_msg, F_CIB_NOTIFY_TYPE, callback);
97  crm_xml_add_int(notify_msg, F_CIB_NOTIFY_ACTIVATE, enabled);
98  pcmk__remote_send_xml(&private->callback, notify_msg);
99  free_xml(notify_msg);
100  return pcmk_ok;
101 }
102 
103 cib_t *
104 cib_remote_new(const char *server, const char *user, const char *passwd, int port,
105  gboolean encrypted)
106 {
107  cib_remote_opaque_t *private = NULL;
108  cib_t *cib = cib_new_variant();
109 
110  if (cib == NULL) {
111  return NULL;
112  }
113 
114  private = calloc(1, sizeof(cib_remote_opaque_t));
115 
116  if (private == NULL) {
117  free(cib);
118  return NULL;
119  }
120 
121  cib->variant = cib_remote;
122  cib->variant_opaque = private;
123 
124  pcmk__str_update(&private->server, server);
125  pcmk__str_update(&private->user, user);
126  pcmk__str_update(&private->passwd, passwd);
127 
128  private->port = port;
129  private->encrypted = encrypted;
130 
131  /* assign variant specific ops */
133  cib->cmds->signon = cib_remote_signon;
135  cib->cmds->free = cib_remote_free;
136  cib->cmds->inputfd = cib_remote_inputfd;
137 
138  cib->cmds->register_notification = cib_remote_register_notification;
139  cib->cmds->set_connection_dnotify = cib_remote_set_connection_dnotify;
140 
141  return cib;
142 }
143 
144 static int
145 cib_tls_close(cib_t * cib)
146 {
147  cib_remote_opaque_t *private = cib->variant_opaque;
148 
149 #ifdef HAVE_GNUTLS_GNUTLS_H
150  if (private->encrypted) {
151  if (private->command.tls_session) {
152  gnutls_bye(*(private->command.tls_session), GNUTLS_SHUT_RDWR);
153  gnutls_deinit(*(private->command.tls_session));
154  gnutls_free(private->command.tls_session);
155  }
156 
157  if (private->callback.tls_session) {
158  gnutls_bye(*(private->callback.tls_session), GNUTLS_SHUT_RDWR);
159  gnutls_deinit(*(private->callback.tls_session));
160  gnutls_free(private->callback.tls_session);
161  }
162  private->command.tls_session = NULL;
163  private->callback.tls_session = NULL;
164  if (remote_gnutls_credentials_init) {
165  gnutls_anon_free_client_credentials(anon_cred_c);
166  gnutls_global_deinit();
167  remote_gnutls_credentials_init = FALSE;
168  }
169  }
170 #endif
171 
172  if (private->command.tcp_socket) {
173  shutdown(private->command.tcp_socket, SHUT_RDWR); /* no more receptions */
174  close(private->command.tcp_socket);
175  }
176  if (private->callback.tcp_socket) {
177  shutdown(private->callback.tcp_socket, SHUT_RDWR); /* no more receptions */
178  close(private->callback.tcp_socket);
179  }
180  private->command.tcp_socket = 0;
181  private->callback.tcp_socket = 0;
182 
183  free(private->command.buffer);
184  free(private->callback.buffer);
185  private->command.buffer = NULL;
186  private->callback.buffer = NULL;
187 
188  return 0;
189 }
190 
191 static int
192 cib_tls_signon(cib_t *cib, pcmk__remote_t *connection, gboolean event_channel)
193 {
194  cib_remote_opaque_t *private = cib->variant_opaque;
195  int rc;
196 
197  xmlNode *answer = NULL;
198  xmlNode *login = NULL;
199 
200  static struct mainloop_fd_callbacks cib_fd_callbacks = { 0, };
201 
202  cib_fd_callbacks.dispatch =
204  cib_fd_callbacks.destroy = cib_remote_connection_destroy;
205 
206  connection->tcp_socket = -1;
207 #ifdef HAVE_GNUTLS_GNUTLS_H
208  connection->tls_session = NULL;
209 #endif
210  rc = pcmk__connect_remote(private->server, private->port, 0, NULL,
211  &(connection->tcp_socket), NULL, NULL);
212  if (rc != pcmk_rc_ok) {
213  crm_info("Remote connection to %s:%d failed: %s " CRM_XS " rc=%d",
214  private->server, private->port, pcmk_rc_str(rc), rc);
215  return -ENOTCONN;
216  }
217 
218  if (private->encrypted) {
219  /* initialize GnuTls lib */
220 #ifdef HAVE_GNUTLS_GNUTLS_H
221  if (remote_gnutls_credentials_init == FALSE) {
222  crm_gnutls_global_init();
223  gnutls_anon_allocate_client_credentials(&anon_cred_c);
224  remote_gnutls_credentials_init = TRUE;
225  }
226 
227  /* bind the socket to GnuTls lib */
228  connection->tls_session = pcmk__new_tls_session(connection->tcp_socket,
229  GNUTLS_CLIENT,
230  GNUTLS_CRD_ANON,
231  anon_cred_c);
232  if (connection->tls_session == NULL) {
233  cib_tls_close(cib);
234  return -1;
235  }
236 
237  if (pcmk__tls_client_handshake(connection, TLS_HANDSHAKE_TIMEOUT_MS)
238  != pcmk_rc_ok) {
239  crm_err("Session creation for %s:%d failed", private->server, private->port);
240 
241  gnutls_deinit(*connection->tls_session);
242  gnutls_free(connection->tls_session);
243  connection->tls_session = NULL;
244  cib_tls_close(cib);
245  return -1;
246  }
247 #else
248  return -EPROTONOSUPPORT;
249 #endif
250  }
251 
252  /* login to server */
253  login = create_xml_node(NULL, "cib_command");
254  crm_xml_add(login, "op", "authenticate");
255  crm_xml_add(login, "user", private->user);
256  crm_xml_add(login, "password", private->passwd);
257  crm_xml_add(login, "hidden", "password");
258 
259  pcmk__remote_send_xml(connection, login);
260  free_xml(login);
261 
262  rc = pcmk_ok;
263  if (pcmk__read_remote_message(connection, -1) == ENOTCONN) {
264  rc = -ENOTCONN;
265  }
266 
267  answer = pcmk__remote_message_xml(connection);
268 
269  crm_log_xml_trace(answer, "Reply");
270  if (answer == NULL) {
271  rc = -EPROTO;
272 
273  } else {
274  /* grab the token */
275  const char *msg_type = crm_element_value(answer, F_CIB_OPERATION);
276  const char *tmp_ticket = crm_element_value(answer, F_CIB_CLIENTID);
277 
278  if (!pcmk__str_eq(msg_type, CRM_OP_REGISTER, pcmk__str_casei)) {
279  crm_err("Invalid registration message: %s", msg_type);
280  rc = -EPROTO;
281 
282  } else if (tmp_ticket == NULL) {
283  rc = -EPROTO;
284 
285  } else {
286  connection->token = strdup(tmp_ticket);
287  }
288  }
289  free_xml(answer);
290  answer = NULL;
291 
292  if (rc != 0) {
293  cib_tls_close(cib);
294  return rc;
295  }
296 
297  crm_trace("remote client connection established");
298  connection->source = mainloop_add_fd("cib-remote", G_PRIORITY_HIGH,
299  connection->tcp_socket, cib,
300  &cib_fd_callbacks);
301  return rc;
302 }
303 
304 void
305 cib_remote_connection_destroy(gpointer user_data)
306 {
307  crm_err("Connection destroyed");
308 #ifdef HAVE_GNUTLS_GNUTLS_H
309  cib_tls_close(user_data);
310 #endif
311  return;
312 }
313 
314 int
315 cib_remote_command_dispatch(gpointer user_data)
316 {
317  int rc;
318  cib_t *cib = user_data;
319  cib_remote_opaque_t *private = cib->variant_opaque;
320 
321  rc = pcmk__read_remote_message(&private->command, -1);
322 
323  free(private->command.buffer);
324  private->command.buffer = NULL;
325  crm_err("received late reply for remote cib connection, discarding");
326 
327  if (rc == ENOTCONN) {
328  return -1;
329  }
330  return 0;
331 }
332 
333 int
334 cib_remote_callback_dispatch(gpointer user_data)
335 {
336  int rc;
337  cib_t *cib = user_data;
338  cib_remote_opaque_t *private = cib->variant_opaque;
339 
340  xmlNode *msg = NULL;
341 
342  crm_info("Message on callback channel");
343 
344  rc = pcmk__read_remote_message(&private->callback, -1);
345 
346  msg = pcmk__remote_message_xml(&private->callback);
347  while (msg) {
348  const char *type = crm_element_value(msg, F_TYPE);
349 
350  crm_trace("Activating %s callbacks...", type);
351 
352  if (pcmk__str_eq(type, T_CIB, pcmk__str_casei)) {
353  cib_native_callback(cib, msg, 0, 0);
354 
355  } else if (pcmk__str_eq(type, T_CIB_NOTIFY, pcmk__str_casei)) {
356  g_list_foreach(cib->notify_list, cib_native_notify, msg);
357 
358  } else {
359  crm_err("Unknown message type: %s", type);
360  }
361 
362  free_xml(msg);
363  msg = pcmk__remote_message_xml(&private->callback);
364  }
365 
366  if (rc == ENOTCONN) {
367  return -1;
368  }
369 
370  return 0;
371 }
372 
373 int
374 cib_remote_signon(cib_t * cib, const char *name, enum cib_conn_type type)
375 {
376  int rc = pcmk_ok;
377  cib_remote_opaque_t *private = cib->variant_opaque;
378 
379  if (private->passwd == NULL) {
380  if (private->out == NULL) {
381  /* If no pcmk__output_t is set, just assume that a text prompt
382  * is good enough.
383  */
384  pcmk__text_prompt("Password", false, &(private->passwd));
385  } else {
386  private->out->prompt("Password", false, &(private->passwd));
387  }
388  }
389 
390  if (private->server == NULL || private->user == NULL) {
391  rc = -EINVAL;
392  }
393 
394  if (rc == pcmk_ok) {
395  rc = cib_tls_signon(cib, &(private->command), FALSE);
396  }
397 
398  if (rc == pcmk_ok) {
399  rc = cib_tls_signon(cib, &(private->callback), TRUE);
400  }
401 
402  if (rc == pcmk_ok) {
403  xmlNode *hello =
404  cib_create_op(0, private->callback.token, CRM_OP_REGISTER, NULL, NULL, NULL, 0, NULL);
406  pcmk__remote_send_xml(&private->command, hello);
407  free_xml(hello);
408  }
409 
410  if (rc == pcmk_ok) {
411  crm_info("Opened connection to %s:%d for %s",
412  private->server, private->port, name);
414  cib->type = cib_command;
415 
416  } else {
417  crm_info("Connection to %s:%d for %s failed: %s\n",
418  private->server, private->port, name, pcmk_strerror(rc));
419  }
420 
421  return rc;
422 }
423 
424 int
426 {
427  int rc = pcmk_ok;
428 
429  /* cib_remote_opaque_t *private = cib->variant_opaque; */
430 
431  crm_debug("Disconnecting from the CIB manager");
432 #ifdef HAVE_GNUTLS_GNUTLS_H
433  cib_tls_close(cib);
434 #endif
435 
436  cib->state = cib_disconnected;
437  cib->type = cib_no_connection;
438 
439  return rc;
440 }
441 
442 int
444 {
445  int rc = pcmk_ok;
446 
447  crm_warn("Freeing CIB");
448  if (cib->state != cib_disconnected) {
449  rc = cib_remote_signoff(cib);
450  if (rc == pcmk_ok) {
451  cib_remote_opaque_t *private = cib->variant_opaque;
452 
453  free(private->server);
454  free(private->user);
455  free(private->passwd);
456  free(cib->cmds);
457  free(private);
458  free(cib);
459  }
460  }
461 
462  return rc;
463 }
464 
465 int
466 cib_remote_perform_op(cib_t * cib, const char *op, const char *host, const char *section,
467  xmlNode * data, xmlNode ** output_data, int call_options, const char *name)
468 {
469  int rc;
470  int remaining_time = 0;
471  time_t start_time;
472 
473  xmlNode *op_msg = NULL;
474  xmlNode *op_reply = NULL;
475 
476  cib_remote_opaque_t *private = cib->variant_opaque;
477 
478  if (cib->state == cib_disconnected) {
479  return -ENOTCONN;
480  }
481 
482  if (output_data != NULL) {
483  *output_data = NULL;
484  }
485 
486  if (op == NULL) {
487  crm_err("No operation specified");
488  return -EINVAL;
489  }
490 
491  cib->call_id++;
492  if (cib->call_id < 1) {
493  cib->call_id = 1;
494  }
495 
496  op_msg =
497  cib_create_op(cib->call_id, private->callback.token, op, host, section, data, call_options,
498  NULL);
499  if (op_msg == NULL) {
500  return -EPROTO;
501  }
502 
503  crm_trace("Sending %s message to the CIB manager", op);
504  if (!(call_options & cib_sync_call)) {
505  pcmk__remote_send_xml(&private->callback, op_msg);
506  } else {
507  pcmk__remote_send_xml(&private->command, op_msg);
508  }
509  free_xml(op_msg);
510 
511  if ((call_options & cib_discard_reply)) {
512  crm_trace("Discarding reply");
513  return pcmk_ok;
514 
515  } else if (!(call_options & cib_sync_call)) {
516  return cib->call_id;
517  }
518 
519  crm_trace("Waiting for a synchronous reply");
520 
521  start_time = time(NULL);
522  remaining_time = cib->call_timeout ? cib->call_timeout : 60;
523 
524  rc = pcmk_rc_ok;
525  while (remaining_time > 0 && (rc != ENOTCONN)) {
526  int reply_id = -1;
527  int msg_id = cib->call_id;
528 
529  rc = pcmk__read_remote_message(&private->command,
530  remaining_time * 1000);
531  op_reply = pcmk__remote_message_xml(&private->command);
532 
533  if (!op_reply) {
534  break;
535  }
536 
537  crm_element_value_int(op_reply, F_CIB_CALLID, &reply_id);
538 
539  if (reply_id == msg_id) {
540  break;
541 
542  } else if (reply_id < msg_id) {
543  crm_debug("Received old reply: %d (wanted %d)", reply_id, msg_id);
544  crm_log_xml_trace(op_reply, "Old reply");
545 
546  } else if ((reply_id - 10000) > msg_id) {
547  /* wrap-around case */
548  crm_debug("Received old reply: %d (wanted %d)", reply_id, msg_id);
549  crm_log_xml_trace(op_reply, "Old reply");
550  } else {
551  crm_err("Received a __future__ reply:" " %d (wanted %d)", reply_id, msg_id);
552  }
553 
554  free_xml(op_reply);
555  op_reply = NULL;
556 
557  /* wasn't the right reply, try and read some more */
558  remaining_time = time(NULL) - start_time;
559  }
560 
561  /* if(IPC_ISRCONN(native->command_channel) == FALSE) { */
562  /* crm_err("The CIB manager disconnected: %d", */
563  /* native->command_channel->ch_status); */
564  /* cib->state = cib_disconnected; */
565  /* } */
566 
567  if (rc == ENOTCONN) {
568  crm_err("Disconnected while waiting for reply.");
569  return -ENOTCONN;
570  } else if (op_reply == NULL) {
571  crm_err("No reply message - empty");
572  return -ENOMSG;
573  }
574 
575  crm_trace("Synchronous reply received");
576 
577  /* Start processing the reply... */
578  if (crm_element_value_int(op_reply, F_CIB_RC, &rc) != 0) {
579  rc = -EPROTO;
580  }
581 
582  if (rc == -pcmk_err_diff_resync) {
583  /* This is an internal value that clients do not and should not care about */
584  rc = pcmk_ok;
585  }
586 
587  if (rc == pcmk_ok || rc == -EPERM) {
588  crm_log_xml_debug(op_reply, "passed");
589 
590  } else {
591 /* } else if(rc == -ETIME) { */
592  crm_err("Call failed: %s", pcmk_strerror(rc));
593  crm_log_xml_warn(op_reply, "failed");
594  }
595 
596  if (output_data == NULL) {
597  /* do nothing more */
598 
599  } else if (!(call_options & cib_discard_reply)) {
600  xmlNode *tmp = get_message_xml(op_reply, F_CIB_CALLDATA);
601 
602  if (tmp == NULL) {
603  crm_trace("No output in reply to \"%s\" command %d", op, cib->call_id - 1);
604  } else {
605  *output_data = copy_xml(tmp);
606  }
607  }
608 
609  free_xml(op_reply);
610 
611  return rc;
612 }
613 
614 void
616 {
617  cib_remote_opaque_t *private;
618 
619  if (cib->variant != cib_remote) {
620  return;
621  }
622 
623  private = cib->variant_opaque;
624  private->out = out;
625 }
pcmk__cpg_host_t host
Definition: cpg.c:49
void cib__set_output(cib_t *cib, pcmk__output_t *out)
Definition: cib_remote.c:615
int pcmk__remote_send_xml(pcmk__remote_t *remote, xmlNode *msg)
Definition: remote.c:488
A dumping ground.
#define F_TYPE
Definition: msg_xml.h:69
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: messages.c:154
const char * pcmk_strerror(int rc)
Definition: results.c:58
char data[0]
Definition: cpg.c:55
mainloop_io_t * mainloop_add_fd(const char *name, int priority, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks)
Definition: mainloop.c:976
void cib_remote_connection_destroy(gpointer user_data)
Definition: cib_remote.c:305
int call_timeout
Definition: cib_types.h:140
void void void void void pcmk__text_prompt(const char *prompt, bool echo, char **dest)
Definition: output_text.c:390
const char * name
Definition: cib.c:24
void(* destroy)(gpointer userdata)
Destroy function for mainloop file descriptor client data.
Definition: mainloop.h:145
int(* signoff)(cib_t *cib)
Definition: cib_types.h:76
int cib_remote_command_dispatch(gpointer user_data)
Definition: cib_remote.c:315
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: nvpair.c:431
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:323
int(* inputfd)(cib_t *cib)
Definition: cib_types.h:89
enum crm_ais_msg_types type
Definition: cpg.c:48
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:370
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:565
Wrappers for and extensions to glib mainloop.
#define CRM_OP_REGISTER
Definition: crm.h:146
#define F_CIB_NOTIFY_ACTIVATE
Definition: internal.h:55
xmlNode * cib_create_op(int call_id, const char *token, const char *op, const char *host, const char *section, xmlNode *data, int call_options, const char *user_name)
Definition: cib_utils.c:437
void cib_native_notify(gpointer data, gpointer user_data)
Definition: cib_utils.c:518
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:830
int(* dispatch)(gpointer userdata)
Dispatch function for mainloop file descriptor with data ready.
Definition: mainloop.h:138
cib_t * cib_new_variant(void)
Definition: cib_client.c:352
int(* set_connection_dnotify)(cib_t *cib, void(*dnotify)(gpointer user_data))
Definition: cib_types.h:87
#define crm_warn(fmt, args...)
Definition: logging.h:359
Formatted output for pacemaker tools.
cib_api_operations_t * cmds
Definition: cib_types.h:147
#define crm_debug(fmt, args...)
Definition: logging.h:363
int cib_remote_callback_dispatch(gpointer user_data)
Definition: cib_remote.c:334
#define F_CIB_RC
Definition: internal.h:41
cib_conn_type
Definition: cib_types.h:42
int(* signon)(cib_t *cib, const char *name, enum cib_conn_type type)
Definition: cib_types.h:73
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
#define F_CIB_OPERATION
Definition: internal.h:37
void gnutls_session_t
Definition: cib_remote.c:42
#define F_CIB_CLIENTNAME
Definition: internal.h:53
#define crm_trace(fmt, args...)
Definition: logging.h:364
int pcmk__connect_remote(const char *host, int port, int timeout_ms, int *timer_id, int *sock_fd, void *userdata, void(*callback)(void *userdata, int rc, int sock))
Definition: remote.c:1063
#define crm_log_xml_debug(xml, text)
Definition: logging.h:371
void pcmk__str_update(char **str, const char *value)
Definition: strings.c:1188
struct cib_remote_opaque_s cib_remote_opaque_t
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:696
#define crm_log_xml_warn(xml, text)
Definition: logging.h:368
int cib_remote_free(cib_t *cib)
Definition: cib_remote.c:443
void free_xml(xmlNode *child)
Definition: xml.c:824
int(* register_notification)(cib_t *cib, const char *callback, int enabled)
Definition: cib_types.h:119
#define T_CIB
Definition: internal.h:63
void * variant_opaque
Definition: cib_types.h:141
mainloop_io_t * source
Definition: ipc_internal.h:105
#define F_CIB_NOTIFY_TYPE
Definition: internal.h:54
#define T_CIB_NOTIFY
Definition: internal.h:64
#define CRM_XS
Definition: logging.h:55
#define pcmk_err_diff_resync
Definition: results.h:77
#define F_CIB_CALLDATA
Definition: internal.h:36
#define crm_err(fmt, args...)
Definition: logging.h:358
This structure contains everything that makes up a single output formatter.
enum cib_variant variant
Definition: cib_types.h:137
#define pcmk_ok
Definition: results.h:68
void cib_native_callback(cib_t *cib, xmlNode *msg, int call_id, int rc)
Definition: cib_utils.c:470
int call_id
Definition: cib_types.h:139
#define F_CIB_CLIENTID
Definition: internal.h:33
#define crm_log_xml_trace(xml, text)
Definition: logging.h:372
#define F_CIB_CALLID
Definition: internal.h:35
int cib_remote_perform_op(cib_t *cib, const char *op, const char *host, const char *section, xmlNode *data, xmlNode **output_data, int call_options, const char *name)
Definition: cib_remote.c:466
int cib_remote_signoff(cib_t *cib)
Definition: cib_remote.c:425
int pcmk__read_remote_message(pcmk__remote_t *remote, int timeout_ms)
Definition: remote.c:791
cib_t * cib_remote_new(const char *server, const char *user, const char *passwd, int port, gboolean encrypted)
Definition: cib_remote.c:104
enum cib_conn_type type
Definition: cib_types.h:136
enum cib_state state
Definition: cib_types.h:135
GList * notify_list
Definition: cib_types.h:144
int(* free)(cib_t *cib)
Definition: cib_types.h:77
#define crm_info(fmt, args...)
Definition: logging.h:361
uint64_t flags
Definition: remote.c:149
xmlNode * pcmk__remote_message_xml(pcmk__remote_t *remote)
Definition: remote.c:540
void * delegate_fn
Definition: cib_types.h:142
int cib_remote_signon(cib_t *cib, const char *name, enum cib_conn_type type)
Definition: cib_remote.c:374