This source file includes following definitions.
- init_working_set
- handle_pecalc_op
- process_pe_message
- pe_ipc_accept
- pe_ipc_dispatch
- pe_ipc_closed
- pe_ipc_destroy
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <crm/msg_xml.h>
13 #include <pacemaker-internal.h>
14
15 #include <stdbool.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19
20 #include "pacemaker-schedulerd.h"
21
22 static pe_working_set_t *
23 init_working_set(void)
24 {
25 pe_working_set_t *data_set = pe_new_working_set();
26
27 CRM_ASSERT(data_set != NULL);
28
29 crm_config_error = FALSE;
30 crm_config_warning = FALSE;
31
32 was_processing_error = FALSE;
33 was_processing_warning = FALSE;
34
35 data_set->priv = logger_out;
36 return data_set;
37 }
38
39 static void
40 handle_pecalc_op(xmlNode *msg, xmlNode *xml_data, pcmk__client_t *sender)
41 {
42 static struct series_s {
43 const char *name;
44 const char *param;
45
46
47
48
49 int wrap;
50 } series[] = {
51 { "pe-error", "pe-error-series-max", -1 },
52 { "pe-warn", "pe-warn-series-max", 5000 },
53 { "pe-input", "pe-input-series-max", 4000 },
54 };
55 static char *last_digest = NULL;
56 static char *filename = NULL;
57
58 unsigned int seq;
59 int series_id = 0;
60 int series_wrap = 0;
61 char *digest = NULL;
62 const char *value = NULL;
63 time_t execution_date = time(NULL);
64 xmlNode *converted = NULL;
65 xmlNode *reply = NULL;
66 bool is_repoke = false;
67 bool process = true;
68 pe_working_set_t *data_set = init_working_set();
69
70 digest = calculate_xml_versioned_digest(xml_data, FALSE, FALSE,
71 CRM_FEATURE_SET);
72 converted = copy_xml(xml_data);
73 if (!cli_config_update(&converted, NULL, TRUE)) {
74 data_set->graph = create_xml_node(NULL, XML_TAG_GRAPH);
75 crm_xml_add_int(data_set->graph, "transition_id", 0);
76 crm_xml_add_int(data_set->graph, "cluster-delay", 0);
77 process = false;
78 free(digest);
79
80 } else if (pcmk__str_eq(digest, last_digest, pcmk__str_casei)) {
81 is_repoke = true;
82 free(digest);
83
84 } else {
85 free(last_digest);
86 last_digest = digest;
87 }
88
89 if (process) {
90 pcmk__schedule_actions(converted,
91 pe_flag_no_counts
92 |pe_flag_no_compat
93 |pe_flag_show_utilization, data_set);
94 }
95
96
97 if (was_processing_error) {
98 series_id = 0;
99 } else if (was_processing_warning) {
100 series_id = 1;
101 } else {
102 series_id = 2;
103 }
104
105 value = pe_pref(data_set->config_hash, series[series_id].param);
106 if ((value == NULL)
107 || (pcmk__scan_min_int(value, &series_wrap, -1) != pcmk_rc_ok)) {
108 series_wrap = series[series_id].wrap;
109 }
110
111 if (pcmk__read_series_sequence(PE_STATE_DIR, series[series_id].name,
112 &seq) != pcmk_rc_ok) {
113
114 seq = 0;
115 }
116 crm_trace("Series %s: wrap=%d, seq=%u, pref=%s",
117 series[series_id].name, series_wrap, seq, value);
118
119 data_set->input = NULL;
120 reply = create_reply(msg, data_set->graph);
121 CRM_ASSERT(reply != NULL);
122
123 if (series_wrap == 0) {
124 free(filename);
125 filename = NULL;
126
127 } else if (!is_repoke) {
128 free(filename);
129 filename = pcmk__series_filename(PE_STATE_DIR,
130 series[series_id].name, seq, true);
131 }
132
133 crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
134 crm_xml_add_int(reply, "graph-errors", was_processing_error);
135 crm_xml_add_int(reply, "graph-warnings", was_processing_warning);
136 crm_xml_add_int(reply, "config-errors", crm_config_error);
137 crm_xml_add_int(reply, "config-warnings", crm_config_warning);
138
139 if (pcmk__ipc_send_xml(sender, 0, reply,
140 crm_ipc_server_event) != pcmk_rc_ok) {
141 int graph_file_fd = 0;
142 char *graph_file = NULL;
143 umask(S_IWGRP | S_IWOTH | S_IROTH);
144
145 graph_file = crm_strdup_printf("%s/pengine.graph.XXXXXX",
146 PE_STATE_DIR);
147 graph_file_fd = mkstemp(graph_file);
148
149 crm_err("Couldn't send transition graph to peer, writing to %s instead",
150 graph_file);
151
152 crm_xml_add(reply, F_CRM_TGRAPH, graph_file);
153 write_xml_fd(data_set->graph, graph_file, graph_file_fd, FALSE);
154
155 free(graph_file);
156 free_xml(first_named_child(reply, F_CRM_DATA));
157 CRM_ASSERT(pcmk__ipc_send_xml(sender, 0, reply,
158 crm_ipc_server_event) == pcmk_rc_ok);
159 }
160
161 free_xml(reply);
162 pcmk__log_transition_summary(filename);
163
164 if (series_wrap == 0) {
165 crm_debug("Not saving input to disk (disabled by configuration)");
166
167 } else if (is_repoke) {
168 crm_info("Input has not changed since last time, not saving to disk");
169
170 } else {
171 unlink(filename);
172 crm_xml_add_ll(xml_data, "execution-date", (long long) execution_date);
173 write_xml_file(xml_data, filename, TRUE);
174 pcmk__write_series_sequence(PE_STATE_DIR, series[series_id].name,
175 ++seq, series_wrap);
176 }
177
178 free_xml(converted);
179 pe_free_working_set(data_set);
180 }
181
182 static void
183 process_pe_message(xmlNode *msg, xmlNode *xml_data, pcmk__client_t *sender)
184 {
185 const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
186 const char *op = crm_element_value(msg, F_CRM_TASK);
187 const char *ref = crm_element_value(msg, F_CRM_REFERENCE);
188
189 crm_trace("Processing %s op (ref=%s)...", op, ref);
190
191 if (op == NULL) {
192
193
194 } else if (strcasecmp(op, CRM_OP_HELLO) == 0) {
195
196
197 } else if (pcmk__str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE, pcmk__str_casei)) {
198
199
200 } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) {
201 crm_trace("Bad sys-to %s", crm_str(sys_to));
202
203 } else if (strcasecmp(op, CRM_OP_PECALC) == 0) {
204 handle_pecalc_op(msg, xml_data, sender);
205 }
206 }
207
208 static int32_t
209 pe_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
210 {
211 crm_trace("Connection %p", c);
212 if (pcmk__new_client(c, uid, gid) == NULL) {
213 return -EIO;
214 }
215 return 0;
216 }
217
218 static int32_t
219 pe_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
220 {
221 uint32_t id = 0;
222 uint32_t flags = 0;
223 pcmk__client_t *c = pcmk__find_client(qbc);
224 xmlNode *msg = pcmk__client_data2xml(c, data, &id, &flags);
225
226 pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_INDETERMINATE);
227 if (msg != NULL) {
228 xmlNode *data_xml = get_message_xml(msg, F_CRM_DATA);
229
230 process_pe_message(msg, data_xml, c);
231 free_xml(msg);
232 }
233 return 0;
234 }
235
236
237 static int32_t
238 pe_ipc_closed(qb_ipcs_connection_t * c)
239 {
240 pcmk__client_t *client = pcmk__find_client(c);
241
242 if (client == NULL) {
243 return 0;
244 }
245 crm_trace("Connection %p", c);
246 pcmk__free_client(client);
247 return 0;
248 }
249
250 static void
251 pe_ipc_destroy(qb_ipcs_connection_t * c)
252 {
253 crm_trace("Connection %p", c);
254 pe_ipc_closed(c);
255 }
256
257 struct qb_ipcs_service_handlers ipc_callbacks = {
258 .connection_accept = pe_ipc_accept,
259 .connection_created = NULL,
260 .msg_process = pe_ipc_dispatch,
261 .connection_closed = pe_ipc_closed,
262 .connection_destroyed = pe_ipc_destroy
263 };