root/lib/transition/unpack.c

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

DEFINITIONS

This source file includes following definitions.
  1. unpack_action
  2. unpack_synapse
  3. unpack_graph
  4. destroy_action
  5. destroy_synapse
  6. destroy_graph
  7. convert_graph_action

   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 <sys/param.h>
  22 #include <crm/crm.h>
  23 #include <crm/msg_xml.h>
  24 
  25 #include <crm/common/xml.h>
  26 #include <crm/transition.h>
  27 #include <sys/stat.h>
  28 
  29 CRM_TRACE_INIT_DATA(transitioner);
  30 
  31 static crm_action_t *
  32 unpack_action(synapse_t * parent, xmlNode * xml_action)
     /* [previous][next][first][last][top][bottom][index][help] */
  33 {
  34     crm_action_t *action = NULL;
  35     const char *value = crm_element_value(xml_action, XML_ATTR_ID);
  36 
  37     if (value == NULL) {
  38         crm_err("Actions must have an id!");
  39         crm_log_xml_trace(xml_action, "Action with missing id");
  40         return NULL;
  41     }
  42 
  43     action = calloc(1, sizeof(crm_action_t));
  44     if (action == NULL) {
  45         crm_perror(LOG_CRIT, "Cannot unpack action");
  46         crm_log_xml_trace(xml_action, "Lost action");
  47         return NULL;
  48     }
  49 
  50     action->id = crm_parse_int(value, NULL);
  51     action->type = action_type_rsc;
  52     action->xml = copy_xml(xml_action);
  53     action->synapse = parent;
  54 
  55     if (safe_str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_RSC_OP)) {
  56         action->type = action_type_rsc;
  57 
  58     } else if (safe_str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_PSEUDO_EVENT)) {
  59         action->type = action_type_pseudo;
  60 
  61     } else if (safe_str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_CRM_EVENT)) {
  62         action->type = action_type_crm;
  63     }
  64 
  65     action->params = xml2list(action->xml);
  66 
  67     value = g_hash_table_lookup(action->params, "CRM_meta_timeout");
  68     if (value != NULL) {
  69         action->timeout = crm_parse_int(value, NULL);
  70     }
  71 
  72     /* Take start-delay into account for the timeout of the action timer */
  73     value = g_hash_table_lookup(action->params, "CRM_meta_start_delay");
  74     if (value != NULL) {
  75         action->timeout += crm_parse_int(value, NULL);
  76     }
  77 
  78     value = g_hash_table_lookup(action->params, "CRM_meta_interval");
  79     if (value != NULL) {
  80         action->interval = crm_parse_int(value, NULL);
  81     }
  82 
  83     value = g_hash_table_lookup(action->params, "CRM_meta_can_fail");
  84     if (value != NULL) {
  85         crm_str_to_boolean(value, &(action->can_fail));
  86     }
  87 
  88     crm_trace("Action %d has timer set to %dms", action->id, action->timeout);
  89 
  90     return action;
  91 }
  92 
  93 static synapse_t *
  94 unpack_synapse(crm_graph_t * new_graph, xmlNode * xml_synapse)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96     const char *value = NULL;
  97     xmlNode *inputs = NULL;
  98     xmlNode *action_set = NULL;
  99     synapse_t *new_synapse = NULL;
 100 
 101     CRM_CHECK(xml_synapse != NULL, return NULL);
 102     crm_trace("looking in synapse %s", ID(xml_synapse));
 103 
 104     new_synapse = calloc(1, sizeof(synapse_t));
 105     new_synapse->id = crm_parse_int(ID(xml_synapse), NULL);
 106 
 107     value = crm_element_value(xml_synapse, XML_CIB_ATTR_PRIORITY);
 108     if (value != NULL) {
 109         new_synapse->priority = crm_parse_int(value, NULL);
 110     }
 111 
 112     CRM_CHECK(new_synapse->id >= 0, free(new_synapse);
 113               return NULL);
 114 
 115     new_graph->num_synapses++;
 116 
 117     crm_trace("look for actions in synapse %s", crm_element_value(xml_synapse, XML_ATTR_ID));
 118 
 119     for (action_set = __xml_first_child(xml_synapse); action_set != NULL;
 120          action_set = __xml_next(action_set)) {
 121         if (crm_str_eq((const char *)action_set->name, "action_set", TRUE)) {
 122             xmlNode *action = NULL;
 123 
 124             for (action = __xml_first_child(action_set); action != NULL;
 125                  action = __xml_next(action)) {
 126                 crm_action_t *new_action = unpack_action(new_synapse, action);
 127 
 128                 if (new_action == NULL) {
 129                     continue;
 130                 }
 131 
 132                 new_graph->num_actions++;
 133 
 134                 crm_trace("Adding action %d to synapse %d", new_action->id, new_synapse->id);
 135 
 136                 new_synapse->actions = g_list_append(new_synapse->actions, new_action);
 137             }
 138         }
 139     }
 140 
 141     crm_trace("look for inputs in synapse %s", ID(xml_synapse));
 142 
 143     for (inputs = __xml_first_child(xml_synapse); inputs != NULL; inputs = __xml_next(inputs)) {
 144         if (crm_str_eq((const char *)inputs->name, "inputs", TRUE)) {
 145             xmlNode *trigger = NULL;
 146 
 147             for (trigger = __xml_first_child(inputs); trigger != NULL;
 148                  trigger = __xml_next(trigger)) {
 149                 xmlNode *input = NULL;
 150 
 151                 for (input = __xml_first_child(trigger); input != NULL; input = __xml_next(input)) {
 152                     crm_action_t *new_input = unpack_action(new_synapse, input);
 153 
 154                     if (new_input == NULL) {
 155                         continue;
 156                     }
 157 
 158                     crm_trace("Adding input %d to synapse %d", new_input->id, new_synapse->id);
 159 
 160                     new_synapse->inputs = g_list_append(new_synapse->inputs, new_input);
 161                 }
 162             }
 163         }
 164     }
 165 
 166     return new_synapse;
 167 }
 168 
 169 static void destroy_action(crm_action_t * action);
 170 
 171 crm_graph_t *
 172 unpack_graph(xmlNode * xml_graph, const char *reference)
     /* [previous][next][first][last][top][bottom][index][help] */
 173 {
 174 /*
 175   <transition_graph>
 176   <synapse>
 177   <action_set>
 178   <rsc_op id="2"
 179   ...
 180   <inputs>
 181   <rsc_op id="2"
 182   ...
 183 */
 184     crm_graph_t *new_graph = NULL;
 185     const char *t_id = NULL;
 186     const char *time = NULL;
 187     xmlNode *synapse = NULL;
 188 
 189     new_graph = calloc(1, sizeof(crm_graph_t));
 190 
 191     new_graph->id = -1;
 192     new_graph->abort_priority = 0;
 193     new_graph->network_delay = -1;
 194     new_graph->transition_timeout = -1;
 195     new_graph->stonith_timeout = -1;
 196     new_graph->completion_action = tg_done;
 197 
 198     if (reference) {
 199         new_graph->source = strdup(reference);
 200     } else {
 201         new_graph->source = strdup("unknown");
 202     }
 203 
 204     if (xml_graph != NULL) {
 205         t_id = crm_element_value(xml_graph, "transition_id");
 206         CRM_CHECK(t_id != NULL, free(new_graph);
 207                   return NULL);
 208         new_graph->id = crm_parse_int(t_id, "-1");
 209 
 210         time = crm_element_value(xml_graph, "cluster-delay");
 211         CRM_CHECK(time != NULL, free(new_graph);
 212                   return NULL);
 213         new_graph->network_delay = crm_get_msec(time);
 214 
 215         time = crm_element_value(xml_graph, "stonith-timeout");
 216         if (time == NULL) {
 217             new_graph->stonith_timeout = new_graph->network_delay;
 218         } else {
 219             new_graph->stonith_timeout = crm_get_msec(time);
 220         }
 221 
 222         t_id = crm_element_value(xml_graph, "batch-limit");
 223         new_graph->batch_limit = crm_parse_int(t_id, "0");
 224 
 225         t_id = crm_element_value(xml_graph, "migration-limit");
 226         new_graph->migration_limit = crm_parse_int(t_id, "-1");
 227     }
 228 
 229     for (synapse = __xml_first_child(xml_graph); synapse != NULL; synapse = __xml_next(synapse)) {
 230         if (crm_str_eq((const char *)synapse->name, "synapse", TRUE)) {
 231             synapse_t *new_synapse = unpack_synapse(new_graph, synapse);
 232 
 233             if (new_synapse != NULL) {
 234                 new_graph->synapses = g_list_append(new_graph->synapses, new_synapse);
 235             }
 236         }
 237     }
 238 
 239     crm_debug("Unpacked transition %d: %d actions in %d synapses",
 240               new_graph->id, new_graph->num_actions, new_graph->num_synapses);
 241 
 242     return new_graph;
 243 }
 244 
 245 static void
 246 destroy_action(crm_action_t * action)
     /* [previous][next][first][last][top][bottom][index][help] */
 247 {
 248     if (action->timer && action->timer->source_id != 0) {
 249         crm_warn("Cancelling timer for action %d (src=%d)", action->id, action->timer->source_id);
 250         g_source_remove(action->timer->source_id);
 251     }
 252     if (action->params) {
 253         g_hash_table_destroy(action->params);
 254     }
 255     free_xml(action->xml);
 256     free(action->timer);
 257     free(action);
 258 }
 259 
 260 static void
 261 destroy_synapse(synapse_t * synapse)
     /* [previous][next][first][last][top][bottom][index][help] */
 262 {
 263     while (g_list_length(synapse->actions) > 0) {
 264         crm_action_t *action = g_list_nth_data(synapse->actions, 0);
 265 
 266         synapse->actions = g_list_remove(synapse->actions, action);
 267         destroy_action(action);
 268     }
 269 
 270     while (g_list_length(synapse->inputs) > 0) {
 271         crm_action_t *action = g_list_nth_data(synapse->inputs, 0);
 272 
 273         synapse->inputs = g_list_remove(synapse->inputs, action);
 274         destroy_action(action);
 275     }
 276     free(synapse);
 277 }
 278 
 279 void
 280 destroy_graph(crm_graph_t * graph)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282     if (graph == NULL) {
 283         return;
 284     }
 285     while (g_list_length(graph->synapses) > 0) {
 286         synapse_t *synapse = g_list_nth_data(graph->synapses, 0);
 287 
 288         graph->synapses = g_list_remove(graph->synapses, synapse);
 289         destroy_synapse(synapse);
 290     }
 291 
 292     free(graph->source);
 293     free(graph);
 294 }
 295 
 296 lrmd_event_data_t *
 297 convert_graph_action(xmlNode * resource, crm_action_t * action, int status, int rc)
     /* [previous][next][first][last][top][bottom][index][help] */
 298 {
 299     xmlNode *xop = NULL;
 300     lrmd_event_data_t *op = NULL;
 301     GHashTableIter iter;
 302     const char *name = NULL;
 303     const char *value = NULL;
 304     xmlNode *action_resource = NULL;
 305 
 306     CRM_CHECK(action != NULL, return NULL);
 307     CRM_CHECK(action->type == action_type_rsc, return NULL);
 308 
 309     action_resource = first_named_child(action->xml, XML_CIB_TAG_RESOURCE);
 310     CRM_CHECK(action_resource != NULL, crm_log_xml_warn(action->xml, "Bad");
 311               return NULL);
 312 
 313     op = calloc(1, sizeof(lrmd_event_data_t));
 314 
 315     op->rsc_id = strdup(ID(action_resource));
 316     op->interval = action->interval;
 317     op->op_type = strdup(crm_element_value(action->xml, XML_LRM_ATTR_TASK));
 318 
 319     op->rc = rc;
 320     op->op_status = status;
 321     op->t_run = time(NULL);
 322     op->t_rcchange = op->t_run;
 323 
 324     op->params = g_hash_table_new_full(crm_str_hash, g_str_equal,
 325                                        g_hash_destroy_str, g_hash_destroy_str);
 326 
 327     g_hash_table_iter_init(&iter, action->params);
 328     while (g_hash_table_iter_next(&iter, (void **)&name, (void **)&value)) {
 329         g_hash_table_insert(op->params, strdup(name), strdup(value));
 330     }
 331 
 332     for (xop = __xml_first_child(resource); xop != NULL; xop = __xml_next(xop)) {
 333         int tmp = 0;
 334 
 335         crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp);
 336         crm_debug("Got call_id=%d for %s", tmp, ID(resource));
 337         if (tmp > op->call_id) {
 338             op->call_id = tmp;
 339         }
 340     }
 341 
 342     op->call_id++;
 343     return op;
 344 }

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