| 325 | } |
| 326 | |
| 327 | GHashTable * |
| 328 | rsc_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes, const char *attr, |
| 329 | float factor, enum pe_weights flags) |
| 330 | { |
| 331 | GHashTable *work = NULL; |
| 332 | int multiplier = 1; |
| 333 | |
| 334 | if (factor < 0) { |
| 335 | multiplier = -1; |
| 336 | } |
| 337 | |
| 338 | if (is_set(rsc->flags, pe_rsc_merging)) { |
| 339 | pe_rsc_info(rsc, "%s: Breaking dependency loop at %s", rhs, rsc->id); |
| 340 | return nodes; |
| 341 | } |
| 342 | |
| 343 | set_bit(rsc->flags, pe_rsc_merging); |
| 344 | |
| 345 | if (is_set(flags, pe_weights_init)) { |
| 346 | if (rsc->variant == pe_group && rsc->children) { |
| 347 | GListPtr last = rsc->children; |
| 348 | |
| 349 | while (last->next != NULL) { |
| 350 | last = last->next; |
| 351 | } |
| 352 | |
| 353 | pe_rsc_trace(rsc, "Merging %s as a group %p %p", rsc->id, rsc->children, last); |
| 354 | work = rsc_merge_weights(last->data, rhs, NULL, attr, factor, flags); |
| 355 | |
| 356 | } else { |
| 357 | work = node_hash_dup(rsc->allowed_nodes); |
| 358 | } |
| 359 | clear_bit(flags, pe_weights_init); |
| 360 | |
| 361 | } else { |
| 362 | pe_rsc_trace(rsc, "%s: Combining scores from %s", rhs, rsc->id); |
| 363 | work = node_hash_dup(nodes); |
| 364 | node_hash_update(work, rsc->allowed_nodes, attr, factor, |
| 365 | is_set(flags, pe_weights_positive)); |
| 366 | } |
| 367 | |
| 368 | if (is_set(flags, pe_weights_rollback) && can_run_any(work) == FALSE) { |
| 369 | pe_rsc_info(rsc, "%s: Rolling back scores from %s", rhs, rsc->id); |
| 370 | g_hash_table_destroy(work); |
| 371 | clear_bit(rsc->flags, pe_rsc_merging); |
| 372 | return nodes; |
| 373 | } |
| 374 | |
| 375 | if (can_run_any(work)) { |
| 376 | GListPtr gIter = NULL; |
| 377 | |
| 378 | if (is_set(flags, pe_weights_forward)) { |
| 379 | gIter = rsc->rsc_cons; |
| 380 | } else { |
| 381 | gIter = rsc->rsc_cons_lhs; |
| 382 | } |
| 383 | |
| 384 | for (; gIter != NULL; gIter = gIter->next) { |
no test coverage detected