LCOV - code coverage report
Current view: top level - common - ipc_schedulerd.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 0 78 0.0 %
Date: 2024-05-07 11:09:47 Functions: 0 8 0.0 %

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

Generated by: LCOV version 1.14