pacemaker 2.1.4-dc6eb4362e
Scalable High-Availability cluster resource manager
ipc_schedulerd.c
Go to the documentation of this file.
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>
21#include "crmcommon_private.h"
22
23typedef struct schedulerd_api_private_s {
24 char *client_uuid;
26
27// \return Standard Pacemaker return code
28static int
29new_data(pcmk_ipc_api_t *api)
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
46static void
47free_data(void *data)
48{
49 free(((struct schedulerd_api_private_s *) data)->client_uuid);
50 free(data);
51}
52
53// \return Standard Pacemaker return code
54static int
55post_connect(pcmk_ipc_api_t *api)
56{
57 if (api->api_data == NULL) {
58 return EINVAL;
59 }
60
61 return pcmk_rc_ok;
62}
63
64static bool
65reply_expected(pcmk_ipc_api_t *api, xmlNode *request)
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
77static bool
78dispatch(pcmk_ipc_api_t *api, xmlNode *reply)
79{
80 crm_exit_t status = CRM_EX_OK;
81 xmlNode *msg_data = NULL;
82 pcmk_schedulerd_api_reply_t reply_data = {
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)) {
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
120done:
121 pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data);
122 return false;
123}
124
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
140static int
141do_schedulerd_api_call(pcmk_ipc_api_t *api, const char *task, xmlNode *cib, char **ref)
142{
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,
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
174int
175pcmk_schedulerd_api_graph(pcmk_ipc_api_t *api, xmlNode *cib, char **ref)
176{
177 return do_schedulerd_api_call(api, CRM_OP_PECALC, cib, ref);
178}
char data[0]
Definition: cpg.c:10
A dumping ground.
#define CRM_OP_PECALC
Definition: crm.h:140
char * crm_system_name
Definition: utils.c:54
#define CRM_SYSTEM_PENGINE
Definition: crm.h:108
G_GNUC_INTERNAL int pcmk__send_ipc_request(pcmk_ipc_api_t *api, xmlNode *request)
Definition: ipc_client.c:616
G_GNUC_INTERNAL void pcmk__call_ipc_callback(pcmk_ipc_api_t *api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data)
Definition: ipc_client.c:145
IPC interface to Pacemaker daemons.
#define create_request(task, xml_data, host_to, sys_to, sys_from, uuid_from)
Definition: ipc.h:43
@ pcmk_ipc_event_reply
Daemon's reply to client IPC request.
Definition: ipc.h:83
bool pcmk_ipc_is_connected(pcmk_ipc_api_t *api)
Check whether an IPC API connection is active.
Definition: ipc_client.c:282
int pcmk_schedulerd_api_graph(pcmk_ipc_api_t *api, xmlNode *cib, char **ref)
Make an IPC request to the scheduler for the transition graph.
struct schedulerd_api_private_s schedulerd_api_private_t
pcmk__ipc_methods_t * pcmk__schedulerd_api_methods()
IPC commands for Schedulerd.
@ pcmk_schedulerd_reply_graph
@ pcmk_schedulerd_reply_unknown
#define crm_str(x)
Definition: logging.h:384
#define crm_debug(fmt, args...)
Definition: logging.h:363
#define F_CRM_MSG_TYPE
Definition: msg_xml.h:93
#define F_CRM_REFERENCE
Definition: msg_xml.h:97
#define XML_ATTR_RESPONSE
Definition: msg_xml.h:155
#define XML_ATTR_REFERENCE
Definition: msg_xml.h:159
#define F_CRM_DATA
Definition: msg_xml.h:90
#define F_CRM_TASK
Definition: msg_xml.h:91
#define F_CRM_TGRAPH_INPUT
Definition: msg_xml.h:108
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
#define CRM_ASSERT(expr)
Definition: results.h:42
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:370
@ CRM_EX_PROTOCOL
Protocol violated.
Definition: results.h:263
@ CRM_EX_OK
Success.
Definition: results.h:239
@ pcmk_rc_ok
Definition: results.h:146
enum crm_exit_e crm_exit_t
@ pcmk__str_none
@ pcmk__str_casei
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:955
int(* new_data)(pcmk_ipc_api_t *api)
void(* free_data)(void *api_data)
bool(* dispatch)(pcmk_ipc_api_t *api, xmlNode *msg)
bool(* reply_expected)(pcmk_ipc_api_t *api, xmlNode *request)
int(* post_connect)(pcmk_ipc_api_t *api)
union pcmk_schedulerd_api_reply_t::@7 data
enum pcmk_schedulerd_api_reply reply_type
struct pcmk_schedulerd_api_reply_t::@7::@8 graph
Wrappers for and extensions to libxml2.
void free_xml(xmlNode *child)
Definition: xml.c:824
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: messages.c:154