This source file includes following definitions.
- add_migration_meta
 
- pcmk__create_migration_actions
 
- pcmk__abort_dangling_migration
 
- pcmk__rsc_can_migrate
 
- task_from_action_or_key
 
- pcmk__order_migration_equivalents
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <stdbool.h>
  13 
  14 #include <crm/msg_xml.h>
  15 #include <pacemaker-internal.h>
  16 
  17 #include "libpacemaker_private.h"
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 static void
  28 add_migration_meta(pe_action_t *action, const pe_node_t *source,
     
  29                    const pe_node_t *target)
  30 {
  31     add_hash_param(action->meta, XML_LRM_ATTR_MIGRATE_SOURCE,
  32                    source->details->uname);
  33 
  34     add_hash_param(action->meta, XML_LRM_ATTR_MIGRATE_TARGET,
  35                    target->details->uname);
  36 }
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 void
  46 pcmk__create_migration_actions(pe_resource_t *rsc, const pe_node_t *current)
     
  47 {
  48     pe_action_t *migrate_to = NULL;
  49     pe_action_t *migrate_from = NULL;
  50     pe_action_t *start = NULL;
  51     pe_action_t *stop = NULL;
  52 
  53     pe_rsc_trace(rsc, "Creating actions to %smigrate %s from %s to %s",
  54                  ((rsc->partial_migration_target == NULL)? "" : "partially "),
  55                  rsc->id, pe__node_name(current),
  56                  pe__node_name(rsc->allocated_to));
  57     start = start_action(rsc, rsc->allocated_to, TRUE);
  58     stop = stop_action(rsc, current, TRUE);
  59 
  60     if (rsc->partial_migration_target == NULL) {
  61         migrate_to = custom_action(rsc, pcmk__op_key(rsc->id, RSC_MIGRATE, 0),
  62                                    RSC_MIGRATE, current, TRUE, TRUE,
  63                                    rsc->cluster);
  64     }
  65     migrate_from = custom_action(rsc, pcmk__op_key(rsc->id, RSC_MIGRATED, 0),
  66                                  RSC_MIGRATED, rsc->allocated_to, TRUE, TRUE,
  67                                  rsc->cluster);
  68 
  69     if ((migrate_from != NULL)
  70         && ((migrate_to != NULL) || (rsc->partial_migration_target != NULL))) {
  71 
  72         pe__set_action_flags(start, pe_action_migrate_runnable);
  73         pe__set_action_flags(stop, pe_action_migrate_runnable);
  74 
  75         
  76         pe__set_action_flags(start, pe_action_pseudo);
  77 
  78         if (rsc->partial_migration_target == NULL) {
  79             pe__set_action_flags(migrate_from, pe_action_migrate_runnable);
  80 
  81             if (migrate_to != NULL) {
  82                 pe__set_action_flags(migrate_to, pe_action_migrate_runnable);
  83                 migrate_to->needs = start->needs;
  84             }
  85 
  86             
  87             pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_STATUS, 0), NULL,
  88                                rsc, pcmk__op_key(rsc->id, RSC_MIGRATE, 0),
  89                                NULL, pe_order_optional, rsc->cluster);
  90             pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_MIGRATE, 0), NULL,
  91                                rsc, pcmk__op_key(rsc->id, RSC_MIGRATED, 0),
  92                                NULL,
  93                                pe_order_optional|pe_order_implies_first_migratable,
  94                                rsc->cluster);
  95         } else {
  96             pe__set_action_flags(migrate_from, pe_action_migrate_runnable);
  97             migrate_from->needs = start->needs;
  98 
  99             
 100             pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_STATUS, 0), NULL,
 101                                rsc, pcmk__op_key(rsc->id, RSC_MIGRATED, 0),
 102                                NULL, pe_order_optional, rsc->cluster);
 103         }
 104 
 105         
 106         pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_MIGRATED, 0), NULL,
 107                            rsc, pcmk__op_key(rsc->id, RSC_STOP, 0), NULL,
 108                            pe_order_optional|pe_order_implies_first_migratable,
 109                            rsc->cluster);
 110         pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_MIGRATED, 0), NULL,
 111                            rsc, pcmk__op_key(rsc->id, RSC_START, 0), NULL,
 112                            pe_order_optional|pe_order_implies_first_migratable|pe_order_pseudo_left,
 113                            rsc->cluster);
 114     }
 115 
 116     if (migrate_to != NULL) {
 117         add_migration_meta(migrate_to, current, rsc->allocated_to);
 118 
 119         if (!rsc->is_remote_node) {
 120             
 121 
 122 
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131             add_hash_param(migrate_to->meta, XML_OP_ATTR_PENDING, "true");
 132         }
 133     }
 134 
 135     if (migrate_from != NULL) {
 136         add_migration_meta(migrate_from, current, rsc->allocated_to);
 137     }
 138 }
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 
 147 void
 148 pcmk__abort_dangling_migration(void *data, void *user_data)
     
 149 {
 150     const pe_node_t *dangling_source = (const pe_node_t *) data;
 151     pe_resource_t *rsc = (pe_resource_t *) user_data;
 152 
 153     pe_action_t *stop = NULL;
 154     bool cleanup = pcmk_is_set(rsc->cluster->flags, pe_flag_remove_after_stop);
 155 
 156     pe_rsc_trace(rsc,
 157                  "Scheduling stop%s for %s on %s due to dangling migration",
 158                  (cleanup? " and cleanup" : ""), rsc->id,
 159                  pe__node_name(dangling_source));
 160     stop = stop_action(rsc, dangling_source, FALSE);
 161     pe__set_action_flags(stop, pe_action_dangle);
 162     if (cleanup) {
 163         pcmk__schedule_cleanup(rsc, dangling_source, false);
 164     }
 165 }
 166 
 167 
 168 
 169 
 170 
 171 
 172 
 173 
 174 
 175 
 176 bool
 177 pcmk__rsc_can_migrate(const pe_resource_t *rsc, const pe_node_t *current)
     
 178 {
 179     CRM_CHECK(rsc != NULL, return false);
 180 
 181     if (!pcmk_is_set(rsc->flags, pe_rsc_allow_migrate)) {
 182         pe_rsc_trace(rsc, "%s cannot migrate because "
 183                           "the configuration does not allow it",
 184                      rsc->id);
 185         return false;
 186     }
 187 
 188     if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
 189         pe_rsc_trace(rsc, "%s cannot migrate because it is not managed",
 190                      rsc->id);
 191         return false;
 192     }
 193 
 194     if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
 195         pe_rsc_trace(rsc, "%s cannot migrate because it is failed",
 196                      rsc->id);
 197         return false;
 198     }
 199 
 200     if (pcmk_is_set(rsc->flags, pe_rsc_start_pending)) {
 201         pe_rsc_trace(rsc, "%s cannot migrate because it has a start pending",
 202                      rsc->id);
 203         return false;
 204     }
 205 
 206     if ((current == NULL) || current->details->unclean) {
 207         pe_rsc_trace(rsc, "%s cannot migrate because "
 208                           "its current node (%s) is unclean",
 209                      rsc->id, pe__node_name(current));
 210         return false;
 211     }
 212 
 213     if ((rsc->allocated_to == NULL) || rsc->allocated_to->details->unclean) {
 214         pe_rsc_trace(rsc, "%s cannot migrate because "
 215                           "its next node (%s) is unclean",
 216                      rsc->id, pe__node_name(rsc->allocated_to));
 217         return false;
 218     }
 219 
 220     return true;
 221 }
 222 
 223 
 224 
 225 
 226 
 227 
 228 
 229 
 230 
 231 
 232 static char *
 233 task_from_action_or_key(const pe_action_t *action, const char *key)
     
 234 {
 235     char *res = NULL;
 236 
 237     if (action != NULL) {
 238         res = strdup(action->task);
 239         CRM_ASSERT(res != NULL);
 240     } else if (key != NULL) {
 241         parse_op_key(key, NULL, &res, NULL);
 242     }
 243     return res;
 244 }
 245 
 246 
 247 
 248 
 249 
 250 
 251 
 252 
 253 
 254 
 255 
 256 void
 257 pcmk__order_migration_equivalents(pe__ordering_t *order)
     
 258 {
 259     char *first_task = NULL;
 260     char *then_task = NULL;
 261     bool then_migratable;
 262     bool first_migratable;
 263 
 264     
 265     if ((order->lh_rsc == NULL) || (order->rh_rsc == NULL)
 266         || (order->lh_rsc == order->rh_rsc)
 267         || is_parent(order->lh_rsc, order->rh_rsc)
 268         || is_parent(order->rh_rsc, order->lh_rsc)) {
 269         return;
 270     }
 271 
 272     
 273     first_migratable = pcmk_is_set(order->lh_rsc->flags, pe_rsc_allow_migrate);
 274     then_migratable = pcmk_is_set(order->rh_rsc->flags, pe_rsc_allow_migrate);
 275     if (!first_migratable && !then_migratable) {
 276         return;
 277     }
 278 
 279     
 280     first_task = task_from_action_or_key(order->lh_action,
 281                                          order->lh_action_task);
 282     then_task = task_from_action_or_key(order->rh_action,
 283                                         order->rh_action_task);
 284 
 285     if (pcmk__str_eq(first_task, RSC_START, pcmk__str_none)
 286         && pcmk__str_eq(then_task, RSC_START, pcmk__str_none)) {
 287 
 288         uint32_t flags = pe_order_optional;
 289 
 290         if (first_migratable && then_migratable) {
 291             
 292 
 293             pcmk__new_ordering(order->lh_rsc,
 294                                pcmk__op_key(order->lh_rsc->id, RSC_MIGRATED, 0),
 295                                NULL, order->rh_rsc,
 296                                pcmk__op_key(order->rh_rsc->id, RSC_MIGRATE, 0),
 297                                NULL, flags, order->lh_rsc->cluster);
 298         }
 299 
 300         if (then_migratable) {
 301             if (first_migratable) {
 302                 pe__set_order_flags(flags, pe_order_apply_first_non_migratable);
 303             }
 304 
 305             
 306 
 307 
 308 
 309             pcmk__new_ordering(order->lh_rsc,
 310                                pcmk__op_key(order->lh_rsc->id, RSC_START, 0),
 311                                NULL, order->rh_rsc,
 312                                pcmk__op_key(order->rh_rsc->id, RSC_MIGRATE, 0),
 313                                NULL, flags, order->lh_rsc->cluster);
 314         }
 315 
 316     } else if (then_migratable
 317                && pcmk__str_eq(first_task, RSC_STOP, pcmk__str_none)
 318                && pcmk__str_eq(then_task, RSC_STOP, pcmk__str_none)) {
 319 
 320         uint32_t flags = pe_order_optional;
 321 
 322         if (first_migratable) {
 323             pe__set_order_flags(flags, pe_order_apply_first_non_migratable);
 324         }
 325 
 326         
 327 
 328 
 329         pcmk__new_ordering(order->lh_rsc,
 330                            pcmk__op_key(order->lh_rsc->id, RSC_STOP, 0), NULL,
 331                            order->rh_rsc,
 332                            pcmk__op_key(order->rh_rsc->id, RSC_MIGRATE, 0),
 333                            NULL, flags, order->lh_rsc->cluster);
 334 
 335         
 336         if (order->rh_rsc->partial_migration_target) {
 337             pcmk__new_ordering(order->lh_rsc,
 338                                pcmk__op_key(order->lh_rsc->id, RSC_STOP, 0),
 339                                NULL, order->rh_rsc,
 340                                pcmk__op_key(order->rh_rsc->id, RSC_MIGRATED, 0),
 341                                NULL, flags, order->lh_rsc->cluster);
 342         }
 343 
 344     } else if (pcmk__str_eq(first_task, RSC_PROMOTE, pcmk__str_none)
 345                && pcmk__str_eq(then_task, RSC_START, pcmk__str_none)) {
 346 
 347         uint32_t flags = pe_order_optional;
 348 
 349         if (then_migratable) {
 350             
 351 
 352             pcmk__new_ordering(order->lh_rsc,
 353                                pcmk__op_key(order->lh_rsc->id, RSC_PROMOTE, 0),
 354                                NULL, order->rh_rsc,
 355                                pcmk__op_key(order->rh_rsc->id, RSC_MIGRATE, 0),
 356                                NULL, flags, order->lh_rsc->cluster);
 357         }
 358 
 359     } else if (pcmk__str_eq(first_task, RSC_DEMOTE, pcmk__str_none)
 360                && pcmk__str_eq(then_task, RSC_STOP, pcmk__str_none)) {
 361 
 362         uint32_t flags = pe_order_optional;
 363 
 364         if (then_migratable) {
 365             
 366 
 367             pcmk__new_ordering(order->lh_rsc,
 368                                pcmk__op_key(order->lh_rsc->id, RSC_DEMOTE, 0),
 369                                NULL, order->rh_rsc,
 370                                pcmk__op_key(order->rh_rsc->id, RSC_MIGRATE, 0),
 371                                NULL, flags, order->lh_rsc->cluster);
 372 
 373             
 374             if (order->rh_rsc->partial_migration_target) {
 375                 pcmk__new_ordering(order->lh_rsc,
 376                                    pcmk__op_key(order->lh_rsc->id, RSC_DEMOTE, 0),
 377                                    NULL, order->rh_rsc,
 378                                    pcmk__op_key(order->rh_rsc->id, RSC_MIGRATED, 0),
 379                                    NULL, flags, order->lh_rsc->cluster);
 380             }
 381         }
 382     }
 383 
 384     free(first_task);
 385     free(then_task);
 386 }