Exemple #1
0
node_t *
container_color(resource_t * rsc, node_t * prefer, pe_working_set_t * data_set)
{
    GListPtr containers = NULL;
    GListPtr nodes = NULL;
    container_variant_data_t *container_data = NULL;

    CRM_CHECK(rsc != NULL, return NULL);

    get_container_variant_data(container_data, rsc);

    set_bit(rsc->flags, pe_rsc_allocating);
    containers = get_container_list(rsc);

    dump_node_scores(show_scores ? 0 : scores_log_level, rsc, __FUNCTION__, rsc->allowed_nodes);

    nodes = g_hash_table_get_values(rsc->allowed_nodes);
    nodes = g_list_sort_with_data(nodes, sort_node_weight, NULL);
    containers = g_list_sort_with_data(containers, sort_clone_instance, data_set);
    distribute_children(rsc, containers, nodes,
                        container_data->replicas, container_data->replicas_per_host, data_set);
    g_list_free(nodes);
    g_list_free(containers);

    for (GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
        container_grouping_t *tuple = (container_grouping_t *)gIter->data;
        pe_node_t *docker_host = tuple->docker->allocated_to;

        CRM_ASSERT(tuple);
        if(tuple->ip) {
            tuple->ip->cmds->allocate(tuple->ip, prefer, data_set);
        }

        if(tuple->remote && is_remote_node(docker_host)) {
            /* We need 'nested' connection resources to be on the same
             * host because pacemaker-remoted only supports a single
             * active connection
             */
            rsc_colocation_new("child-remote-with-docker-remote", NULL,
                               INFINITY, tuple->remote, docker_host->details->remote_rsc, NULL, NULL, data_set);
        }

        if(tuple->remote) {
            tuple->remote->cmds->allocate(tuple->remote, prefer, data_set);
        }

        // Explicitly allocate tuple->child before the container->child
        if(tuple->child) {
            pe_node_t *node = NULL;
            GHashTableIter iter;
            g_hash_table_iter_init(&iter, tuple->child->allowed_nodes);
            while (g_hash_table_iter_next(&iter, NULL, (gpointer *) & node)) {
                if(node->details != tuple->node->details) {
                    node->weight = -INFINITY;
                } else if(migration_threshold_reached(tuple->child, node, data_set) == FALSE) {
                    node->weight = INFINITY;
                }
            }

            set_bit(tuple->child->parent->flags, pe_rsc_allocating);
            tuple->child->cmds->allocate(tuple->child, tuple->node, data_set);
            clear_bit(tuple->child->parent->flags, pe_rsc_allocating);
        }
    }

    if(container_data->child) {
        pe_node_t *node = NULL;
        GHashTableIter iter;
        g_hash_table_iter_init(&iter, container_data->child->allowed_nodes);
        while (g_hash_table_iter_next(&iter, NULL, (gpointer *) & node)) {
            if(is_child_container_node(container_data, node)) {
                node->weight = 0;
            } else {
                node->weight = -INFINITY;
            }
        }
        container_data->child->cmds->allocate(container_data->child, prefer, data_set);
    }

    clear_bit(rsc->flags, pe_rsc_allocating);
    clear_bit(rsc->flags, pe_rsc_provisional);
    return NULL;
}
Exemple #2
0
void
container_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
{
    container_variant_data_t *container_data = NULL;

    CRM_CHECK(rsc != NULL, return);

    get_container_variant_data(container_data, rsc);

    if(container_data->child) {
        new_rsc_order(rsc, RSC_START, container_data->child, RSC_START, pe_order_implies_first_printed, data_set);
        new_rsc_order(rsc, RSC_STOP, container_data->child, RSC_STOP, pe_order_implies_first_printed, data_set);

        if(container_data->child->children) {
            new_rsc_order(container_data->child, RSC_STARTED, rsc, RSC_STARTED, pe_order_implies_then_printed, data_set);
            new_rsc_order(container_data->child, RSC_STOPPED, rsc, RSC_STOPPED, pe_order_implies_then_printed, data_set);
        } else {
            new_rsc_order(container_data->child, RSC_START, rsc, RSC_STARTED, pe_order_implies_then_printed, data_set);
            new_rsc_order(container_data->child, RSC_STOP, rsc, RSC_STOPPED, pe_order_implies_then_printed, data_set);
        }
    }

    for (GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
        container_grouping_t *tuple = (container_grouping_t *)gIter->data;

        CRM_ASSERT(tuple);
        CRM_ASSERT(tuple->docker);

        tuple->docker->cmds->internal_constraints(tuple->docker, data_set);

        order_start_start(rsc, tuple->docker, pe_order_runnable_left | pe_order_implies_first_printed);

        if(tuple->child) {
            order_stop_stop(rsc, tuple->child, pe_order_implies_first_printed);
        }
        order_stop_stop(rsc, tuple->docker, pe_order_implies_first_printed);
        new_rsc_order(tuple->docker, RSC_START, rsc, RSC_STARTED, pe_order_implies_then_printed, data_set);
        new_rsc_order(tuple->docker, RSC_STOP, rsc, RSC_STOPPED, pe_order_implies_then_printed, data_set);

        if(tuple->ip) {
            tuple->ip->cmds->internal_constraints(tuple->ip, data_set);

            // Start ip then docker
            new_rsc_order(tuple->ip, RSC_START, tuple->docker, RSC_START,
                          pe_order_runnable_left|pe_order_preserve, data_set);
            new_rsc_order(tuple->docker, RSC_STOP, tuple->ip, RSC_STOP,
                          pe_order_implies_first|pe_order_preserve, data_set);

            rsc_colocation_new("ip-with-docker", NULL, INFINITY, tuple->ip, tuple->docker, NULL, NULL, data_set);
        }

        if(tuple->remote) {
            /* This handles ordering and colocating remote relative to docker
             * (via "resource-with-container"). Since IP is also ordered and
             * colocated relative to docker, we don't need to do anything
             * explicit here with IP.
             */
            tuple->remote->cmds->internal_constraints(tuple->remote, data_set);
        }

        if(tuple->child) {
            CRM_ASSERT(tuple->remote);

            // Start of the remote then child is implicit in the PE's remote logic
        }

    }

    if(container_data->child) {
        container_data->child->cmds->internal_constraints(container_data->child, data_set);
        if(container_data->child->variant == pe_master) {
            master_promotion_constraints(rsc, data_set);

            /* child demoted before global demoted */
            new_rsc_order(container_data->child, RSC_DEMOTED, rsc, RSC_DEMOTED, pe_order_implies_then_printed, data_set);

            /* global demote before child demote */
            new_rsc_order(rsc, RSC_DEMOTE, container_data->child, RSC_DEMOTE, pe_order_implies_first_printed, data_set);

            /* child promoted before global promoted */
            new_rsc_order(container_data->child, RSC_PROMOTED, rsc, RSC_PROMOTED, pe_order_implies_then_printed, data_set);

            /* global promote before child promote */
            new_rsc_order(rsc, RSC_PROMOTE, container_data->child, RSC_PROMOTE, pe_order_implies_first_printed, data_set);
        }

    } else {
//    int type = pe_order_optional | pe_order_implies_then | pe_order_restart;
//        custom_action_order(rsc, generate_op_key(rsc->id, RSC_STOP, 0), NULL,
//                            rsc, generate_op_key(rsc->id, RSC_START, 0), NULL, pe_order_optional, data_set);
    }
}
Exemple #3
0
void
group_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
{
    GListPtr gIter = rsc->children;
    resource_t *last_rsc = NULL;
    resource_t *top = uber_parent(rsc);
    group_variant_data_t *group_data = NULL;

    get_group_variant_data(group_data, rsc);

    new_rsc_order(rsc, RSC_STOPPED, rsc, RSC_START, pe_order_optional, data_set);
    new_rsc_order(rsc, RSC_START, rsc, RSC_STARTED, pe_order_runnable_left, data_set);
    new_rsc_order(rsc, RSC_STOP, rsc, RSC_STOPPED, pe_order_runnable_left, data_set);

    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child_rsc = (resource_t *) gIter->data;
        int stop = pe_order_none;
        int stopped = pe_order_implies_then_printed;
        int start = pe_order_implies_then | pe_order_runnable_left;
        int started =
            pe_order_runnable_left | pe_order_implies_then | pe_order_implies_then_printed;

        child_rsc->cmds->internal_constraints(child_rsc, data_set);

        if (last_rsc == NULL) {
            if (group_data->ordered) {
                stop |= pe_order_optional;
                stopped = pe_order_implies_then;
            }

        } else if (group_data->colocated) {
            rsc_colocation_new("group:internal_colocation", NULL, INFINITY,
                               child_rsc, last_rsc, NULL, NULL, data_set);
        }

        if (top->variant == pe_master) {
            new_rsc_order(rsc, RSC_DEMOTE, child_rsc, RSC_DEMOTE,
                          stop | pe_order_implies_first_printed, data_set);

            new_rsc_order(child_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stopped, data_set);

            new_rsc_order(child_rsc, RSC_PROMOTE, rsc, RSC_PROMOTED, started, data_set);

            new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE,
                          pe_order_implies_first_printed, data_set);

        }

        order_start_start(rsc, child_rsc, pe_order_implies_first_printed);
        order_stop_stop(rsc, child_rsc, stop | pe_order_implies_first_printed);

        new_rsc_order(child_rsc, RSC_STOP, rsc, RSC_STOPPED, stopped, data_set);

        new_rsc_order(child_rsc, RSC_START, rsc, RSC_STARTED, started, data_set);

        if (group_data->ordered == FALSE) {
            order_start_start(rsc, child_rsc, start | pe_order_implies_first_printed);
            if (top->variant == pe_master) {
                new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE,
                              start | pe_order_implies_first_printed, data_set);
            }

        } else if (last_rsc != NULL) {
            child_rsc->restart_type = pe_restart_restart;

            order_start_start(last_rsc, child_rsc, start);
            order_stop_stop(child_rsc, last_rsc, pe_order_optional);

            if (top->variant == pe_master) {
                new_rsc_order(last_rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, start, data_set);
                new_rsc_order(child_rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, pe_order_optional,
                              data_set);
            }

        } else {
            /* If anyone in the group is starting, then
             *  pe_order_implies_then will cause _everyone_ in the group
             *  to be sent a start action
             * But this is safe since starting something that is already
             *  started is required to be "safe"
             */
            int flags = pe_order_none;

            order_start_start(rsc, child_rsc, flags);
            if (top->variant == pe_master) {
                new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, flags, data_set);
            }

        }

        last_rsc = child_rsc;
    }

    if (group_data->ordered && last_rsc != NULL) {
        int stop_stop_flags = pe_order_implies_then;
        int stop_stopped_flags = pe_order_optional;

        order_stop_stop(rsc, last_rsc, stop_stop_flags);
        new_rsc_order(last_rsc, RSC_STOP, rsc, RSC_STOPPED, stop_stopped_flags, data_set);

        if (top->variant == pe_master) {
            new_rsc_order(rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, stop_stop_flags, data_set);
            new_rsc_order(last_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stop_stopped_flags, data_set);
        }
    }
}