root/daemons/attrd/attrd_messages.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. handle_unknown_request
  2. handle_clear_failure_request
  3. handle_flush_request
  4. handle_query_request
  5. handle_remove_request
  6. handle_refresh_request
  7. handle_sync_request
  8. handle_sync_response_request
  9. handle_update_request
  10. attrd_register_handlers
  11. attrd_unregister_handlers
  12. attrd_handle_request
  13. attrd_broadcast_protocol
  14. attrd_send_message

   1 /*
   2  * Copyright 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 General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <glib.h>
  13 
  14 #include <crm/common/messages_internal.h>
  15 #include <crm/msg_xml.h>
  16 
  17 #include "pacemaker-attrd.h"
  18 
  19 int minimum_protocol_version = -1;
  20 
  21 static GHashTable *attrd_handlers = NULL;
  22 
  23 static xmlNode *
  24 handle_unknown_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26     crm_err("Unknown IPC request %s from %s %s",
  27             request->op, pcmk__request_origin_type(request),
  28             pcmk__request_origin(request));
  29     pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID,
  30                         "Unknown request type '%s' (bug?)", request->op);
  31     return NULL;
  32 }
  33 
  34 static xmlNode *
  35 handle_clear_failure_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  36 {
  37     if (request->peer != NULL) {
  38         /* It is not currently possible to receive this as a peer command,
  39          * but will be, if we one day enable propagating this operation.
  40          */
  41         attrd_peer_clear_failure(request);
  42         pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
  43         return NULL;
  44     } else {
  45         return attrd_client_clear_failure(request);
  46     }
  47 }
  48 
  49 static xmlNode *
  50 handle_flush_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52     if (request->peer != NULL) {
  53         /* Ignore. The flush command was removed in 2.0.0 but may be
  54          * received from peers running older versions.
  55          */
  56         pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
  57         return NULL;
  58     } else {
  59         return handle_unknown_request(request);
  60     }
  61 }
  62 
  63 static xmlNode *
  64 handle_query_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  65 {
  66     if (request->peer != NULL) {
  67         return handle_unknown_request(request);
  68     } else {
  69         return attrd_client_query(request);
  70     }
  71 }
  72 
  73 static xmlNode *
  74 handle_remove_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76     if (request->peer != NULL) {
  77         const char *host = crm_element_value(request->xml, PCMK__XA_ATTR_NODE_NAME);
  78         attrd_peer_remove(host, true, request->peer);
  79         pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
  80         return NULL;
  81     } else {
  82         return attrd_client_peer_remove(request);
  83     }
  84 }
  85 
  86 static xmlNode *
  87 handle_refresh_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89     if (request->peer != NULL) {
  90         return handle_unknown_request(request);
  91     } else {
  92         return attrd_client_refresh(request);
  93     }
  94 }
  95 
  96 static xmlNode *
  97 handle_sync_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99     if (request->peer != NULL) {
 100         crm_node_t *peer = crm_get_peer(0, request->peer);
 101 
 102         attrd_peer_sync(peer, request->xml);
 103         pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
 104         return NULL;
 105     } else {
 106         return handle_unknown_request(request);
 107     }
 108 }
 109 
 110 static xmlNode *
 111 handle_sync_response_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113     if (request->ipc_client != NULL) {
 114         return handle_unknown_request(request);
 115     } else {
 116         if (request->peer != NULL) {
 117             crm_node_t *peer = crm_get_peer(0, request->peer);
 118             bool peer_won = attrd_check_for_new_writer(peer, request->xml);
 119 
 120             if (!pcmk__str_eq(peer->uname, attrd_cluster->uname, pcmk__str_casei)) {
 121                 attrd_peer_sync_response(peer, peer_won, request->xml);
 122             }
 123         }
 124 
 125         pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
 126         return NULL;
 127     }
 128 }
 129 
 130 static xmlNode *
 131 handle_update_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
 132 {
 133     if (request->peer != NULL) {
 134         const char *host = crm_element_value(request->xml, PCMK__XA_ATTR_NODE_NAME);
 135         crm_node_t *peer = crm_get_peer(0, request->peer);
 136 
 137         attrd_peer_update(peer, request->xml, host, false);
 138         pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
 139         return NULL;
 140     } else {
 141         /* Because attrd_client_update can be called recursively, we send the ACK
 142          * here to ensure that the client only ever receives one.
 143          */
 144         attrd_send_ack(request->ipc_client, request->ipc_id,
 145                        request->flags|crm_ipc_client_response);
 146         return attrd_client_update(request);
 147     }
 148 }
 149 
 150 static void
 151 attrd_register_handlers(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 152 {
 153     pcmk__server_command_t handlers[] = {
 154         { PCMK__ATTRD_CMD_CLEAR_FAILURE, handle_clear_failure_request },
 155         { PCMK__ATTRD_CMD_FLUSH, handle_flush_request },
 156         { PCMK__ATTRD_CMD_PEER_REMOVE, handle_remove_request },
 157         { PCMK__ATTRD_CMD_QUERY, handle_query_request },
 158         { PCMK__ATTRD_CMD_REFRESH, handle_refresh_request },
 159         { PCMK__ATTRD_CMD_SYNC, handle_sync_request },
 160         { PCMK__ATTRD_CMD_SYNC_RESPONSE, handle_sync_response_request },
 161         { PCMK__ATTRD_CMD_UPDATE, handle_update_request },
 162         { PCMK__ATTRD_CMD_UPDATE_DELAY, handle_update_request },
 163         { PCMK__ATTRD_CMD_UPDATE_BOTH, handle_update_request },
 164         { NULL, handle_unknown_request },
 165     };
 166 
 167     attrd_handlers = pcmk__register_handlers(handlers);
 168 }
 169 
 170 void
 171 attrd_unregister_handlers(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 172 {
 173     if (attrd_handlers != NULL) {
 174         g_hash_table_destroy(attrd_handlers);
 175         attrd_handlers = NULL;
 176     }
 177 }
 178 
 179 void
 180 attrd_handle_request(pcmk__request_t *request)
     /* [previous][next][first][last][top][bottom][index][help] */
 181 {
 182     xmlNode *reply = NULL;
 183     char *log_msg = NULL;
 184     const char *reason = NULL;
 185 
 186     if (attrd_handlers == NULL) {
 187         attrd_register_handlers();
 188     }
 189 
 190     reply = pcmk__process_request(request, attrd_handlers);
 191 
 192     if (reply != NULL) {
 193         crm_log_xml_trace(reply, "Reply");
 194 
 195         if (request->ipc_client != NULL) {
 196             pcmk__ipc_send_xml(request->ipc_client, request->ipc_id, reply,
 197                                request->ipc_flags);
 198         } else {
 199             crm_err("Not sending CPG reply to client");
 200         }
 201 
 202         free_xml(reply);
 203     }
 204 
 205     reason = request->result.exit_reason;
 206     log_msg = crm_strdup_printf("Processed %s request from %s %s: %s%s%s%s",
 207                                 request->op, pcmk__request_origin_type(request),
 208                                 pcmk__request_origin(request),
 209                                 pcmk_exec_status_str(request->result.execution_status),
 210                                 (reason == NULL)? "" : " (",
 211                                 pcmk__s(reason, ""),
 212                                 (reason == NULL)? "" : ")");
 213 
 214     if (!pcmk__result_ok(&request->result)) {
 215         crm_warn("%s", log_msg);
 216     } else {
 217         crm_debug("%s", log_msg);
 218     }
 219 
 220     free(log_msg);
 221     pcmk__reset_request(request);
 222 }
 223 
 224 /*!
 225     \internal
 226     \brief Broadcast private attribute for local node with protocol version
 227 */
 228 void
 229 attrd_broadcast_protocol(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231     xmlNode *attrd_op = create_xml_node(NULL, __func__);
 232 
 233     crm_xml_add(attrd_op, F_TYPE, T_ATTRD);
 234     crm_xml_add(attrd_op, F_ORIG, crm_system_name);
 235     crm_xml_add(attrd_op, PCMK__XA_TASK, PCMK__ATTRD_CMD_UPDATE);
 236     crm_xml_add(attrd_op, PCMK__XA_ATTR_NAME, CRM_ATTR_PROTOCOL);
 237     crm_xml_add(attrd_op, PCMK__XA_ATTR_VALUE, ATTRD_PROTOCOL_VERSION);
 238     crm_xml_add_int(attrd_op, PCMK__XA_ATTR_IS_PRIVATE, 1);
 239     pcmk__xe_add_node(attrd_op, attrd_cluster->uname, attrd_cluster->nodeid);
 240 
 241     crm_debug("Broadcasting attrd protocol version %s for node %s",
 242               ATTRD_PROTOCOL_VERSION, attrd_cluster->uname);
 243 
 244     attrd_send_message(NULL, attrd_op); /* ends up at attrd_peer_message() */
 245 
 246     free_xml(attrd_op);
 247 }
 248 
 249 gboolean
 250 attrd_send_message(crm_node_t * node, xmlNode * data)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252     crm_xml_add(data, F_TYPE, T_ATTRD);
 253     crm_xml_add(data, PCMK__XA_ATTR_VERSION, ATTRD_PROTOCOL_VERSION);
 254     attrd_xml_add_writer(data);
 255     return send_cluster_message(node, crm_msg_attrd, data, TRUE);
 256 }

/* [previous][next][first][last][top][bottom][index][help] */