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-2024 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/common/xml.h>
  17 #include <crm/common/ipc.h>
  18 #include <crm/common/ipc_internal.h>
  19 #include <crm/common/ipc_schedulerd.h>
  20 #include "crmcommon_private.h"
  21 
  22 typedef struct schedulerd_api_private_s {
  23     char *client_uuid;
  24 } schedulerd_api_private_t;
  25 
  26 // \return Standard Pacemaker return code
  27 static int
  28 new_data(pcmk_ipc_api_t *api)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30     struct schedulerd_api_private_s *private = NULL;
  31 
  32     api->api_data = calloc(1, sizeof(struct schedulerd_api_private_s));
  33 
  34     if (api->api_data == NULL) {
  35         return errno;
  36     }
  37 
  38     private = api->api_data;
  39     /* See comments in ipc_pacemakerd.c. */
  40     private->client_uuid = pcmk__getpid_s();
  41 
  42     return pcmk_rc_ok;
  43 }
  44 
  45 static void
  46 free_data(void *data)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48     free(((struct schedulerd_api_private_s *) data)->client_uuid);
  49     free(data);
  50 }
  51 
  52 // \return Standard Pacemaker return code
  53 static int
  54 post_connect(pcmk_ipc_api_t *api)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56     if (api->api_data == NULL) {
  57         return EINVAL;
  58     }
  59 
  60     return pcmk_rc_ok;
  61 }
  62 
  63 static bool
  64 reply_expected(pcmk_ipc_api_t *api, const xmlNode *request)
     /* [previous][next][first][last][top][bottom][index][help] */
  65 {
  66     const char *command = crm_element_value(request, PCMK__XA_CRM_TASK);
  67 
  68     if (command == NULL) {
  69         return false;
  70     }
  71 
  72     // We only need to handle commands that functions in this file can send
  73     return pcmk__str_any_of(command, CRM_OP_PECALC, NULL);
  74 }
  75 
  76 static bool
  77 dispatch(pcmk_ipc_api_t *api, xmlNode *reply)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79     crm_exit_t status = CRM_EX_OK;
  80     xmlNode *wrapper = NULL;
  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__xe_is(reply, PCMK__XE_ACK)) {
  88         return false;
  89     }
  90 
  91     value = crm_element_value(reply, PCMK__XA_T);
  92     if (pcmk__parse_server(value) != pcmk_ipc_schedulerd) {
  93         crm_info("Unrecognizable message from schedulerd: "
  94                   "unexpected message type '%s'",
  95                   pcmk__s(value, ""));
  96         status = CRM_EX_PROTOCOL;
  97         goto done;
  98     }
  99 
 100     value = crm_element_value(reply, PCMK__XA_SUBT);
 101     if (!pcmk__str_eq(value, PCMK__VALUE_RESPONSE, pcmk__str_none)) {
 102         crm_info("Unrecognizable message from schedulerd: "
 103                  "message type '%s' not '" PCMK__VALUE_RESPONSE "'",
 104                  pcmk__s(value, ""));
 105         status = CRM_EX_PROTOCOL;
 106         goto done;
 107     }
 108 
 109     if (pcmk__str_empty(crm_element_value(reply, PCMK_XA_REFERENCE))) {
 110         crm_info("Unrecognizable message from schedulerd: no reference");
 111         status = CRM_EX_PROTOCOL;
 112         goto done;
 113     }
 114 
 115     // Parse useful info from reply
 116     wrapper = pcmk__xe_first_child(reply, PCMK__XE_CRM_XML, NULL, NULL);
 117     msg_data = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
 118 
 119     value = crm_element_value(reply, PCMK__XA_CRM_TASK);
 120 
 121     if (pcmk__str_eq(value, CRM_OP_PECALC, pcmk__str_none)) {
 122         reply_data.reply_type = pcmk_schedulerd_reply_graph;
 123         reply_data.data.graph.reference = crm_element_value(reply,
 124                                                             PCMK_XA_REFERENCE);
 125         reply_data.data.graph.input = crm_element_value(reply,
 126                                                         PCMK__XA_CRM_TGRAPH_IN);
 127         reply_data.data.graph.tgraph = msg_data;
 128     } else {
 129         crm_info("Unrecognizable message from schedulerd: "
 130                   "unknown command '%s'", pcmk__s(value, ""));
 131         status = CRM_EX_PROTOCOL;
 132         goto done;
 133     }
 134 
 135 done:
 136     pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data);
 137     return false;
 138 }
 139 
 140 pcmk__ipc_methods_t *
 141 pcmk__schedulerd_api_methods(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143     pcmk__ipc_methods_t *cmds = calloc(1, sizeof(pcmk__ipc_methods_t));
 144 
 145     if (cmds != NULL) {
 146         cmds->new_data = new_data;
 147         cmds->free_data = free_data;
 148         cmds->post_connect = post_connect;
 149         cmds->reply_expected = reply_expected;
 150         cmds->dispatch = dispatch;
 151     }
 152     return cmds;
 153 }
 154 
 155 static int
 156 do_schedulerd_api_call(pcmk_ipc_api_t *api, const char *task, xmlNode *cib, char **ref)
     /* [previous][next][first][last][top][bottom][index][help] */
 157 {
 158     schedulerd_api_private_t *private;
 159     xmlNode *cmd = NULL;
 160     int rc;
 161     char *sender_system = NULL;
 162 
 163     if (!pcmk_ipc_is_connected(api)) {
 164         return ENOTCONN;
 165     }
 166 
 167     private = api->api_data;
 168     pcmk__assert(private != NULL);
 169 
 170     sender_system = crm_strdup_printf("%s_%s", private->client_uuid,
 171                                       pcmk__s(crm_system_name, "client"));
 172     cmd = pcmk__new_request(pcmk_ipc_schedulerd, sender_system, NULL,
 173                             CRM_SYSTEM_PENGINE, task, cib);
 174     free(sender_system);
 175 
 176     if (cmd) {
 177         rc = pcmk__send_ipc_request(api, cmd);
 178         if (rc != pcmk_rc_ok) {
 179             crm_debug("Couldn't send request to schedulerd: %s rc=%d",
 180                       pcmk_rc_str(rc), rc);
 181         }
 182 
 183         *ref = strdup(crm_element_value(cmd, PCMK_XA_REFERENCE));
 184         pcmk__xml_free(cmd);
 185     } else {
 186         rc = ENOMSG;
 187     }
 188 
 189     return rc;
 190 }
 191 
 192 int
 193 pcmk_schedulerd_api_graph(pcmk_ipc_api_t *api, xmlNode *cib, char **ref)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195     return do_schedulerd_api_call(api, CRM_OP_PECALC, cib, ref);
 196 }

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