This source file includes following definitions.
- probe_needed_before_action
- add_probe_orderings_for_stops
- add_restart_orderings_for_probe
- clear_actions_tracking_flag
- add_restart_orderings_for_rsc
- order_then_probes
- pcmk__order_probes
- pcmk__schedule_probes
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <glib.h>
  13 
  14 #include <crm/crm.h>
  15 #include <crm/pengine/status.h>
  16 #include <pacemaker-internal.h>
  17 #include "libpacemaker_private.h"
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 static bool
  29 probe_needed_before_action(pe_action_t *probe, pe_action_t *then)
     
  30 {
  31     
  32     if (pcmk__str_eq(then->task, CRM_OP_FENCE, pcmk__str_casei)
  33          && (probe->node != NULL) && (then->node != NULL)
  34          && (probe->node->details == then->node->details)) {
  35         const char *op = g_hash_table_lookup(then->meta, "stonith_action");
  36 
  37         if (pcmk__str_eq(op, "on", pcmk__str_casei)) {
  38             return false;
  39         }
  40     }
  41 
  42     
  43     if (pcmk__str_eq(then->task, CRM_OP_SHUTDOWN, pcmk__str_none)
  44         && (probe->node != NULL) && (then->node != NULL)
  45         && (probe->node->details != then->node->details)) {
  46         return false;
  47     }
  48 
  49     
  50     return true;
  51 }
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 static void
  67 add_probe_orderings_for_stops(pe_working_set_t *data_set)
     
  68 {
  69     for (GList *iter = data_set->ordering_constraints; iter != NULL;
  70          iter = iter->next) {
  71 
  72         pe__ordering_t *order = iter->data;
  73         enum pe_ordering order_type = pe_order_optional;
  74         GList *probes = NULL;
  75         GList *then_actions = NULL;
  76 
  77         
  78         if (order->type == pe_order_none) {
  79             continue;
  80         }
  81 
  82         
  83         if ((order->lh_rsc == NULL) || (order->lh_rsc == order->rh_rsc)) {
  84             continue;
  85         }
  86 
  87         
  88         if (((order->lh_action == NULL) && (order->lh_action_task == NULL)) ||
  89             ((order->rh_action == NULL) && (order->rh_action_task == NULL))) {
  90             continue;
  91         }
  92 
  93         
  94         if ((order->lh_action != NULL)
  95             && !pcmk__str_eq(order->lh_action->task, RSC_STOP, pcmk__str_none)) {
  96             continue;
  97         } else if ((order->lh_action == NULL)
  98                    && !pcmk__ends_with(order->lh_action_task, "_" RSC_STOP "_0")) {
  99             continue;
 100         }
 101 
 102         
 103 
 104 
 105 
 106         if ((order->rh_rsc != NULL)
 107             && (order->lh_rsc->container == order->rh_rsc)) {
 108 
 109             if ((order->rh_action != NULL)
 110                 && pcmk__str_eq(order->rh_action->task, RSC_STOP,
 111                                 pcmk__str_none)) {
 112                 continue;
 113             } else if ((order->rh_action == NULL)
 114                        && pcmk__ends_with(order->rh_action_task,
 115                                           "_" RSC_STOP "_0")) {
 116                 continue;
 117             }
 118         }
 119 
 120         
 121         if (pcmk_is_set(order->type, pe_order_apply_first_non_migratable)) {
 122             pe__set_order_flags(order_type,
 123                                 pe_order_apply_first_non_migratable);
 124         }
 125         if (pcmk_is_set(order->type, pe_order_same_node)) {
 126             pe__set_order_flags(order_type, pe_order_same_node);
 127         }
 128 
 129         
 130         if ((order->type == pe_order_anti_colocation)
 131             || (order->type == pe_order_load)) {
 132             order_type = order->type;
 133         }
 134 
 135         
 136         probes = pe__resource_actions(order->lh_rsc, NULL, RSC_STATUS, FALSE);
 137         if (probes == NULL) { 
 138             continue;
 139         }
 140 
 141         
 142         if (order->rh_action != NULL) {
 143             then_actions = g_list_prepend(NULL, order->rh_action);
 144 
 145         } else if (order->rh_rsc != NULL) {
 146             then_actions = find_actions(order->rh_rsc->actions,
 147                                         order->rh_action_task, NULL);
 148             if (then_actions == NULL) { 
 149                 g_list_free(probes);
 150                 continue;
 151             }
 152         }
 153 
 154         crm_trace("Implying 'probe then' orderings for '%s then %s' "
 155                   "(id=%d, type=%.6x)",
 156                   order->lh_action? order->lh_action->uuid : order->lh_action_task,
 157                   order->rh_action? order->rh_action->uuid : order->rh_action_task,
 158                   order->id, order->type);
 159 
 160         for (GList *probe_iter = probes; probe_iter != NULL;
 161              probe_iter = probe_iter->next) {
 162 
 163             pe_action_t *probe = (pe_action_t *) probe_iter->data;
 164 
 165             for (GList *then_iter = then_actions; then_iter != NULL;
 166                  then_iter = then_iter->next) {
 167 
 168                 pe_action_t *then = (pe_action_t *) then_iter->data;
 169 
 170                 if (probe_needed_before_action(probe, then)) {
 171                     order_actions(probe, then, order_type);
 172                 }
 173             }
 174         }
 175 
 176         g_list_free(then_actions);
 177         g_list_free(probes);
 178     }
 179 }
 180 
 181 
 182 
 183 
 184 
 185 
 186 
 187 
 188 
 189 
 190 
 191 
 192 
 193 
 194 static void
 195 add_restart_orderings_for_probe(pe_action_t *probe, pe_action_t *after,
     
 196                                 pe_working_set_t *data_set)
 197 {
 198     GList *iter = NULL;
 199     bool interleave = false;
 200     pe_resource_t *compatible_rsc = NULL;
 201 
 202     
 203     if ((after == NULL) || (probe == NULL) || (probe->rsc == NULL)
 204         || (probe->rsc->variant != pe_native)
 205         || !pcmk__str_eq(probe->task, RSC_STATUS, pcmk__str_casei)) {
 206         return;
 207     }
 208 
 209     
 210     if (pcmk_is_set(after->flags, pe_action_tracking)) {
 211         return;
 212     }
 213     pe__set_action_flags(after, pe_action_tracking);
 214 
 215     crm_trace("Adding probe restart orderings for '%s@%s then %s@%s'",
 216               probe->uuid,
 217               ((probe->node == NULL)? "" : probe->node->details->uname),
 218               after->uuid,
 219               ((after->node == NULL)? "" : after->node->details->uname));
 220 
 221     
 222 
 223 
 224     if ((after->rsc != NULL) && (after->rsc->variant == pe_native)
 225         && (probe->rsc != after->rsc)) {
 226 
 227             GList *then_actions = NULL;
 228 
 229             if (pcmk__str_eq(after->task, RSC_START, pcmk__str_casei)) {
 230                 then_actions = pe__resource_actions(after->rsc, NULL, RSC_STOP,
 231                                                     FALSE);
 232 
 233             } else if (pcmk__str_eq(after->task, RSC_PROMOTE, pcmk__str_casei)) {
 234                 then_actions = pe__resource_actions(after->rsc, NULL,
 235                                                     RSC_DEMOTE, FALSE);
 236             }
 237 
 238             for (iter = then_actions; iter != NULL; iter = iter->next) {
 239                 pe_action_t *then = (pe_action_t *) iter->data;
 240 
 241                 
 242                 if (!pcmk_is_set(then->flags, pe_action_pseudo)) {
 243                     order_actions(probe, then, pe_order_optional);
 244                 }
 245             }
 246             g_list_free(then_actions);
 247     }
 248 
 249     
 250 
 251 
 252     if ((after->rsc != NULL)
 253         && (after->rsc->variant > pe_group)) {
 254         const char *interleave_s = g_hash_table_lookup(after->rsc->meta,
 255                                                        XML_RSC_ATTR_INTERLEAVE);
 256 
 257         interleave = crm_is_true(interleave_s);
 258         if (interleave) {
 259             compatible_rsc = find_compatible_child(probe->rsc,
 260                                                    after->rsc,
 261                                                    RSC_ROLE_UNKNOWN,
 262                                                    FALSE, data_set);
 263         }
 264     }
 265 
 266     
 267 
 268 
 269 
 270     for (iter = after->actions_after; iter != NULL; iter = iter->next) {
 271         pe_action_wrapper_t *after_wrapper = (pe_action_wrapper_t *) iter->data;
 272 
 273         
 274 
 275 
 276 
 277 
 278 
 279 
 280 
 281         if (!pcmk_is_set(after_wrapper->type, pe_order_implies_then)) {
 282             
 283 
 284 
 285 
 286 
 287 
 288 
 289             if ((after->rsc == NULL)
 290                 || (after->rsc->variant < pe_group)
 291                 || (probe->rsc->parent == after->rsc)
 292                 || (after_wrapper->action->rsc == NULL)
 293                 || (after_wrapper->action->rsc->variant > pe_group)
 294                 || (after->rsc != after_wrapper->action->rsc->parent)) {
 295                 continue;
 296             }
 297 
 298             
 299 
 300 
 301             if ((after->rsc->variant > pe_group) && interleave
 302                 && ((compatible_rsc == NULL)
 303                     || (compatible_rsc != after_wrapper->action->rsc))) {
 304                 continue;
 305             }
 306         }
 307 
 308         crm_trace("Recursively adding probe restart orderings for "
 309                   "'%s@%s then %s@%s' (type=%#.6x)",
 310                   after->uuid,
 311                   ((after->node == NULL)? "" : after->node->details->uname),
 312                   after_wrapper->action->uuid,
 313                   ((after_wrapper->action->node == NULL)? "" : after_wrapper->action->node->details->uname),
 314                   after_wrapper->type);
 315 
 316         add_restart_orderings_for_probe(probe, after_wrapper->action, data_set);
 317     }
 318 }
 319 
 320 
 321 
 322 
 323 
 324 
 325 
 326 static void
 327 clear_actions_tracking_flag(pe_working_set_t *data_set)
     
 328 {
 329     GList *gIter = NULL;
 330 
 331     for (gIter = data_set->actions; gIter != NULL; gIter = gIter->next) {
 332         pe_action_t *action = (pe_action_t *) gIter->data;
 333 
 334         pe__clear_action_flags(action, pe_action_tracking);
 335     }
 336 }
 337 
 338 
 339 
 340 
 341 
 342 
 343 
 344 
 345 static void
 346 add_restart_orderings_for_rsc(pe_resource_t *rsc, pe_working_set_t *data_set)
     
 347 {
 348     GList *probes = NULL;
 349 
 350     
 351     if (rsc->variant != pe_native) {
 352         g_list_foreach(rsc->children, (GFunc) add_restart_orderings_for_rsc,
 353                        data_set);
 354         return;
 355     }
 356 
 357     
 358     probes = pe__resource_actions(rsc, NULL, RSC_STATUS, FALSE);
 359 
 360     
 361     for (GList *iter = probes; iter != NULL; iter = iter->next) {
 362         pe_action_t *probe = (pe_action_t *) iter->data;
 363 
 364         for (GList *then_iter = probe->actions_after; then_iter != NULL;
 365              then_iter = then_iter->next) {
 366 
 367             pe_action_wrapper_t *then = (pe_action_wrapper_t *) then_iter->data;
 368 
 369             add_restart_orderings_for_probe(probe, then->action, data_set);
 370             clear_actions_tracking_flag(data_set);
 371         }
 372     }
 373 
 374     g_list_free(probes);
 375 }
 376 
 377 
 378 
 379 
 380 
 381 
 382 
 383 
 384 
 385 static void
 386 order_then_probes(pe_working_set_t *data_set)
     
 387 {
 388 #if 0
 389     
 390 
 391 
 392 
 393 
 394 
 395 
 396 
 397 
 398 
 399 
 400 
 401 
 402 
 403 
 404 
 405 
 406 
 407 
 408 
 409 
 410 
 411 
 412 
 413 
 414 
 415 
 416 
 417 
 418     for (GList *iter = data_set->resources; iter != NULL; iter = iter->next) {
 419         pe_resource_t *rsc = (pe_resource_t *) iter->data;
 420 
 421         pe_action_t *start = NULL;
 422         GList *actions = NULL;
 423         GList *probes = NULL;
 424 
 425         actions = pe__resource_actions(rsc, NULL, RSC_START, FALSE);
 426 
 427         if (actions) {
 428             start = actions->data;
 429             g_list_free(actions);
 430         }
 431 
 432         if (start == NULL) {
 433             crm_err("No start action for %s", rsc->id);
 434             continue;
 435         }
 436 
 437         probes = pe__resource_actions(rsc, NULL, RSC_STATUS, FALSE);
 438 
 439         for (actions = start->actions_before; actions != NULL;
 440              actions = actions->next) {
 441 
 442             pe_action_wrapper_t *before = (pe_action_wrapper_t *) actions->data;
 443 
 444             pe_action_t *first = before->action;
 445             pe_resource_t *first_rsc = first->rsc;
 446 
 447             if (first->required_runnable_before) {
 448                 for (GList *clone_actions = first->actions_before;
 449                      clone_actions != NULL;
 450                      clone_actions = clone_actions->next) {
 451 
 452                     before = (pe_action_wrapper_t *) clone_actions->data;
 453 
 454                     crm_trace("Testing '%s then %s' for %s",
 455                               first->uuid, before->action->uuid, start->uuid);
 456 
 457                     CRM_ASSERT(before->action->rsc != NULL);
 458                     first_rsc = before->action->rsc;
 459                     break;
 460                 }
 461 
 462             } else if (!pcmk__str_eq(first->task, RSC_START, pcmk__str_none)) {
 463                 crm_trace("Not a start op %s for %s", first->uuid, start->uuid);
 464             }
 465 
 466             if (first_rsc == NULL) {
 467                 continue;
 468 
 469             } else if (uber_parent(first_rsc) == uber_parent(start->rsc)) {
 470                 crm_trace("Same parent %s for %s", first_rsc->id, start->uuid);
 471                 continue;
 472 
 473             } else if (!pe_rsc_is_clone(uber_parent(first_rsc))) {
 474                 crm_trace("Not a clone %s for %s", first_rsc->id, start->uuid);
 475                 continue;
 476             }
 477 
 478             crm_err("Applying %s before %s %d", first->uuid, start->uuid,
 479                     uber_parent(first_rsc)->variant);
 480 
 481             for (GList *probe_iter = probes; probe_iter != NULL;
 482                  probe_iter = probe_iter->next) {
 483 
 484                 pe_action_t *probe = (pe_action_t *) probe_iter->data;
 485 
 486                 crm_err("Ordering %s before %s", first->uuid, probe->uuid);
 487                 order_actions(first, probe, pe_order_optional);
 488             }
 489         }
 490     }
 491 #endif
 492 }
 493 
 494 void
 495 pcmk__order_probes(pe_working_set_t *data_set)
     
 496 {
 497     
 498     g_list_foreach(data_set->resources, (GFunc) add_restart_orderings_for_rsc,
 499                    data_set);
 500     add_probe_orderings_for_stops(data_set);
 501 
 502     order_then_probes(data_set);
 503 }
 504 
 505 
 506 
 507 
 508 
 509 
 510 
 511 
 512 
 513 void
 514 pcmk__schedule_probes(pe_working_set_t *data_set)
     
 515 {
 516     
 517     for (GList *iter = data_set->nodes; iter != NULL; iter = iter->next) {
 518         pe_node_t *node = (pe_node_t *) iter->data;
 519         const char *probed = NULL;
 520 
 521         if (!node->details->online) { 
 522             if (pcmk__is_failed_remote_node(node)) {
 523                 pe_fence_node(data_set, node,
 524                               "the connection is unrecoverable", FALSE);
 525             }
 526             continue;
 527 
 528         } else if (node->details->unclean) { 
 529             continue;
 530 
 531         } else if (!node->details->rsc_discovery_enabled) {
 532             
 533             continue;
 534         }
 535 
 536         
 537 
 538 
 539 
 540 
 541         probed = pe_node_attribute_raw(node, CRM_OP_PROBED);
 542         if (probed != NULL && crm_is_true(probed) == FALSE) {
 543             pe_action_t *probe_op = NULL;
 544 
 545             probe_op = custom_action(NULL,
 546                                      crm_strdup_printf("%s-%s", CRM_OP_REPROBE,
 547                                                        node->details->uname),
 548                                      CRM_OP_REPROBE, node, FALSE, TRUE,
 549                                      data_set);
 550             add_hash_param(probe_op->meta, XML_ATTR_TE_NOWAIT,
 551                            XML_BOOLEAN_TRUE);
 552             continue;
 553         }
 554 
 555         
 556         for (GList *rsc_iter = data_set->resources; rsc_iter != NULL;
 557              rsc_iter = rsc_iter->next) {
 558             pe_resource_t *rsc = (pe_resource_t *) rsc_iter->data;
 559 
 560             rsc->cmds->create_probe(rsc, node, NULL, FALSE, data_set);
 561         }
 562     }
 563 }