This source file includes following definitions.
- new_data
- free_data
- post_connect
- reply_expected
- dispatch
- pcmk__schedulerd_api_methods
- do_schedulerd_api_call
- pcmk_schedulerd_api_graph
1
2
3
4
5
6
7
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
27 static int
28 new_data(pcmk_ipc_api_t *api)
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
40 private->client_uuid = pcmk__getpid_s();
41
42 return pcmk_rc_ok;
43 }
44
45 static void
46 free_data(void *data)
47 {
48 free(((struct schedulerd_api_private_s *) data)->client_uuid);
49 free(data);
50 }
51
52
53 static int
54 post_connect(pcmk_ipc_api_t *api)
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)
65 {
66 const char *command = crm_element_value(request, PCMK__XA_CRM_TASK);
67
68 if (command == NULL) {
69 return false;
70 }
71
72
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)
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
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)
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)
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)
194 {
195 return do_schedulerd_api_call(api, CRM_OP_PECALC, cib, ref);
196 }