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

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