18 #include <libxml/tree.h> 27 struct controld_api_private_s {
29 unsigned int replies_expected;
32 static xmlNode *create_hello_message(
const char *uuid,
const char *client_name,
33 const char *major_version,
34 const char *minor_version);
67 struct controld_api_private_s *
private = NULL;
69 api->
api_data = calloc(1,
sizeof(
struct controld_api_private_s));
83 private->client_uuid = pcmk__getpid_s();
95 free(((
struct controld_api_private_s *)
data)->client_uuid);
106 struct controld_api_private_s *
private = api->
api_data;
111 hello = create_hello_message(private->client_uuid, client_name,
117 crm_info(
"Could not send IPC hello to %s: %s " QB_XS
" rc=%s",
129 if (msg_data == NULL) {
132 data->data.node_info.have_quorum =
134 data->data.node_info.is_remote =
153 if (msg_data == NULL) {
178 node_info->
id = id_ll;
182 data->data.nodes = g_list_prepend(
data->data.nodes, node_info);
204 struct controld_api_private_s *
private = api->
api_data;
206 xmlNode *wrapper = NULL;
207 xmlNode *msg_data = NULL;
208 const char *value = NULL;
218 return private->replies_expected > 0;
221 if (private->replies_expected > 0) {
222 private->replies_expected--;
234 crm_trace(
"Received a reply that was marked as a request " 235 "(bug unless sent by a controller <3.0.0)");
238 crm_info(
"Unrecognizable message from controller: " 239 "invalid message type '%s'", pcmk__s(value,
""));
245 crm_info(
"Unrecognizable message from controller: no reference");
251 if (pcmk__str_empty(value)) {
252 crm_info(
"Unrecognizable message from controller: no command name");
269 set_node_info_data(&reply_data, msg_data);
276 set_ping_data(&reply_data, msg_data);
279 set_nodes_data(&reply_data, msg_data);
282 crm_info(
"Unrecognizable message from controller: unknown command '%s'",
292 g_list_free_full(reply_data.
data.
nodes, free);
325 create_controller_request(
const pcmk_ipc_api_t *api,
const char *op,
326 const char *node, xmlNode *msg_data)
328 struct controld_api_private_s *
private = NULL;
329 const char *sys_to = NULL;
330 char *sender_system = NULL;
331 xmlNode *request = NULL;
352 send_controller_request(
pcmk_ipc_api_t *api,
const xmlNode *request,
353 bool reply_is_expected)
358 if (reply_is_expected) {
359 struct controld_api_private_s *
private = api->
api_data;
361 private->replies_expected++;
367 create_reprobe_message_data(
const char *target_node,
const char *router_node)
373 if ((router_node != NULL) && !pcmk__str_eq(router_node, target_node,
pcmk__str_casei)) {
391 const char *router_node)
400 if (router_node == NULL) {
401 router_node = target_node;
403 crm_debug(
"Sending %s IPC request to reprobe %s via %s",
404 pcmk_ipc_name(api,
true), pcmk__s(target_node,
"local node"),
405 pcmk__s(router_node,
"local node"));
406 msg_data = create_reprobe_message_data(target_node, router_node);
407 request = create_controller_request(api,
CRM_OP_REPROBE, router_node,
409 rc = send_controller_request(api, request,
true);
431 if (request == NULL) {
438 rc = send_controller_request(api, request,
true);
458 request = create_controller_request(api,
CRM_OP_PING, node_name, NULL);
459 if (request == NULL) {
462 rc = send_controller_request(api, request,
true);
483 if (request != NULL) {
484 rc = send_controller_request(api, request,
true);
493 const char *target_node,
const char *router_node,
494 bool cib_only,
const char *rsc_id,
495 const char *rsc_long_id,
const char *standard,
496 const char *provider,
const char *
type)
500 xmlNode *request, *msg_data, *xml_rsc, *params;
505 if (router_node == NULL) {
506 router_node = target_node;
516 "xxxxxxxx-xrsc-opxx-xcrm-resourcexxxx");
545 request = create_controller_request(api, op, router_node, msg_data);
546 rc = send_controller_request(api, request,
true);
569 const char *target_node,
const char *router_node,
570 const char *rsc_id,
const char *rsc_long_id,
571 const char *standard,
const char *provider,
574 crm_debug(
"Sending %s IPC request to fail %s (a.k.a. %s) on %s via %s",
575 pcmk_ipc_name(api,
true), pcmk__s(rsc_id,
"unknown resource"),
576 pcmk__s(rsc_long_id,
"no other names"),
577 pcmk__s(target_node,
"unspecified node"),
578 pcmk__s(router_node,
"unspecified node"));
580 router_node,
false, rsc_id, rsc_long_id,
581 standard, provider,
type);
602 const char *router_node,
603 const char *rsc_id,
const char *rsc_long_id,
604 const char *standard,
const char *provider,
605 const char *
type,
bool cib_only)
607 crm_debug(
"Sending %s IPC request to refresh %s (a.k.a. %s) on %s via %s",
608 pcmk_ipc_name(api,
true), pcmk__s(rsc_id,
"unknown resource"),
609 pcmk__s(rsc_long_id,
"no other names"),
610 pcmk__s(target_node,
"unspecified node"),
611 pcmk__s(router_node,
"unspecified node"));
613 router_node, cib_only, rsc_id, rsc_long_id,
614 standard, provider,
type);
627 struct controld_api_private_s *
private = api->
api_data;
629 return private->replies_expected;
637 create_hello_message(
const char *uuid,
const char *client_name,
638 const char *major_version,
const char *minor_version)
640 xmlNode *hello_node = NULL;
641 xmlNode *hello = NULL;
642 char *sender_system = NULL;
644 if (pcmk__str_empty(uuid) || pcmk__str_empty(client_name)
645 || pcmk__str_empty(major_version) || pcmk__str_empty(minor_version)) {
646 crm_err(
"Could not create IPC hello message from %s (UUID %s): " 647 "missing information",
648 client_name? client_name :
"unknown client",
649 uuid? uuid :
"unknown");
667 crm_err(
"Could not create IPC hello message from %s (UUID %s): " 668 "Request creation failed", client_name, uuid);
672 crm_trace(
"Created hello message from %s (UUID %s)", client_name, uuid);
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
#define PCMK__VALUE_RESPONSE
union pcmk_controld_api_reply_t::@1 data
int crm_element_value_ll(const xmlNode *data, const char *name, long long *dest)
Retrieve the long long integer value of an XML attribute.
enum pcmk_controld_api_reply reply_type
#define PCMK__XA_ROUTER_NODE
#define PCMK_XA_REMOTE_NODE
int pcmk_controld_api_reprobe(pcmk_ipc_api_t *api, const char *target_node, const char *router_node)
Send a reprobe controller operation.
enum pcmk_ipc_server type
const char * host_from
Name of node that sent reply.
#define PCMK_XE_PRIMITIVE
#define PCMK__CONTROLD_API_MAJOR
#define PCMK_XA_REFERENCE
#define PCMK_XA_HAVE_QUORUM
#define PCMK__XE_ATTRIBUTES
enum crm_exit_e crm_exit_t
#define PCMK__XA_MAJOR_VERSION
#define PCMK__META_ON_NODE
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
G_GNUC_INTERNAL void pcmk__call_ipc_callback(pcmk_ipc_api_t *api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data)
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
#define PCMK__XA_CRMD_STATE
const char * crm_xml_add_ll(xmlNode *node, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
void pcmk__xml_free(xmlNode *xml)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define PCMK__XA_CRM_TASK
#define PCMK__CONTROLD_API_MINOR
#define PCMK__XA_TRANSITION_KEY
char * pcmk__transition_key(int transition_id, int action_id, int target_rc, const char *node)
#define crm_debug(fmt, args...)
struct pcmk_controld_api_reply_t::@1::@3 resource
G_GNUC_INTERNAL int pcmk__send_ipc_request(pcmk_ipc_api_t *api, const xmlNode *request)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define crm_trace(fmt, args...)
const char * feature_set
CRM feature set advertised by controller.
pcmk__ipc_methods_t * pcmk__controld_api_methods(void)
Wrappers for and extensions to libxml2.
int pcmk_controld_api_refresh(pcmk_ipc_api_t *api, const char *target_node, const char *router_node, const char *rsc_id, const char *rsc_long_id, const char *standard, const char *provider, const char *type, bool cib_only)
Ask the controller to refresh a resource.
#define PCMK__XA_CLIENT_UUID
#define pcmk__new_request(server, sender_system, recipient_node, recipient_system, task, data)
int(* post_connect)(pcmk_ipc_api_t *api)
#define PCMK__XA_CRM_SUBSYSTEM
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
IPC commands for Pacemaker controller.
#define PCMK_META_TIMEOUT
int pcmk_controld_api_list_nodes(pcmk_ipc_api_t *api)
Ask the controller for cluster information.
xmlNode * pcmk__xe_next(const xmlNode *node, const char *element_name)
#define PCMK_XA_CRM_FEATURE_SET
int(* new_data)(pcmk_ipc_api_t *api)
#define CRM_OP_RM_NODE_CACHE
#define PCMK__XA_MINOR_VERSION
int pcmk_controld_api_node_info(pcmk_ipc_api_t *api, uint32_t nodeid)
Send a "node info" controller operation.
bool(* dispatch)(pcmk_ipc_api_t *api, xmlNode *msg)
bool(* reply_expected)(pcmk_ipc_api_t *api, const xmlNode *request)
int pcmk_controld_api_ping(pcmk_ipc_api_t *api, const char *node_name)
Ask the controller for status.
#define crm_err(fmt, args...)
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
void(* free_data)(void *api_data)
const char * pcmk_ipc_name(const pcmk_ipc_api_t *api, bool for_log)
Get the IPC name used with an IPC API connection.
unsigned int pcmk_controld_api_replies_expected(const pcmk_ipc_api_t *api)
Get the number of IPC replies currently expected from the controller.
#define CRM_OP_INVOKE_LRM
const char * pcmk__controld_api_reply2str(enum pcmk_controld_api_reply reply)
IPC interface to Pacemaker daemons.
#define PCMK__CONTROLD_CMD_NODES
Daemon's reply to client IPC request.
#define pcmk__assert_alloc(nmemb, size)
#define CRM_OP_LRM_DELETE
#define PCMK__VALUE_REQUEST
#define crm_info(fmt, args...)
int pcmk_controld_api_fail(pcmk_ipc_api_t *api, const char *target_node, const char *router_node, const char *rsc_id, const char *rsc_long_id, const char *standard, const char *provider, const char *type)
Ask the controller to fail a resource.
#define PCMK__XA_CLIENT_NAME
pcmk_controld_api_reply
Possible types of controller replies.
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
char * crm_meta_name(const char *field)
Get the environment variable equivalent of a meta-attribute name.