13 #include <libxml/tree.h> 48 unsigned int message_timeout_ms;
50 node_info_t node_info;
75 if (
data->rc == ECONNRESET) {
76 out->
err(out,
"error: Lost connection to %s",
88 out->
err(out,
"error: Bad reply from %s: %s",
112 const void *event_data,
119 rc = validate_reply_event(
data, api, event_type, status);
127 out->
err(out,
"error: Unexpected reply type '%s' from controller",
153 const void *event_data,
158 int rc = validate_reply_event(
data, api, event_type, status);
167 out->
err(out,
"error: Unexpected reply type '%s' from pacemakerd",
190 void *event_data,
void *user_data)
192 data_t *
data = (data_t *) user_data;
196 int rc = validate_controld_reply(
data, controld_api, event_type, status,
227 data_t *
data = (data_t *) user_data;
231 int rc = validate_controld_reply(
data, controld_api, event_type, status,
256 crm_exit_t status,
void *event_data,
void *user_data)
258 data_t *
data = (data_t *) user_data;
263 int rc = validate_controld_reply(
data, controld_api, event_type, status,
273 out->
err(out,
"Node is not known to cluster");
286 if (
data->show_output) {
311 void *event_data,
void *user_data)
313 data_t *
data = user_data;
317 int rc = validate_pcmkd_reply(
data, pacemakerd_api, event_type, status,
330 if (!
data->show_output) {
335 out->
message(out,
"pacemakerd-health",
339 out->
message(out,
"pacemakerd-health",
341 "query failed", time(NULL));
355 out->
err(out,
"error: Could not connect to %s: %s",
376 out->
err(out,
"error: Could not connect to %s: %s",
404 uint64_t start_nsec = qb_util_nano_current_get();
405 uint64_t end_nsec = start_nsec;
406 uint64_t elapsed_ms = 0;
407 uint64_t remaining_ms =
data->message_timeout_ms;
409 while (remaining_ms > 0) {
418 out->
err(out,
"error: Failed to poll %s API%s%s: %s",
427 if (
data->rc != EAGAIN) {
431 end_nsec = qb_util_nano_current_get();
432 elapsed_ms = (end_nsec - start_nsec) / QB_TIME_NS_IN_MSEC;
433 remaining_ms =
data->message_timeout_ms - elapsed_ms;
437 "error: Timed out after %ums waiting for reply from %s API%s%s",
439 (on_node != NULL)?
" on " :
"", pcmk__s(on_node,
""));
460 unsigned int message_timeout_ms)
465 .message_timeout_ms = message_timeout_ms,
470 if (message_timeout_ms == 0) {
474 controller_status_event_cb, dispatch_type,
477 if (controld_api != NULL) {
480 out->
err(out,
"error: Could not ping controller API on %s: %s",
486 poll_until_reply(&
data, controld_api, pcmk__s(node_name,
"DC"));
498 unsigned int message_timeout_ms)
530 unsigned int message_timeout_ms)
535 .message_timeout_ms = message_timeout_ms,
540 if (message_timeout_ms == 0) {
544 designated_controller_event_cb, dispatch_type,
547 if (controld_api != NULL) {
550 out->
err(out,
"error: Could not ping controller API on DC: %s",
556 poll_until_reply(&
data, controld_api,
"DC");
617 char **uuid,
char **state,
bool *have_quorum,
618 bool *is_remote,
bool show_output,
619 unsigned int message_timeout_ms)
623 .show_output = show_output,
625 .message_timeout_ms = message_timeout_ms,
627 .id = (node_id == NULL)? 0 : *node_id,
628 .node_name = node_name,
636 if (node_name != NULL) {
646 if (message_timeout_ms == 0) {
650 dispatch_type,
false);
652 if (controld_api != NULL) {
654 (node_id != NULL)? *node_id : 0);
658 "error: Could not send request to controller API on local " 664 poll_until_reply(&
data, controld_api,
"local node");
674 if (node_id != NULL) {
675 *node_id =
data.node_info.id;
677 if (have_quorum != NULL) {
678 *have_quorum =
data.node_info.have_quorum;
680 if (is_remote != NULL) {
681 *is_remote =
data.node_info.is_remote;
690 char **uuid,
char **state,
bool *have_quorum,
691 bool *is_remote,
bool show_output,
692 unsigned int message_timeout_ms)
707 have_quorum, is_remote, show_output,
738 unsigned int message_timeout_ms,
bool show_output,
743 .show_output = show_output,
745 .message_timeout_ms = message_timeout_ms,
751 if (message_timeout_ms == 0) {
755 pacemakerd_event_cb, dispatch_type,
true);
757 if (pacemakerd_api != NULL) {
760 out->
err(out,
"error: Could not ping launcher API: %s",
766 poll_until_reply(&
data, pacemakerd_api, NULL);
773 out->
message(out,
"pacemakerd-health",
774 NULL,
data.pcmkd_state, NULL, time(NULL));
778 *state =
data.pcmkd_state;
786 unsigned int message_timeout_ms)
809 gboolean bash_export;
813 remote_node_print_helper(xmlNode *
result,
void *user_data)
815 struct node_data *
data = user_data;
831 gboolean bash_export)
833 xmlNode *xml_node = NULL;
839 struct node_data
data = {
842 .bash_export = bash_export
847 if (!pcmk__str_empty(node_types) && strstr(node_types,
"all")) {
851 if (pcmk__str_empty(node_types) || strstr(node_types,
"cluster")) {
853 data.type =
"cluster";
855 remote_node_print_helper, &
data);
858 if (pcmk__str_empty(node_types) || strstr(node_types,
"guest")) {
859 data.field =
"value";
862 remote_node_print_helper, &
data);
867 data.type =
"remote";
869 remote_node_print_helper, &
data);
874 if (
data.found == 0) {
875 out->
info(out,
"No nodes configured");
void(* end_list)(pcmk__output_t *out)
int pcmk__query_node_info(pcmk__output_t *out, uint32_t *node_id, char **node_name, char **uuid, char **state, bool *have_quorum, bool *is_remote, bool show_output, unsigned int message_timeout_ms)
struct pcmk_controld_api_reply_t::@1::@4 ping
union pcmk_controld_api_reply_t::@1 data
enum pcmk_controld_api_reply reply_type
int pcmk_designated_controller(xmlNodePtr *xml, unsigned int message_timeout_ms)
Get and output designated controller node name.
const char * pcmk__pcmkd_api_reply2str(enum pcmk_pacemakerd_api_reply reply)
int pcmk__designated_controller(pcmk__output_t *out, unsigned int message_timeout_ms)
int pcmk_connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type)
Connect to a Pacemaker daemon via IPC.
int cib__signon_query(pcmk__output_t *out, cib_t **cib, xmlNode **cib_object)
int(* message)(pcmk__output_t *out, const char *message_id,...)
const char * host_from
Name of node that sent reply.
int pcmk_controld_api_ping(pcmk_ipc_api_t *api, const char *node_name)
Ask the controller for status.
const char * pcmk__controld_api_reply2str(enum pcmk_controld_api_reply reply)
int pcmk_new_ipc_api(pcmk_ipc_api_t **api, enum pcmk_ipc_server server)
Create a new object for using Pacemaker daemon IPC.
int pcmk_controller_status(xmlNodePtr *xml, const char *node_name, unsigned int message_timeout_ms)
Get and output controller status.
void pcmk_dispatch_ipc(pcmk_ipc_api_t *api)
Dispatch available messages on an IPC connection (without main loop)
int pcmk_query_node_info(xmlNodePtr *xml, uint32_t *node_id, char **node_name, char **uuid, char **state, bool *have_quorum, bool *is_remote, bool show_output, unsigned int message_timeout_ms)
Get and optionally output node info corresponding to a node ID from the controller.
enum crm_exit_e crm_exit_t
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
enum crm_ais_msg_types type
struct pcmk_pacemakerd_api_reply_t::@5::@6 ping
pcmk_pacemakerd_api_reply
Possible types of pacemakerd replies.
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
int pcmk_poll_ipc(const pcmk_ipc_api_t *api, int timeout_ms)
Check whether an IPC connection has data available (without main loop)
union pcmk_pacemakerd_api_reply_t::@5 data
Caller will poll and dispatch IPC.
enum pcmk_pacemakerd_api_reply reply_type
Formatted output for pacemaker tools.
#define PCMK__XP_GUEST_NODE_CONFIG
pcmk_ipc_server
Available IPC interfaces.
const char * crm_exit_str(crm_exit_t exit_code)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml)
int(*) int(*) void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
void pcmk__register_lib_messages(pcmk__output_t *out)
#define PCMK__XP_REMOTE_NODE_CONFIG
void pcmk__str_update(char **str, const char *value)
Wrappers for and extensions to libxml2.
int pcmk_list_nodes(xmlNodePtr *xml, const char *node_types)
Get nodes list.
IPC commands for Pacemakerd.
void free_xml(xmlNode *child)
void(* pcmk_ipc_callback_t)(pcmk_ipc_api_t *api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data, void *user_data)
Callback function type for Pacemaker daemon IPC APIs.
IPC commands for Pacemaker controller.
int pcmk__list_nodes(pcmk__output_t *out, const char *node_types, gboolean bash_export)
int pcmk_pacemakerd_api_ping(pcmk_ipc_api_t *api, const char *ipc_name)
pcmk_ipc_dispatch
How IPC replies should be dispatched.
int pcmk__controller_status(pcmk__output_t *out, const char *node_name, unsigned int message_timeout_ms)
pcmk_ipc_event
Possible event types that an IPC event callback can be called for.
Termination of IPC connection.
pcmk__action_result_t result
struct pcmk_controld_api_reply_t::@1::@2 node_info
Sending a command will wait for any reply.
void pcmk_free_ipc_api(pcmk_ipc_api_t *api)
Free the contents of an IPC API object.
int pcmk__pacemakerd_status(pcmk__output_t *out, const char *ipc_name, unsigned int message_timeout_ms, bool show_output, enum pcmk_pacemakerd_state *state)
This structure contains everything that makes up a single output formatter.
const char * pcmk_ipc_name(const pcmk_ipc_api_t *api, bool for_log)
Get the IPC name used with an IPC API connection.
int pcmk__strcmp(const char *s1, const char *s2, uint32_t flags)
void(* begin_list)(pcmk__output_t *out, const char *singular_noun, const char *plural_noun, const char *format,...) G_GNUC_PRINTF(4
void crm_foreach_xpath_result(xmlNode *xml, const char *xpath, void(*helper)(xmlNode *, void *), void *user_data)
Run a supplied function for each result of an xpath search.
void pcmk__xml_output_finish(pcmk__output_t *out, xmlNodePtr *xml)
Daemon's reply to client IPC request.
int pcmk_pacemakerd_status(xmlNodePtr *xml, const char *ipc_name, unsigned int message_timeout_ms)
Get and output pacemakerd status.
#define PCMK__XP_MEMBER_NODE_CONFIG
int pcmk_controld_api_node_info(pcmk_ipc_api_t *api, uint32_t nodeid)
Send a "node info" controller operation.
void pcmk_register_ipc_callback(pcmk_ipc_api_t *api, pcmk_ipc_callback_t cb, void *user_data)
Register a callback for IPC API events.
pcmk_controld_api_reply
Possible types of controller replies.