This source file includes following definitions.
- process_pe_message
- do_calculations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <crm_internal.h>
20
21 #include <sys/stat.h>
22 #include <sys/param.h>
23
24 #include <crm/crm.h>
25 #include <crm/cib.h>
26 #include <crm/msg_xml.h>
27 #include <crm/common/xml.h>
28
29 #include <glib.h>
30
31 #include <crm/pengine/status.h>
32 #include <pengine.h>
33 #include <allocate.h>
34 #include <utils.h>
35 #include <crm/common/ipcs.h>
36
37 xmlNode *do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now);
38
39 gboolean show_scores = FALSE;
40 int scores_log_level = LOG_DEBUG_2;
41 gboolean show_utilization = FALSE;
42 int utilization_log_level = LOG_DEBUG_2;
43 extern int transition_id;
44
45 #define get_series() was_processing_error?1:was_processing_warning?2:3
46
47 typedef struct series_s {
48 const char *name;
49 const char *param;
50 int wrap;
51 } series_t;
52
53 series_t series[] = {
54 {"pe-unknown", "_dont_match_anything_", -1},
55 {"pe-error", "pe-error-series-max", -1},
56 {"pe-warn", "pe-warn-series-max", 200},
57 {"pe-input", "pe-input-series-max", 400},
58 };
59
60 gboolean process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender);
61
62 gboolean
63 process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender)
64 {
65 static char *last_digest = NULL;
66 static char *filename = NULL;
67
68 time_t execution_date = time(NULL);
69 const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
70 const char *op = crm_element_value(msg, F_CRM_TASK);
71 const char *ref = crm_element_value(msg, F_CRM_REFERENCE);
72
73 crm_trace("Processing %s op (ref=%s)...", op, ref);
74
75 if (op == NULL) {
76
77
78 } else if (strcasecmp(op, CRM_OP_HELLO) == 0) {
79
80
81 } else if (safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) {
82
83
84 } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) {
85 crm_trace("Bad sys-to %s", crm_str(sys_to));
86 return FALSE;
87
88 } else if (strcasecmp(op, CRM_OP_PECALC) == 0) {
89 int seq = -1;
90 int series_id = 0;
91 int series_wrap = 0;
92 char *digest = NULL;
93 const char *value = NULL;
94 pe_working_set_t data_set;
95 xmlNode *converted = NULL;
96 xmlNode *reply = NULL;
97 gboolean is_repoke = FALSE;
98 gboolean process = TRUE;
99
100 crm_config_error = FALSE;
101 crm_config_warning = FALSE;
102
103 was_processing_error = FALSE;
104 was_processing_warning = FALSE;
105
106 set_working_set_defaults(&data_set);
107
108 digest = calculate_xml_versioned_digest(xml_data, FALSE, FALSE, CRM_FEATURE_SET);
109 converted = copy_xml(xml_data);
110 if (cli_config_update(&converted, NULL, TRUE) == FALSE) {
111 data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH);
112 crm_xml_add_int(data_set.graph, "transition_id", 0);
113 crm_xml_add_int(data_set.graph, "cluster-delay", 0);
114 process = FALSE;
115 free(digest);
116
117 } else if (safe_str_eq(digest, last_digest)) {
118 crm_info("Input has not changed since last time, not saving to disk");
119 is_repoke = TRUE;
120 free(digest);
121
122 } else {
123 free(last_digest);
124 last_digest = digest;
125 }
126
127 if (process) {
128 do_calculations(&data_set, converted, NULL);
129 }
130
131 series_id = get_series();
132 series_wrap = series[series_id].wrap;
133 value = pe_pref(data_set.config_hash, series[series_id].param);
134
135 if (value != NULL) {
136 series_wrap = crm_int_helper(value, NULL);
137 if (errno != 0) {
138 series_wrap = series[series_id].wrap;
139 }
140
141 } else {
142 crm_config_warn("No value specified for cluster"
143 " preference: %s", series[series_id].param);
144 }
145
146 seq = get_last_sequence(PE_STATE_DIR, series[series_id].name);
147 crm_trace("Series %s: wrap=%d, seq=%d, pref=%s",
148 series[series_id].name, series_wrap, seq, value);
149
150 data_set.input = NULL;
151 reply = create_reply(msg, data_set.graph);
152 CRM_ASSERT(reply != NULL);
153
154 if (is_repoke == FALSE) {
155 free(filename);
156 filename =
157 generate_series_filename(PE_STATE_DIR, series[series_id].name, seq, HAVE_BZLIB_H);
158 }
159
160 crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
161 crm_xml_add_int(reply, "graph-errors", was_processing_error);
162 crm_xml_add_int(reply, "graph-warnings", was_processing_warning);
163 crm_xml_add_int(reply, "config-errors", crm_config_error);
164 crm_xml_add_int(reply, "config-warnings", crm_config_warning);
165
166 if (crm_ipcs_send(sender, 0, reply, crm_ipc_server_event) == FALSE) {
167 int graph_file_fd = 0;
168 char *graph_file = NULL;
169 umask(S_IWGRP | S_IWOTH | S_IROTH);
170
171 graph_file = crm_strdup_printf("%s/pengine.graph.XXXXXX",
172 PE_STATE_DIR);
173 graph_file_fd = mkstemp(graph_file);
174
175 crm_err("Couldn't send transition graph to peer, writing to %s instead",
176 graph_file);
177
178 crm_xml_add(reply, F_CRM_TGRAPH, graph_file);
179 write_xml_fd(data_set.graph, graph_file, graph_file_fd, FALSE);
180
181 free(graph_file);
182 free_xml(first_named_child(reply, F_CRM_DATA));
183 CRM_ASSERT(crm_ipcs_send(sender, 0, reply, crm_ipc_server_event));
184 }
185
186 free_xml(reply);
187 cleanup_alloc_calculations(&data_set);
188
189 if (was_processing_error) {
190 crm_err("Calculated transition %d (with errors), saving inputs in %s",
191 transition_id, filename);
192
193 } else if (was_processing_warning) {
194 crm_warn("Calculated transition %d (with warnings), saving inputs in %s",
195 transition_id, filename);
196
197 } else {
198 crm_notice("Calculated transition %d, saving inputs in %s",
199 transition_id, filename);
200 }
201
202 if (crm_config_error) {
203 crm_notice("Configuration ERRORs found during PE processing."
204 " Please run \"crm_verify -L\" to identify issues.");
205 }
206
207 if (is_repoke == FALSE && series_wrap != 0) {
208 unlink(filename);
209 crm_xml_add_int(xml_data, "execution-date", execution_date);
210 write_xml_file(xml_data, filename, HAVE_BZLIB_H);
211 write_last_sequence(PE_STATE_DIR, series[series_id].name, seq + 1, series_wrap);
212 } else {
213 crm_trace("Not writing out %s: %d & %d", filename, is_repoke, series_wrap);
214 }
215
216 free_xml(converted);
217 }
218
219 return TRUE;
220 }
221
222 xmlNode *
223 do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now)
224 {
225 GListPtr gIter = NULL;
226 int rsc_log_level = LOG_INFO;
227
228
229
230 CRM_ASSERT(xml_input || is_set(data_set->flags, pe_flag_have_status));
231
232 if (is_set(data_set->flags, pe_flag_have_status) == FALSE) {
233 set_working_set_defaults(data_set);
234 data_set->input = xml_input;
235 data_set->now = now;
236
237 } else {
238 crm_trace("Already have status - reusing");
239 }
240
241 if (data_set->now == NULL) {
242 data_set->now = crm_time_new(NULL);
243 }
244
245 crm_trace("Calculate cluster status");
246 stage0(data_set);
247
248 if(is_not_set(data_set->flags, pe_flag_quick_location)) {
249 gIter = data_set->resources;
250 for (; gIter != NULL; gIter = gIter->next) {
251 resource_t *rsc = (resource_t *) gIter->data;
252
253 if (is_set(rsc->flags, pe_rsc_orphan) && rsc->role == RSC_ROLE_STOPPED) {
254 continue;
255 }
256 rsc->fns->print(rsc, NULL, pe_print_log, &rsc_log_level);
257 }
258 }
259
260 crm_trace("Applying placement constraints");
261 stage2(data_set);
262
263 if(is_set(data_set->flags, pe_flag_quick_location)){
264 return NULL;
265 }
266
267 crm_trace("Create internal constraints");
268 stage3(data_set);
269
270 crm_trace("Check actions");
271 stage4(data_set);
272
273 crm_trace("Allocate resources");
274 stage5(data_set);
275
276 crm_trace("Processing fencing and shutdown cases");
277 stage6(data_set);
278
279 crm_trace("Applying ordering constraints");
280 stage7(data_set);
281
282 crm_trace("Create transition graph");
283 stage8(data_set);
284
285 crm_trace("=#=#=#=#= Summary =#=#=#=#=");
286 crm_trace("\t========= Set %d (Un-runnable) =========", -1);
287 if (get_crm_log_level() >= LOG_TRACE) {
288 gIter = data_set->actions;
289 for (; gIter != NULL; gIter = gIter->next) {
290 action_t *action = (action_t *) gIter->data;
291
292 if (is_set(action->flags, pe_action_optional) == FALSE
293 && is_set(action->flags, pe_action_runnable) == FALSE
294 && is_set(action->flags, pe_action_pseudo) == FALSE) {
295 log_action(LOG_TRACE, "\t", action, TRUE);
296 }
297 }
298 }
299
300 return data_set->graph;
301 }