예제 #1
0
void
distribute_children(resource_t *rsc, GListPtr children, GListPtr nodes,
                    int max, int per_host_max, pe_working_set_t * data_set) 
{
    int loop_max = 0;
    int allocated = 0;
    int available_nodes = 0;

    /* count now tracks the number of clones currently allocated */
    for(GListPtr nIter = nodes; nIter != NULL; nIter = nIter->next) {
        pe_node_t *node = nIter->data;

        node->count = 0;
        if (can_run_resources(node)) {
            available_nodes++;
        }
    }

    if(available_nodes) {
        loop_max = max / available_nodes;
    }
    if (loop_max < 1) {
        loop_max = 1;
    }

    pe_rsc_debug(rsc, "Allocating up to %d %s instances to a possible %d nodes (at most %d per host, %d optimal)",
                 max, rsc->id, available_nodes, per_host_max, loop_max);

    /* Pre-allocate as many instances as we can to their current location */
    for (GListPtr gIter = children; gIter != NULL && allocated < max; gIter = gIter->next) {
        resource_t *child = (resource_t *) gIter->data;

        if (child->running_on && is_set(child->flags, pe_rsc_provisional)
            && is_not_set(child->flags, pe_rsc_failed)) {
            node_t *child_node = pe__current_node(child);
            node_t *local_node = parent_node_instance(child, child_node);

            pe_rsc_trace(rsc, "Checking pre-allocation of %s to %s (%d remaining of %d)",
                         child->id, child_node->details->uname, max - allocated, max);

            if (can_run_resources(child_node) == FALSE || child_node->weight < 0) {
                pe_rsc_trace(rsc, "Not pre-allocating because %s can not run %s",
                             child_node->details->uname, child->id);

            } else if(local_node && local_node->count >= loop_max) {
                pe_rsc_trace(rsc,
                             "Not pre-allocating because %s already allocated optimal instances",
                             child_node->details->uname);

            } else if (color_instance(child, child_node, max < available_nodes, per_host_max, data_set)) {
                pe_rsc_trace(rsc, "Pre-allocated %s to %s", child->id,
                             child_node->details->uname);
                allocated++;
            }
        }
    }

    pe_rsc_trace(rsc, "Done pre-allocating (%d of %d)", allocated, max);

    for (GListPtr gIter = children; gIter != NULL; gIter = gIter->next) {
        resource_t *child = (resource_t *) gIter->data;

        if (child->running_on != NULL) {
            node_t *child_node = pe__current_node(child);
            node_t *local_node = parent_node_instance(child, child_node);

            if (local_node == NULL) {
                crm_err("%s is running on %s which isn't allowed",
                        child->id, child_node->details->uname);
            }
        }

        if (is_not_set(child->flags, pe_rsc_provisional)) {
        } else if (allocated >= max) {
            pe_rsc_debug(rsc, "Child %s not allocated - limit reached %d %d", child->id, allocated, max);
            resource_location(child, NULL, -INFINITY, "clone_color:limit_reached", data_set);
        } else {
            if (color_instance(child, NULL, max < available_nodes, per_host_max, data_set)) {
                allocated++;
            }
        }
    }

    pe_rsc_debug(rsc, "Allocated %d %s instances of a possible %d",
                 allocated, rsc->id, max);
}
예제 #2
0
파일: master.c 프로젝트: smellman/pacemaker
static void
master_promotion_order(resource_t * rsc, pe_working_set_t * data_set)
{
    GListPtr gIter = NULL;
    node_t *node = NULL;
    node_t *chosen = NULL;
    clone_variant_data_t *clone_data = NULL;

    get_clone_variant_data(clone_data, rsc);

    if (clone_data->merged_master_weights) {
        return;
    }
    clone_data->merged_master_weights = TRUE;
    crm_trace("Merging weights for %s", rsc->id);
    set_bit(rsc->flags, pe_rsc_merging);

    gIter = rsc->children;
    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child = (resource_t *) gIter->data;

        crm_trace("Sort index: %s = %d", child->id, child->sort_index);
    }
    dump_node_scores(LOG_DEBUG_3, rsc, "Before", rsc->allowed_nodes);

    gIter = rsc->children;
    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child = (resource_t *) gIter->data;

        chosen = child->fns->location(child, NULL, FALSE);
        if (chosen == NULL || child->sort_index < 0) {
            crm_trace("Skipping %s", child->id);
            continue;
        }

        node = (node_t *) pe_hash_table_lookup(rsc->allowed_nodes, chosen->details->id);
        CRM_ASSERT(node != NULL);
        /* adds in master preferences and rsc_location.role=Master */
        crm_trace("Adding %s to %s from %s", score2char(child->sort_index), node->details->uname,
                  child->id);
        node->weight = merge_weights(child->sort_index, node->weight);
    }

    dump_node_scores(LOG_DEBUG_3, rsc, "Middle", rsc->allowed_nodes);

    gIter = rsc->rsc_cons;
    for (; gIter != NULL; gIter = gIter->next) {
        rsc_colocation_t *constraint = (rsc_colocation_t *) gIter->data;

        /* (re-)adds location preferences of resources that the
         * master instance should/must be colocated with
         */
        if (constraint->role_lh == RSC_ROLE_MASTER) {
            crm_trace("RHS: %s with %s: %d", constraint->rsc_lh->id, constraint->rsc_rh->id,
                        constraint->score);
            rsc->allowed_nodes =
                constraint->rsc_rh->cmds->merge_weights(constraint->rsc_rh, rsc->id,
                                                        rsc->allowed_nodes,
                                                        constraint->node_attribute,
                                                        constraint->score / INFINITY,
                                                        constraint->score ==
                                                        INFINITY ? FALSE : TRUE, FALSE);
        }
    }

    gIter = rsc->rsc_cons_lhs;
    for (; gIter != NULL; gIter = gIter->next) {
        rsc_colocation_t *constraint = (rsc_colocation_t *) gIter->data;

        /* (re-)adds location preferences of resource that wish to be
         * colocated with the master instance
         */
        if (constraint->role_rh == RSC_ROLE_MASTER) {
            crm_trace("LHS: %s with %s: %d", constraint->rsc_lh->id, constraint->rsc_rh->id,
                        constraint->score);
            rsc->allowed_nodes =
                constraint->rsc_lh->cmds->merge_weights(constraint->rsc_lh, rsc->id,
                                                        rsc->allowed_nodes,
                                                        constraint->node_attribute,
                                                        constraint->score / INFINITY, TRUE, TRUE);
        }
    }

    gIter = rsc->rsc_tickets;
    for (; gIter != NULL; gIter = gIter->next) {
        rsc_ticket_t *rsc_ticket = (rsc_ticket_t *) gIter->data;

        if (rsc_ticket->role_lh == RSC_ROLE_MASTER && rsc_ticket->ticket->granted == FALSE) {
            resource_location(rsc, NULL, -INFINITY, "__stateful_without_ticket__", data_set);
        }
    }

    dump_node_scores(LOG_DEBUG_3, rsc, "After", rsc->allowed_nodes);

    /* write them back and sort */

    gIter = rsc->children;
    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child = (resource_t *) gIter->data;

        chosen = child->fns->location(child, NULL, FALSE);
        if (is_not_set(child->flags, pe_rsc_managed) && child->next_role == RSC_ROLE_MASTER) {
            child->sort_index = INFINITY;

        } else if (chosen == NULL || child->sort_index < 0) {
            crm_trace("%s: %d", child->id, child->sort_index);

        } else {
            node = (node_t *) pe_hash_table_lookup(rsc->allowed_nodes, chosen->details->id);
            CRM_ASSERT(node != NULL);

            child->sort_index = node->weight;
        }
        crm_trace("Set sort index: %s = %d", child->id, child->sort_index);
    }

    rsc->children = g_list_sort_with_data(rsc->children, sort_master_instance, data_set);
    clear_bit(rsc->flags, pe_rsc_merging);
}
예제 #3
0
void
process_utilization(resource_t * rsc, node_t ** prefer, pe_working_set_t * data_set)
{
    int alloc_details = scores_log_level + 1;

    if (safe_str_neq(data_set->placement_strategy, "default")) {
        GListPtr gIter = NULL;
        GListPtr colocated_rscs = NULL;
        gboolean any_capable = FALSE;

        colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, rsc);
        if (colocated_rscs) {
            GHashTable *unallocated_utilization = NULL;
            char *rscs_id = crm_concat(rsc->id, "and its colocated resources", ' ');
            node_t *most_capable_node = NULL;

            unallocated_utilization = sum_unallocated_utilization(rsc, colocated_rscs);

            for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
                node_t *node = (node_t *) gIter->data;

                if (have_enough_capacity(node, rscs_id, unallocated_utilization)) {
                    any_capable = TRUE;
                }

                if (most_capable_node == NULL ||
                    compare_capacity(node, most_capable_node) < 0) {
                    /* < 0 means 'node' is more capable */
                    most_capable_node = node;
                }
            }

            if (any_capable) {
                for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
                    node_t *node = (node_t *) gIter->data;

                    if (have_enough_capacity(node, rscs_id, unallocated_utilization) == FALSE) {
                        pe_rsc_debug(rsc, "Resource %s and its colocated resources cannot be allocated to node %s: no enough capacity",
                                     rsc->id, node->details->uname);
                        resource_location(rsc, node, -INFINITY, "__limit_utilization__", data_set);
                    }
                }

            } else if (*prefer == NULL) {
                *prefer = most_capable_node;
            }

            if (unallocated_utilization) {
                g_hash_table_destroy(unallocated_utilization);
            }

            g_list_free(colocated_rscs);
            free(rscs_id);
        }

        if (any_capable == FALSE) {
            for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
                node_t *node = (node_t *) gIter->data;

                if (have_enough_capacity(node, rsc->id, rsc->utilization) == FALSE) {
                    pe_rsc_debug(rsc, "Resource %s cannot be allocated to node %s: no enough capacity",
                                 rsc->id, node->details->uname);
                    resource_location(rsc, node, -INFINITY, "__limit_utilization__", data_set);
                }
            }
        }
        dump_node_scores(alloc_details, rsc, "Post-utilization", rsc->allowed_nodes);
    }
}