dhodovsk / source-git / pacemaker

Forked from source-git/pacemaker 3 years ago
Clone

Blame lib/pengine/group.c

rpm-build 3ee90c
/*
rpm-build 3ee90c
 * Copyright 2004-2019 the Pacemaker project contributors
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * The version control history for this file may have further details.
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * This source code is licensed under the GNU Lesser General Public License
rpm-build 3ee90c
 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
rpm-build 3ee90c
 */
rpm-build 3ee90c
rpm-build 3ee90c
#include <crm_internal.h>
rpm-build 3ee90c
rpm-build 3ee90c
#include <crm/common/curses_internal.h>
rpm-build 3ee90c
#include <crm/pengine/rules.h>
rpm-build 3ee90c
#include <crm/pengine/status.h>
rpm-build 3ee90c
#include <crm/pengine/internal.h>
rpm-build 3ee90c
#include <crm/msg_xml.h>
rpm-build 3ee90c
rpm-build 3ee90c
#define VARIANT_GROUP 1
rpm-build 3ee90c
#include "./variant.h"
rpm-build 3ee90c
rpm-build 3ee90c
gboolean
rpm-build 3ee90c
group_unpack(resource_t * rsc, pe_working_set_t * data_set)
rpm-build 3ee90c
{
rpm-build 3ee90c
    xmlNode *xml_obj = rsc->xml;
rpm-build 3ee90c
    xmlNode *xml_native_rsc = NULL;
rpm-build 3ee90c
    group_variant_data_t *group_data = NULL;
rpm-build 3ee90c
    const char *group_ordered = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_ORDERED);
rpm-build 3ee90c
    const char *group_colocated = g_hash_table_lookup(rsc->meta, "collocated");
rpm-build 3ee90c
    const char *clone_id = NULL;
rpm-build 3ee90c
rpm-build 3ee90c
    pe_rsc_trace(rsc, "Processing resource %s...", rsc->id);
rpm-build 3ee90c
rpm-build 3ee90c
    group_data = calloc(1, sizeof(group_variant_data_t));
rpm-build 3ee90c
    group_data->num_children = 0;
rpm-build 3ee90c
    group_data->first_child = NULL;
rpm-build 3ee90c
    group_data->last_child = NULL;
rpm-build 3ee90c
    rsc->variant_opaque = group_data;
rpm-build 3ee90c
rpm-build 3ee90c
    group_data->ordered = TRUE;
rpm-build 3ee90c
    group_data->colocated = TRUE;
rpm-build 3ee90c
rpm-build 3ee90c
    if (group_ordered != NULL) {
rpm-build 3ee90c
        crm_str_to_boolean(group_ordered, &(group_data->ordered));
rpm-build 3ee90c
    }
rpm-build 3ee90c
    if (group_colocated != NULL) {
rpm-build 3ee90c
        crm_str_to_boolean(group_colocated, &(group_data->colocated));
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    clone_id = crm_element_value(rsc->xml, XML_RSC_ATTR_INCARNATION);
rpm-build 3ee90c
rpm-build 3ee90c
    for (xml_native_rsc = __xml_first_child_element(xml_obj); xml_native_rsc != NULL;
rpm-build 3ee90c
         xml_native_rsc = __xml_next_element(xml_native_rsc)) {
rpm-build 3ee90c
        if (crm_str_eq((const char *)xml_native_rsc->name, XML_CIB_TAG_RESOURCE, TRUE)) {
rpm-build 3ee90c
            resource_t *new_rsc = NULL;
rpm-build 3ee90c
rpm-build 3ee90c
            crm_xml_add(xml_native_rsc, XML_RSC_ATTR_INCARNATION, clone_id);
rpm-build 3ee90c
            if (common_unpack(xml_native_rsc, &new_rsc, rsc, data_set) == FALSE) {
rpm-build 3ee90c
                pe_err("Failed unpacking resource %s", crm_element_value(xml_obj, XML_ATTR_ID));
rpm-build 3ee90c
                if (new_rsc != NULL && new_rsc->fns != NULL) {
rpm-build 3ee90c
                    new_rsc->fns->free(new_rsc);
rpm-build 3ee90c
                }
rpm-build 3ee90c
                continue;
rpm-build 3ee90c
            }
rpm-build 3ee90c
rpm-build 3ee90c
            group_data->num_children++;
rpm-build 3ee90c
            rsc->children = g_list_append(rsc->children, new_rsc);
rpm-build 3ee90c
rpm-build 3ee90c
            if (group_data->first_child == NULL) {
rpm-build 3ee90c
                group_data->first_child = new_rsc;
rpm-build 3ee90c
            }
rpm-build 3ee90c
            group_data->last_child = new_rsc;
rpm-build 3ee90c
            pe_rsc_trace(rsc, "Added %s member %s", rsc->id, new_rsc->id);
rpm-build 3ee90c
        }
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    if (group_data->num_children == 0) {
rpm-build 3ee90c
#if 0
rpm-build 3ee90c
        /* Bug #1287 */
rpm-build 3ee90c
        crm_config_err("Group %s did not have any children", rsc->id);
rpm-build 3ee90c
        return FALSE;
rpm-build 3ee90c
#else
rpm-build 3ee90c
        crm_config_warn("Group %s did not have any children", rsc->id);
rpm-build 3ee90c
        return TRUE;
rpm-build 3ee90c
#endif
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    pe_rsc_trace(rsc, "Added %d children to resource %s...", group_data->num_children, rsc->id);
rpm-build 3ee90c
rpm-build 3ee90c
    return TRUE;
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
gboolean
rpm-build 3ee90c
group_active(resource_t * rsc, gboolean all)
rpm-build 3ee90c
{
rpm-build 3ee90c
    gboolean c_all = TRUE;
rpm-build 3ee90c
    gboolean c_any = FALSE;
rpm-build 3ee90c
    GListPtr gIter = rsc->children;
rpm-build 3ee90c
rpm-build 3ee90c
    for (; gIter != NULL; gIter = gIter->next) {
rpm-build 3ee90c
        resource_t *child_rsc = (resource_t *) gIter->data;
rpm-build 3ee90c
rpm-build 3ee90c
        if (child_rsc->fns->active(child_rsc, all)) {
rpm-build 3ee90c
            c_any = TRUE;
rpm-build 3ee90c
        } else {
rpm-build 3ee90c
            c_all = FALSE;
rpm-build 3ee90c
        }
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    if (c_any == FALSE) {
rpm-build 3ee90c
        return FALSE;
rpm-build 3ee90c
    } else if (all && c_all == FALSE) {
rpm-build 3ee90c
        return FALSE;
rpm-build 3ee90c
    }
rpm-build 3ee90c
    return TRUE;
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
static void
rpm-build 3ee90c
group_print_xml(resource_t * rsc, const char *pre_text, long options, void *print_data)
rpm-build 3ee90c
{
rpm-build 3ee90c
    GListPtr gIter = rsc->children;
rpm-build 3ee90c
    char *child_text = crm_concat(pre_text, "    ", ' ');
rpm-build 3ee90c
rpm-build 3ee90c
    status_print("%s<group id=\"%s\" ", pre_text, rsc->id);
rpm-build 3ee90c
    status_print("number_resources=\"%d\" ", g_list_length(rsc->children));
rpm-build 3ee90c
    status_print(">\n");
rpm-build 3ee90c
rpm-build 3ee90c
    for (; gIter != NULL; gIter = gIter->next) {
rpm-build 3ee90c
        resource_t *child_rsc = (resource_t *) gIter->data;
rpm-build 3ee90c
rpm-build 3ee90c
        child_rsc->fns->print(child_rsc, child_text, options, print_data);
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    status_print("%s</group>\n", pre_text);
rpm-build 3ee90c
    free(child_text);
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
void
rpm-build 3ee90c
group_print(resource_t * rsc, const char *pre_text, long options, void *print_data)
rpm-build 3ee90c
{
rpm-build 3ee90c
    char *child_text = NULL;
rpm-build 3ee90c
    GListPtr gIter = rsc->children;
rpm-build 3ee90c
rpm-build 3ee90c
    if (pre_text == NULL) {
rpm-build 3ee90c
        pre_text = " ";
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    if (options & pe_print_xml) {
rpm-build 3ee90c
        group_print_xml(rsc, pre_text, options, print_data);
rpm-build 3ee90c
        return;
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    child_text = crm_concat(pre_text, "   ", ' ');
rpm-build 3ee90c
rpm-build 3ee90c
    status_print("%sResource Group: %s", pre_text ? pre_text : "", rsc->id);
rpm-build 3ee90c
rpm-build 3ee90c
    if (options & pe_print_html) {
rpm-build 3ee90c
        status_print("\n
    \n");
rpm-build 3ee90c
rpm-build 3ee90c
    } else if ((options & pe_print_log) == 0) {
rpm-build 3ee90c
        status_print("\n");
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    if (options & pe_print_brief) {
rpm-build 3ee90c
        print_rscs_brief(rsc->children, child_text, options, print_data, TRUE);
rpm-build 3ee90c
rpm-build 3ee90c
    } else {
rpm-build 3ee90c
        for (; gIter != NULL; gIter = gIter->next) {
rpm-build 3ee90c
            resource_t *child_rsc = (resource_t *) gIter->data;
rpm-build 3ee90c
rpm-build 3ee90c
            if (options & pe_print_html) {
rpm-build 3ee90c
                status_print("
  • \n");
  • rpm-build 3ee90c
                }
    rpm-build 3ee90c
                child_rsc->fns->print(child_rsc, child_text, options, print_data);
    rpm-build 3ee90c
                if (options & pe_print_html) {
    rpm-build 3ee90c
                    status_print("\n");
    rpm-build 3ee90c
                }
    rpm-build 3ee90c
            }
    rpm-build 3ee90c
        }
    rpm-build 3ee90c
    rpm-build 3ee90c
        if (options & pe_print_html) {
    rpm-build 3ee90c
            status_print("\n");
    rpm-build 3ee90c
        }
    rpm-build 3ee90c
        free(child_text);
    rpm-build 3ee90c
    }
    rpm-build 3ee90c
    rpm-build 3ee90c
    int
    rpm-build 3ee90c
    pe__group_xml(pcmk__output_t *out, va_list args)
    rpm-build 3ee90c
    {
    rpm-build 3ee90c
        long options = va_arg(args, long);
    rpm-build 3ee90c
        resource_t *rsc = va_arg(args, resource_t *);
    rpm-build 3ee90c
    rpm-build 3ee90c
        GListPtr gIter = rsc->children;
    rpm-build 3ee90c
        char *count = crm_itoa(g_list_length(gIter));
    rpm-build 3ee90c
    rpm-build 3ee90c
        int rc = pe__name_and_nvpairs_xml(out, true, "group", 2
    rpm-build 3ee90c
                                          , "id", rsc->id
    rpm-build 3ee90c
                                          , "number_resources", count);
    rpm-build 3ee90c
        free(count);
    rpm-build 3ee90c
        CRM_ASSERT(rc == 0);
    rpm-build 3ee90c
    rpm-build 3ee90c
        for (; gIter != NULL; gIter = gIter->next) {
    rpm-build 3ee90c
            resource_t *child_rsc = (resource_t *) gIter->data;
    rpm-build 3ee90c
    rpm-build 3ee90c
            out->message(out, crm_map_element_name(child_rsc->xml), options, child_rsc);
    rpm-build 3ee90c
        }
    rpm-build 3ee90c
    rpm-build 3ee90c
        pcmk__output_xml_pop_parent(out);
    rpm-build 3ee90c
        return rc;
    rpm-build 3ee90c
    }
    rpm-build 3ee90c
    rpm-build 3ee90c
    int
    rpm-build 3ee90c
    pe__group_html(pcmk__output_t *out, va_list args)
    rpm-build 3ee90c
    {
    rpm-build 3ee90c
        long options = va_arg(args, long);
    rpm-build 3ee90c
        resource_t *rsc = va_arg(args, resource_t *);
    rpm-build 3ee90c
    rpm-build 3ee90c
        out->begin_list(out, NULL, NULL, "Resource Group: %s", rsc->id);
    rpm-build 3ee90c
    rpm-build 3ee90c
        if (options & pe_print_brief) {
    rpm-build 3ee90c
            pe__rscs_brief_output(out, rsc->children, options, TRUE);
    rpm-build 3ee90c
    rpm-build 3ee90c
        } else {
    rpm-build 3ee90c
            for (GListPtr gIter = rsc->children; gIter; gIter = gIter->next) {
    rpm-build 3ee90c
                resource_t *child_rsc = (resource_t *) gIter->data;
    rpm-build 3ee90c
                out->message(out, crm_map_element_name(child_rsc->xml), options, child_rsc);
    rpm-build 3ee90c
            }
    rpm-build 3ee90c
        }
    rpm-build 3ee90c
    rpm-build 3ee90c
        out->end_list(out);
    rpm-build 3ee90c
    rpm-build 3ee90c
        return 0;
    rpm-build 3ee90c
    }
    rpm-build 3ee90c
    rpm-build 3ee90c
    int
    rpm-build 3ee90c
    pe__group_text(pcmk__output_t *out, va_list args)
    rpm-build 3ee90c
    {
    rpm-build 3ee90c
        long options = va_arg(args, long);
    rpm-build 3ee90c
        resource_t *rsc = va_arg(args, resource_t *);
    rpm-build 3ee90c
    rpm-build 3ee90c
        out->begin_list(out, NULL, NULL, "Resource Group: %s", rsc->id);
    rpm-build 3ee90c
    rpm-build 3ee90c
        if (options & pe_print_brief) {
    rpm-build 3ee90c
            pe__rscs_brief_output(out, rsc->children, options, TRUE);
    rpm-build 3ee90c
    rpm-build 3ee90c
        } else {
    rpm-build 3ee90c
            for (GListPtr gIter = rsc->children; gIter; gIter = gIter->next) {
    rpm-build 3ee90c
                resource_t *child_rsc = (resource_t *) gIter->data;
    rpm-build 3ee90c
    rpm-build 3ee90c
                out->message(out, crm_map_element_name(child_rsc->xml), options, child_rsc);
    rpm-build 3ee90c
            }
    rpm-build 3ee90c
        }
    rpm-build 3ee90c
        out->end_list(out);
    rpm-build 3ee90c
    rpm-build 3ee90c
        return 0;
    rpm-build 3ee90c
    }
    rpm-build 3ee90c
    rpm-build 3ee90c
    void
    rpm-build 3ee90c
    group_free(resource_t * rsc)
    rpm-build 3ee90c
    {
    rpm-build 3ee90c
        CRM_CHECK(rsc != NULL, return);
    rpm-build 3ee90c
    rpm-build 3ee90c
        pe_rsc_trace(rsc, "Freeing %s", rsc->id);
    rpm-build 3ee90c
    rpm-build 3ee90c
        for (GListPtr gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
    rpm-build 3ee90c
            resource_t *child_rsc = (resource_t *) gIter->data;
    rpm-build 3ee90c
    rpm-build 3ee90c
            CRM_ASSERT(child_rsc);
    rpm-build 3ee90c
            pe_rsc_trace(child_rsc, "Freeing child %s", child_rsc->id);
    rpm-build 3ee90c
            child_rsc->fns->free(child_rsc);
    rpm-build 3ee90c
        }
    rpm-build 3ee90c
    rpm-build 3ee90c
        pe_rsc_trace(rsc, "Freeing child list");
    rpm-build 3ee90c
        g_list_free(rsc->children);
    rpm-build 3ee90c
    rpm-build 3ee90c
        common_free(rsc);
    rpm-build 3ee90c
    }
    rpm-build 3ee90c
    rpm-build 3ee90c
    enum rsc_role_e
    rpm-build 3ee90c
    group_resource_state(const resource_t * rsc, gboolean current)
    rpm-build 3ee90c
    {
    rpm-build 3ee90c
        enum rsc_role_e group_role = RSC_ROLE_UNKNOWN;
    rpm-build 3ee90c
        GListPtr gIter = rsc->children;
    rpm-build 3ee90c
    rpm-build 3ee90c
        for (; gIter != NULL; gIter = gIter->next) {
    rpm-build 3ee90c
            resource_t *child_rsc = (resource_t *) gIter->data;
    rpm-build 3ee90c
            enum rsc_role_e role = child_rsc->fns->state(child_rsc, current);
    rpm-build 3ee90c
    rpm-build 3ee90c
            if (role > group_role) {
    rpm-build 3ee90c
                group_role = role;
    rpm-build 3ee90c
            }
    rpm-build 3ee90c
        }
    rpm-build 3ee90c
    rpm-build 3ee90c
        pe_rsc_trace(rsc, "%s role: %s", rsc->id, role2text(group_role));
    rpm-build 3ee90c
        return group_role;
    rpm-build 3ee90c
    }