Beispiel #1
0
gboolean
is_child_compatible(resource_t *child_rsc, node_t * local_node, enum rsc_role_e filter, gboolean current) 
{
    node_t *node = NULL;
    enum rsc_role_e next_role = child_rsc->fns->state(child_rsc, current);

    CRM_CHECK(child_rsc && local_node, return FALSE);
    if (is_set_recursive(child_rsc, pe_rsc_block, TRUE) == FALSE) {
        /* We only want instances that haven't failed */
        node = child_rsc->fns->location(child_rsc, NULL, current);
    }

    if (filter != RSC_ROLE_UNKNOWN && next_role != filter) {
        crm_trace("Filtered %s", child_rsc->id);
        return FALSE;
    }

    if (node && (node->details == local_node->details)) {
        return TRUE;

    } else if (node) {
        crm_trace("%s - %s vs %s", child_rsc->id, node->details->uname,
                  local_node->details->uname);

    } else {
        crm_trace("%s - not allocated %d", child_rsc->id, current);
    }
    return FALSE;
}
Beispiel #2
0
bool is_set_recursive(resource_t * rsc, long long flag, bool any)
{
    GListPtr gIter;
    bool all = !any;

    if(is_set(rsc->flags, flag)) {
        if(any) {
            return TRUE;
        }
    } else if(all) {
        return FALSE;
    }

    for (gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
        if(is_set_recursive(gIter->data, flag, any)) {
            if(any) {
                return TRUE;
            }

        } else if(all) {
            return FALSE;
        }
    }

    if(all) {
        return TRUE;
    }
    return FALSE;
}
Beispiel #3
0
void
clone_rsc_colocation_rh(pe_resource_t *rsc_lh, pe_resource_t *rsc_rh,
                        rsc_colocation_t *constraint,
                        pe_working_set_t *data_set)
{
    GListPtr gIter = NULL;
    gboolean do_interleave = FALSE;
    const char *interleave_s = NULL;

    CRM_CHECK(constraint != NULL, return);
    CRM_CHECK(rsc_lh != NULL, pe_err("rsc_lh was NULL for %s", constraint->id); return);
    CRM_CHECK(rsc_rh != NULL, pe_err("rsc_rh was NULL for %s", constraint->id); return);
    CRM_CHECK(rsc_lh->variant == pe_native, return);

    pe_rsc_trace(rsc_rh, "Processing constraint %s: %s -> %s %d",
                 constraint->id, rsc_lh->id, rsc_rh->id, constraint->score);

    if (is_set(rsc_rh->flags, pe_rsc_promotable)) {
        if (is_set(rsc_rh->flags, pe_rsc_provisional)) {
            pe_rsc_trace(rsc_rh, "%s is still provisional", rsc_rh->id);
            return;
        } else if (constraint->role_rh == RSC_ROLE_UNKNOWN) {
            pe_rsc_trace(rsc_rh, "Handling %s as a clone colocation", constraint->id);
        } else {
            promotable_colocation_rh(rsc_lh, rsc_rh, constraint, data_set);
            return;
        }
    }

    /* only the LHS side needs to be labeled as interleave */
    interleave_s = g_hash_table_lookup(constraint->rsc_lh->meta, XML_RSC_ATTR_INTERLEAVE);
    if(crm_is_true(interleave_s) && constraint->rsc_lh->variant > pe_group) {
        // TODO: Do we actually care about multiple RH copies sharing a LH copy anymore?
        if (copies_per_node(constraint->rsc_lh) != copies_per_node(constraint->rsc_rh)) {
            crm_config_err("Cannot interleave %s and %s because"
                           " they do not support the same number of copies per node",
                           constraint->rsc_lh->id, constraint->rsc_rh->id);

        } else {
            do_interleave = TRUE;
        }
    }

    if (is_set(rsc_rh->flags, pe_rsc_provisional)) {
        pe_rsc_trace(rsc_rh, "%s is still provisional", rsc_rh->id);
        return;

    } else if (do_interleave) {
        resource_t *rh_child = NULL;

        rh_child = find_compatible_child(rsc_lh, rsc_rh, RSC_ROLE_UNKNOWN,
                                         FALSE, data_set);

        if (rh_child) {
            pe_rsc_debug(rsc_rh, "Pairing %s with %s", rsc_lh->id, rh_child->id);
            rsc_lh->cmds->rsc_colocation_lh(rsc_lh, rh_child, constraint,
                                            data_set);

        } else if (constraint->score >= INFINITY) {
            crm_notice("Cannot pair %s with instance of %s", rsc_lh->id, rsc_rh->id);
            assign_node(rsc_lh, NULL, TRUE);

        } else {
            pe_rsc_debug(rsc_rh, "Cannot pair %s with instance of %s", rsc_lh->id, rsc_rh->id);
        }

        return;

    } else if (constraint->score >= INFINITY) {
        GListPtr rhs = NULL;

        gIter = rsc_rh->children;
        for (; gIter != NULL; gIter = gIter->next) {
            resource_t *child_rsc = (resource_t *) gIter->data;
            node_t *chosen = child_rsc->fns->location(child_rsc, NULL, FALSE);

            if (chosen != NULL && is_set_recursive(child_rsc, pe_rsc_block, TRUE) == FALSE) {
                pe_rsc_trace(rsc_rh, "Allowing %s: %s %d", constraint->id, chosen->details->uname, chosen->weight);
                rhs = g_list_prepend(rhs, chosen);
            }
        }

        node_list_exclude(rsc_lh->allowed_nodes, rhs, FALSE);
        g_list_free(rhs);
        return;
    }

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

        child_rsc->cmds->rsc_colocation_rh(rsc_lh, child_rsc, constraint,
                                           data_set);
    }
}
Beispiel #4
0
void
container_rsc_colocation_rh(resource_t * rsc_lh, resource_t * rsc, rsc_colocation_t * constraint)
{
    GListPtr allocated_rhs = NULL;
    container_variant_data_t *container_data = NULL;

    CRM_CHECK(constraint != NULL, return);
    CRM_CHECK(rsc_lh != NULL, pe_err("rsc_lh was NULL for %s", constraint->id); return);
    CRM_CHECK(rsc != NULL, pe_err("rsc was NULL for %s", constraint->id); return);
    CRM_ASSERT(rsc_lh->variant == pe_native);

    if (is_set(rsc->flags, pe_rsc_provisional)) {
        pe_rsc_trace(rsc, "%s is still provisional", rsc->id);
        return;

    } else if(constraint->rsc_lh->variant > pe_group) {
        resource_t *rh_child = find_compatible_tuple(rsc_lh, rsc, RSC_ROLE_UNKNOWN, FALSE);

        if (rh_child) {
            pe_rsc_debug(rsc, "Pairing %s with %s", rsc_lh->id, rh_child->id);
            rsc_lh->cmds->rsc_colocation_lh(rsc_lh, rh_child, constraint);

        } else if (constraint->score >= INFINITY) {
            crm_notice("Cannot pair %s with instance of %s", rsc_lh->id, rsc->id);
            assign_node(rsc_lh, NULL, TRUE);

        } else {
            pe_rsc_debug(rsc, "Cannot pair %s with instance of %s", rsc_lh->id, rsc->id);
        }

        return;
    }

    get_container_variant_data(container_data, rsc);
    pe_rsc_trace(rsc, "Processing constraint %s: %s -> %s %d",
                 constraint->id, rsc_lh->id, rsc->id, constraint->score);

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

        if (constraint->score < INFINITY) {
            tuple->docker->cmds->rsc_colocation_rh(rsc_lh, tuple->docker, constraint);

        } else {
            node_t *chosen = tuple->docker->fns->location(tuple->docker, NULL, FALSE);

            if (chosen == NULL || is_set_recursive(tuple->docker, pe_rsc_block, TRUE)) {
                continue;
            }
            if(constraint->role_rh >= RSC_ROLE_MASTER && tuple->child == NULL) {
                continue;
            }
            if(constraint->role_rh >= RSC_ROLE_MASTER && tuple->child->next_role < RSC_ROLE_MASTER) {
                continue;
            }

            pe_rsc_trace(rsc, "Allowing %s: %s %d", constraint->id, chosen->details->uname, chosen->weight);
            allocated_rhs = g_list_prepend(allocated_rhs, chosen);
        }
    }

    if (constraint->score >= INFINITY) {
        node_list_exclude(rsc_lh->allowed_nodes, allocated_rhs, FALSE);
    }
    g_list_free(allocated_rhs);
}
Beispiel #5
0
void
clone_print(resource_t * rsc, const char *pre_text, long options, void *print_data)
{
    char *list_text = NULL;
    char *child_text = NULL;
    char *stopped_list = NULL;
    const char *type = "Clone";

    GListPtr master_list = NULL;
    GListPtr started_list = NULL;
    GListPtr gIter = rsc->children;

    clone_variant_data_t *clone_data = NULL;
    int active_instances = 0;

    if (pre_text == NULL) {
        pre_text = " ";
    }

    if (options & pe_print_xml) {
        clone_print_xml(rsc, pre_text, options, print_data);
        return;
    }

    get_clone_variant_data(clone_data, rsc);

    child_text = crm_concat(pre_text, "   ", ' ');

    if (rsc->variant == pe_master) {
        type = "Master/Slave";
    }

    status_print("%s%s Set: %s [%s]%s%s",
                 pre_text ? pre_text : "", type, rsc->id, ID(clone_data->xml_obj_child),
                 is_set(rsc->flags, pe_rsc_unique) ? " (unique)" : "",
                 is_set(rsc->flags, pe_rsc_managed) ? "" : " (unmanaged)");

    if (options & pe_print_html) {
        status_print("\n<ul>\n");

    } else if ((options & pe_print_log) == 0) {
        status_print("\n");
    }

    for (; gIter != NULL; gIter = gIter->next) {
        gboolean print_full = FALSE;
        resource_t *child_rsc = (resource_t *) gIter->data;

        if (options & pe_print_clone_details) {
            print_full = TRUE;
        }

        if (child_rsc->fns->active(child_rsc, FALSE) == FALSE) {
            /* Inactive clone */
            if (is_set(child_rsc->flags, pe_rsc_orphan)) {
                continue;

            } else if (is_set(rsc->flags, pe_rsc_unique)) {
                print_full = TRUE;

            } else if (is_not_set(options, pe_print_clone_active)) {
                stopped_list = add_list_element(stopped_list, child_rsc->id);
            }

        } else if (is_set_recursive(child_rsc, pe_rsc_unique, TRUE)
                   || is_set_recursive(child_rsc, pe_rsc_orphan, TRUE)
                   || is_set_recursive(child_rsc, pe_rsc_managed, FALSE) == FALSE
                   || is_set_recursive(child_rsc, pe_rsc_failed, TRUE)) {

            /* Unique, unmanaged or failed clone */
            print_full = TRUE;

        } else if (is_set(options, pe_print_pending) && child_rsc->pending_task != NULL) {
            /* In a pending state */
            print_full = TRUE;

        } else if (child_rsc->fns->active(child_rsc, TRUE)) {
            /* Fully active anonymous clone */
            node_t *location = child_rsc->fns->location(child_rsc, NULL, TRUE);

            if (location) {
                enum rsc_role_e a_role = child_rsc->fns->state(child_rsc, TRUE);

                if (location->details->online == FALSE && location->details->unclean) {
                    print_full = TRUE;

                } else if (a_role > RSC_ROLE_SLAVE) {
                    /* And active on a single node as master */
                    master_list = g_list_append(master_list, location);

                } else {
                    /* And active on a single node as started/slave */
                    started_list = g_list_append(started_list, location);
                }

            } else {
                /* uncolocated group - bleh */
                print_full = TRUE;
            }

        } else {
            /* Partially active anonymous clone */
            print_full = TRUE;
        }

        if (print_full) {
            if (options & pe_print_html) {
                status_print("<li>\n");
            }
            child_rsc->fns->print(child_rsc, child_text, options, print_data);
            if (options & pe_print_html) {
                status_print("</li>\n");
            }
        }
    }

    /* Masters */
    master_list = g_list_sort(master_list, sort_node_uname);
    for (gIter = master_list; gIter; gIter = gIter->next) {
        node_t *host = gIter->data;

        list_text = add_list_element(list_text, host->details->uname);
	active_instances++;
    }

    short_print(list_text, child_text, "Masters", NULL, options, print_data);
    g_list_free(master_list);
    free(list_text);
    list_text = NULL;

    /* Started/Slaves */
    started_list = g_list_sort(started_list, sort_node_uname);
    for (gIter = started_list; gIter; gIter = gIter->next) {
        node_t *host = gIter->data;

        list_text = add_list_element(list_text, host->details->uname);
	active_instances++;
    }

    if(rsc->variant == pe_master) {
        enum rsc_role_e role = configured_role(rsc);

        if(role > RSC_ROLE_STOPPED && role < RSC_ROLE_MASTER) {
            short_print(list_text, child_text, "Slaves (target-role)", NULL, options, print_data);
        } else {
            short_print(list_text, child_text, "Slaves", NULL, options, print_data);
        }

    } else {
        short_print(list_text, child_text, "Started", NULL, options, print_data);
    }

    g_list_free(started_list);
    free(list_text);
    list_text = NULL;

    if (is_not_set(options, pe_print_clone_active)) {
        const char *state = "Stopped";
        enum rsc_role_e role = configured_role(rsc);

        if (role == RSC_ROLE_STOPPED) {
            state = "Stopped (disabled)";
        }

        if (is_not_set(rsc->flags, pe_rsc_unique)
            && (clone_data->clone_max > active_instances)) {

            GListPtr nIter;
            GListPtr list = g_hash_table_get_values(rsc->allowed_nodes);

            /* Custom stopped list for non-unique clones */
            free(stopped_list); stopped_list = NULL;

            if (g_list_length(list) == 0) {
                /* Clusters with symmetrical=false haven't calculated allowed_nodes yet
                 * If we've not probed for them yet, the Stopped list will be empty
                 */
                list = g_hash_table_get_values(rsc->known_on);
            }

            list = g_list_sort(list, sort_node_uname);
            for (nIter = list; nIter != NULL; nIter = nIter->next) {
                node_t *node = (node_t *)nIter->data;

                if (pe_find_node(rsc->running_on, node->details->uname) == NULL) {
                    stopped_list = add_list_element(stopped_list, node->details->uname);
                }
            }
            g_list_free(list);
        }

        short_print(stopped_list, child_text, state, NULL, options, print_data);
        free(stopped_list);
    }

    if (options & pe_print_html) {
        status_print("</ul>\n");
    }

    free(child_text);
}