root/lib/transition/utils.c

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

DEFINITIONS

This source file includes following definitions.
  1. pseudo_action_dummy
  2. set_default_graph_functions
  3. set_graph_functions
  4. transition_status
  5. actiontype2text
  6. find_action
  7. print_synapse
  8. print_action
  9. print_graph
  10. abort2text
  11. update_abort_priority

   1 /* 
   2  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
   3  * 
   4  * This library is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU Lesser General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2.1 of the License, or (at your option) any later version.
   8  * 
   9  * This library 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  * Lesser General Public License for more details.
  13  * 
  14  * You should have received a copy of the GNU Lesser 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 <crm/crm.h>
  22 #include <crm/msg_xml.h>
  23 #include <crm/common/xml.h>
  24 #include <crm/transition.h>
  25 /* #include <sys/param.h> */
  26 /*  */
  27 
  28 extern crm_graph_functions_t *graph_fns;
  29 
  30 static gboolean
  31 pseudo_action_dummy(crm_graph_t * graph, crm_action_t * action)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33     static int fail = -1;
  34 
  35     if (fail < 0) {
  36         char *fail_s = getenv("PE_fail");
  37 
  38         if (fail_s) {
  39             fail = crm_int_helper(fail_s, NULL);
  40         } else {
  41             fail = 0;
  42         }
  43     }
  44 
  45     crm_trace("Dummy event handler: action %d executed", action->id);
  46     if (action->id == fail) {
  47         crm_err("Dummy event handler: pretending action %d failed", action->id);
  48         action->failed = TRUE;
  49         graph->abort_priority = INFINITY;
  50     }
  51     action->confirmed = TRUE;
  52     update_graph(graph, action);
  53     return TRUE;
  54 }
  55 
  56 crm_graph_functions_t default_fns = {
  57     pseudo_action_dummy,
  58     pseudo_action_dummy,
  59     pseudo_action_dummy,
  60     pseudo_action_dummy
  61 };
  62 
  63 void
  64 set_default_graph_functions(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  65 {
  66     graph_fns = &default_fns;
  67 }
  68 
  69 void
  70 set_graph_functions(crm_graph_functions_t * fns)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72     crm_info("Setting custom graph functions");
  73     graph_fns = fns;
  74 
  75     CRM_ASSERT(graph_fns != NULL);
  76     CRM_ASSERT(graph_fns->rsc != NULL);
  77     CRM_ASSERT(graph_fns->crmd != NULL);
  78     CRM_ASSERT(graph_fns->pseudo != NULL);
  79     CRM_ASSERT(graph_fns->stonith != NULL);
  80 }
  81 
  82 const char *
  83 transition_status(enum transition_status state)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85     switch (state) {
  86         case transition_active:
  87             return "active";
  88         case transition_pending:
  89             return "pending";
  90         case transition_complete:
  91             return "complete";
  92         case transition_stopped:
  93             return "stopped";
  94         case transition_terminated:
  95             return "terminated";
  96         case transition_action_failed:
  97             return "failed (action)";
  98         case transition_failed:
  99             return "failed";
 100     }
 101     return "unknown";
 102 }
 103 
 104 const char *
 105 actiontype2text(action_type_e type)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107     switch (type) {
 108         case action_type_pseudo:
 109             return "pseudo";
 110         case action_type_rsc:
 111             return "rsc";
 112         case action_type_crm:
 113             return "crm";
 114 
 115     }
 116     return "<unknown>";
 117 }
 118 
 119 static crm_action_t *
 120 find_action(crm_graph_t * graph, int id)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122     GListPtr sIter = NULL;
 123 
 124     if (graph == NULL) {
 125         return NULL;
 126     }
 127 
 128     for (sIter = graph->synapses; sIter != NULL; sIter = sIter->next) {
 129         GListPtr aIter = NULL;
 130         synapse_t *synapse = (synapse_t *) sIter->data;
 131 
 132         for (aIter = synapse->actions; aIter != NULL; aIter = aIter->next) {
 133             crm_action_t *action = (crm_action_t *) aIter->data;
 134 
 135             if (action->id == id) {
 136                 return action;
 137             }
 138         }
 139     }
 140     return NULL;
 141 }
 142 
 143 static void
 144 print_synapse(unsigned int log_level, crm_graph_t * graph, synapse_t * synapse)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146     GListPtr lpc = NULL;
 147     char *pending = NULL;
 148     const char *state = "Pending";
 149 
 150     if (synapse->failed) {
 151         state = "Failed";
 152 
 153     } else if (synapse->confirmed) {
 154         state = "Completed";
 155 
 156     } else if (synapse->executed) {
 157         state = "In-flight";
 158 
 159     } else if (synapse->ready) {
 160         state = "Ready";
 161     }
 162 
 163     if (synapse->executed == FALSE) {
 164         for (lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
 165             crm_action_t *input = (crm_action_t *) lpc->data;
 166             const char *id_string = crm_element_value(input->xml, XML_ATTR_ID);
 167 
 168             if (input->failed) {
 169                 pending = add_list_element(pending, id_string);
 170 
 171             } else if (input->confirmed) {
 172                 /* Confirmed, skip */
 173 
 174             } else if (find_action(graph, input->id)) {
 175                 /* In-flight or pending */
 176                 pending = add_list_element(pending, id_string);
 177             }
 178         }
 179     }
 180 
 181     for (lpc = synapse->actions; lpc != NULL; lpc = lpc->next) {
 182         crm_action_t *action = (crm_action_t *) lpc->data;
 183         const char *key = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
 184         const char *host = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);
 185         char *desc = crm_strdup_printf("%s %s op %s", state, actiontype2text(action->type), key);
 186 
 187         do_crm_log(log_level,
 188                    "[Action %4d]: %-50s on %s (priority: %d, waiting: %s)",
 189                    action->id, desc, host ? host : "N/A",
 190                    synapse->priority, pending ? pending : "none");
 191 
 192         free(desc);
 193     }
 194 
 195     if (synapse->executed == FALSE) {
 196         for (lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
 197             crm_action_t *input = (crm_action_t *) lpc->data;
 198             const char *key = crm_element_value(input->xml, XML_LRM_ATTR_TASK_KEY);
 199             const char *host = crm_element_value(input->xml, XML_LRM_ATTR_TARGET);
 200 
 201             if (find_action(graph, input->id) == NULL) {
 202                 if (host == NULL) {
 203                     do_crm_log(log_level, " * [Input %2d]: Unresolved dependency %s op %s",
 204                                input->id, actiontype2text(input->type), key);
 205                 } else {
 206                     do_crm_log(log_level, " * [Input %2d]: Unresolved dependency %s op %s on %s",
 207                                input->id, actiontype2text(input->type), key, host);
 208                 }
 209             }
 210         }
 211     }
 212 
 213     free(pending);
 214 }
 215 
 216 void
 217 print_action(int log_level, const char *prefix, crm_action_t * action)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219     print_synapse(log_level, NULL, action->synapse);
 220 }
 221 
 222 void
 223 print_graph(unsigned int log_level, crm_graph_t * graph)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225     GListPtr lpc = NULL;
 226 
 227     if (graph == NULL || graph->num_actions == 0) {
 228         if (log_level > LOG_DEBUG) {
 229             crm_debug("Empty transition graph");
 230         }
 231         return;
 232     }
 233 
 234     do_crm_log(log_level, "Graph %d with %d actions:"
 235                " batch-limit=%d jobs, network-delay=%dms",
 236                graph->id, graph->num_actions,
 237                graph->batch_limit, graph->network_delay);
 238 
 239     for (lpc = graph->synapses; lpc != NULL; lpc = lpc->next) {
 240         synapse_t *synapse = (synapse_t *) lpc->data;
 241 
 242         print_synapse(log_level, graph, synapse);
 243     }
 244 }
 245 
 246 static const char *
 247 abort2text(enum transition_action abort_action)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249     switch (abort_action) {
 250         case tg_done:
 251             return "done";
 252         case tg_stop:
 253             return "stop";
 254         case tg_restart:
 255             return "restart";
 256         case tg_shutdown:
 257             return "shutdown";
 258     }
 259     return "unknown";
 260 }
 261 
 262 bool
 263 update_abort_priority(crm_graph_t * graph, int priority,
     /* [previous][next][first][last][top][bottom][index][help] */
 264                       enum transition_action action, const char *abort_reason)
 265 {
 266     bool change = FALSE;
 267 
 268     if (graph == NULL) {
 269         return change;
 270     }
 271 
 272     if (graph->abort_priority < priority) {
 273         crm_debug("Abort priority upgraded from %d to %d", graph->abort_priority, priority);
 274         graph->abort_priority = priority;
 275         if (graph->abort_reason != NULL) {
 276             crm_debug("'%s' abort superseded by %s", graph->abort_reason, abort_reason);
 277         }
 278         graph->abort_reason = abort_reason;
 279         change = TRUE;
 280     }
 281 
 282     if (graph->completion_action < action) {
 283         crm_debug("Abort action %s superseded by %s: %s",
 284                   abort2text(graph->completion_action), abort2text(action), abort_reason);
 285         graph->completion_action = action;
 286         change = TRUE;
 287     }
 288 
 289     return change;
 290 }

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