root/pengine/pengine.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. process_pe_message
  2. do_calculations

   1 /*
   2  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2 of the License, or (at your option) any later version.
   8  *
   9  * This software is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  * General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public
  15  * License along with this library; if not, write to the Free Software
  16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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         /* error */
  77 
  78     } else if (strcasecmp(op, CRM_OP_HELLO) == 0) {
  79         /* ignore */
  80 
  81     } else if (safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) {
  82         /* ignore */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225     GListPtr gIter = NULL;
 226     int rsc_log_level = LOG_INFO;
 227 
 228 /*      pe_debug_on(); */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */