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-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 <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 (!pcmk__str_eq(value, XML_ATTR_RESPONSE, pcmk__str_none)) {
  93         crm_info("Unrecognizable message from schedulerd: "
  94                   "message type '%s' not '" XML_ATTR_RESPONSE "'",
  95                   pcmk__s(value, ""));
  96         status = CRM_EX_PROTOCOL;
  97         goto done;
  98     }
  99 
 100     if (pcmk__str_empty(crm_element_value(reply, XML_ATTR_REFERENCE))) {
 101         crm_info("Unrecognizable message from schedulerd: no reference");
 102         status = CRM_EX_PROTOCOL;
 103         goto done;
 104     }
 105 
 106     // Parse useful info from reply
 107     msg_data = get_message_xml(reply, F_CRM_DATA);
 108     value = crm_element_value(reply, F_CRM_TASK);
 109 
 110     if (pcmk__str_eq(value, CRM_OP_PECALC, pcmk__str_none)) {
 111         reply_data.reply_type = pcmk_schedulerd_reply_graph;
 112         reply_data.data.graph.reference = crm_element_value(reply, XML_ATTR_REFERENCE);
 113         reply_data.data.graph.input = crm_element_value(reply, F_CRM_TGRAPH_INPUT);
 114         reply_data.data.graph.tgraph = msg_data;
 115     } else {
 116         crm_info("Unrecognizable message from schedulerd: "
 117                   "unknown command '%s'", pcmk__s(value, ""));
 118         status = CRM_EX_PROTOCOL;
 119         goto done;
 120     }
 121 
 122 done:
 123     pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data);
 124     return false;
 125 }
 126 
 127 pcmk__ipc_methods_t *
 128 pcmk__schedulerd_api_methods(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130     pcmk__ipc_methods_t *cmds = calloc(1, sizeof(pcmk__ipc_methods_t));
 131 
 132     if (cmds != NULL) {
 133         cmds->new_data = new_data;
 134         cmds->free_data = free_data;
 135         cmds->post_connect = post_connect;
 136         cmds->reply_expected = reply_expected;
 137         cmds->dispatch = dispatch;
 138     }
 139     return cmds;
 140 }
 141 
 142 static int
 143 do_schedulerd_api_call(pcmk_ipc_api_t *api, const char *task, xmlNode *cib, char **ref)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145     schedulerd_api_private_t *private;
 146     xmlNode *cmd = NULL;
 147     int rc;
 148 
 149     if (!pcmk_ipc_is_connected(api)) {
 150         return ENOTCONN;
 151     }
 152 
 153     private = api->api_data;
 154     CRM_ASSERT(private != NULL);
 155 
 156     cmd = create_request(task, cib, NULL, CRM_SYSTEM_PENGINE,
 157                          crm_system_name? crm_system_name : "client",
 158                          private->client_uuid);
 159 
 160     if (cmd) {
 161         rc = pcmk__send_ipc_request(api, cmd);
 162         if (rc != pcmk_rc_ok) {
 163             crm_debug("Couldn't send request to schedulerd: %s rc=%d",
 164                       pcmk_rc_str(rc), rc);
 165         }
 166 
 167         *ref = strdup(crm_element_value(cmd, F_CRM_REFERENCE));
 168         free_xml(cmd);
 169     } else {
 170         rc = ENOMSG;
 171     }
 172 
 173     return rc;
 174 }
 175 
 176 int
 177 pcmk_schedulerd_api_graph(pcmk_ipc_api_t *api, xmlNode *cib, char **ref)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179     return do_schedulerd_api_call(api, CRM_OP_PECALC, cib, ref);
 180 }

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