root/lib/common/ipc_schedulerd.c

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

DEFINITIONS

This source file includes following definitions.
  1. new_data
  2. free_data
  3. post_connect
  4. reply_expected
  5. dispatch
  6. pcmk__schedulerd_api_methods
  7. do_schedulerd_api_call
  8. pcmk_schedulerd_api_graph

   1 /*
   2  * Copyright 2021 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 <stdlib.h>
  13 #include <time.h>
  14 
  15 #include <crm/crm.h>
  16 #include <crm/msg_xml.h>
  17 #include <crm/common/xml.h>
  18 #include <crm/common/ipc.h>
  19 #include <crm/common/ipc_internal.h>
  20 #include <crm/common/ipc_schedulerd.h>
  21 #include "crmcommon_private.h"
  22 
  23 typedef struct schedulerd_api_private_s {
  24     char *client_uuid;
  25 } schedulerd_api_private_t;
  26 
  27 // \return Standard Pacemaker return code
  28 static int
  29 new_data(pcmk_ipc_api_t *api)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31     struct schedulerd_api_private_s *private = NULL;
  32 
  33     api->api_data = calloc(1, sizeof(struct schedulerd_api_private_s));
  34 
  35     if (api->api_data == NULL) {
  36         return errno;
  37     }
  38 
  39     private = api->api_data;
  40     /* See comments in ipc_pacemakerd.c. */
  41     private->client_uuid = pcmk__getpid_s();
  42 
  43     return pcmk_rc_ok;
  44 }
  45 
  46 static void
  47 free_data(void *data)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49     free(((struct schedulerd_api_private_s *) data)->client_uuid);
  50     free(data);
  51 }
  52 
  53 // \return Standard Pacemaker return code
  54 static int
  55 post_connect(pcmk_ipc_api_t *api)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57     if (api->api_data == NULL) {
  58         return EINVAL;
  59     }
  60 
  61     return pcmk_rc_ok;
  62 }
  63 
  64 static bool
  65 reply_expected(pcmk_ipc_api_t *api, xmlNode *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67     const char *command = crm_element_value(request, F_CRM_TASK);
  68 
  69     if (command == NULL) {
  70         return false;
  71     }
  72 
  73     // We only need to handle commands that functions in this file can send
  74     return pcmk__str_any_of(command, CRM_OP_PECALC, NULL);
  75 }
  76 
  77 static bool
  78 dispatch(pcmk_ipc_api_t *api, xmlNode *reply)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80     crm_exit_t status = CRM_EX_OK;
  81     xmlNode *msg_data = NULL;
  82     pcmk_schedulerd_api_reply_t reply_data = {
  83         pcmk_schedulerd_reply_unknown
  84     };
  85     const char *value = NULL;
  86 
  87     if (pcmk__str_eq((const char *) reply->name, "ack", pcmk__str_casei)) {
  88         return false;
  89     }
  90 
  91     value = crm_element_value(reply, F_CRM_MSG_TYPE);
  92     if ((value == NULL) || (strcmp(value, XML_ATTR_RESPONSE))) {
  93         crm_debug("Unrecognizable schedulerd message: invalid message type '%s'",
  94                   crm_str(value));
  95         status = CRM_EX_PROTOCOL;
  96         goto done;
  97     }
  98 
  99     if (crm_element_value(reply, XML_ATTR_REFERENCE) == NULL) {
 100         crm_debug("Unrecognizable schedulerd message: no reference");
 101         status = CRM_EX_PROTOCOL;
 102         goto done;
 103     }
 104 
 105     // Parse useful info from reply
 106     msg_data = get_message_xml(reply, F_CRM_DATA);
 107     value = crm_element_value(reply, F_CRM_TASK);
 108 
 109     if (pcmk__str_eq(value, CRM_OP_PECALC, pcmk__str_none)) {
 110         reply_data.reply_type = pcmk_schedulerd_reply_graph;
 111         reply_data.data.graph.reference = crm_element_value(reply, XML_ATTR_REFERENCE);
 112         reply_data.data.graph.input = crm_element_value(reply, F_CRM_TGRAPH_INPUT);
 113         reply_data.data.graph.tgraph = msg_data;
 114     } else {
 115         crm_debug("Unrecognizable pacemakerd message: '%s'", crm_str(value));
 116         status = CRM_EX_PROTOCOL;
 117         goto done;
 118     }
 119 
 120 done:
 121     pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data);
 122     return false;
 123 }
 124 
 125 pcmk__ipc_methods_t *
 126 pcmk__schedulerd_api_methods()
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128     pcmk__ipc_methods_t *cmds = calloc(1, sizeof(pcmk__ipc_methods_t));
 129 
 130     if (cmds != NULL) {
 131         cmds->new_data = new_data;
 132         cmds->free_data = free_data;
 133         cmds->post_connect = post_connect;
 134         cmds->reply_expected = reply_expected;
 135         cmds->dispatch = dispatch;
 136     }
 137     return cmds;
 138 }
 139 
 140 static int
 141 do_schedulerd_api_call(pcmk_ipc_api_t *api, const char *task, xmlNode *cib, char **ref)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143     schedulerd_api_private_t *private;
 144     xmlNode *cmd = NULL;
 145     int rc;
 146 
 147     if (!pcmk_ipc_is_connected(api)) {
 148         return ENOTCONN;
 149     }
 150 
 151     private = api->api_data;
 152     CRM_ASSERT(private != NULL);
 153 
 154     cmd = create_request(task, cib, NULL, CRM_SYSTEM_PENGINE,
 155                          crm_system_name? crm_system_name : "client",
 156                          private->client_uuid);
 157 
 158     if (cmd) {
 159         rc = pcmk__send_ipc_request(api, cmd);
 160         if (rc != pcmk_rc_ok) {
 161             crm_debug("Couldn't send request to schedulerd: %s rc=%d",
 162                       pcmk_rc_str(rc), rc);
 163         }
 164 
 165         *ref = strdup(crm_element_value(cmd, F_CRM_REFERENCE));
 166         free_xml(cmd);
 167     } else {
 168         rc = ENOMSG;
 169     }
 170 
 171     return rc;
 172 }
 173 
 174 int
 175 pcmk_schedulerd_api_graph(pcmk_ipc_api_t *api, xmlNode *cib, char **ref)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177     return do_schedulerd_api_call(api, CRM_OP_PECALC, cib, ref);
 178 }

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