Пример #1
0
void
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
{
    if(election_state(writer) == election_won
        && kind == crm_status_nstate
        && safe_str_eq(peer->state, CRM_NODE_MEMBER)) {

        attrd_peer_sync(peer, NULL);

    } else if(kind == crm_status_nstate
              && safe_str_neq(peer->state, CRM_NODE_MEMBER)) {

        attrd_peer_remove(peer->uname, __FUNCTION__);
        if(peer_writer && safe_str_eq(peer->uname, peer_writer)) {
            free(peer_writer);
            peer_writer = NULL;
            crm_notice("Lost attribute writer %s", peer->uname);
        }

    } else if(kind == crm_status_processes) {
        if(is_set(peer->processes, crm_proc_cpg)) {
            crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_MEMBER, 0);
        } else {
            crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_LOST, 0);
        }
    }
}
Пример #2
0
void
attrd_peer_message(crm_node_t *peer, xmlNode *xml)
{
    const char *op = crm_element_value(xml, F_ATTRD_TASK);
    const char *election_op = crm_element_value(xml, F_CRM_TASK);
    const char *host = crm_element_value(xml, F_ATTRD_HOST);
    bool peer_won = FALSE;

    if (election_op) {
        attrd_handle_election_op(peer, xml);
        return;
    }

    if (attrd_shutting_down()) {
        /* If we're shutting down, we want to continue responding to election
         * ops as long as we're a cluster member (because our vote may be
         * needed). Ignore all other messages.
         */
        return;
    }

    peer_won = attrd_check_for_new_writer(peer, xml);

    if (safe_str_eq(op, ATTRD_OP_UPDATE) || safe_str_eq(op, ATTRD_OP_UPDATE_BOTH) || safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
        attrd_peer_update(peer, xml, host, FALSE);

    } else if (safe_str_eq(op, ATTRD_OP_SYNC)) {
        attrd_peer_sync(peer, xml);

    } else if (safe_str_eq(op, ATTRD_OP_PEER_REMOVE)) {
        attrd_peer_remove(host, TRUE, peer->uname);

    } else if (safe_str_eq(op, ATTRD_OP_CLEAR_FAILURE)) {
        /* It is not currently possible to receive this as a peer command,
         * but will be, if we one day enable propagating this operation.
         */
        attrd_peer_clear_failure(peer, xml);

    } else if (safe_str_eq(op, ATTRD_OP_SYNC_RESPONSE)
              && safe_str_neq(peer->uname, attrd_cluster->uname)) {
        xmlNode *child = NULL;

        crm_info("Processing %s from %s", op, peer->uname);

        /* Clear the seen flag for attribute processing held only in the own node. */
        if (peer_won) {
            clear_attribute_value_seen();
        }

        for (child = __xml_first_child(xml); child != NULL; child = __xml_next(child)) {
            host = crm_element_value(child, F_ATTRD_HOST);
            attrd_peer_update(peer, child, host, TRUE);
        }

        if (peer_won) {
            /* Synchronize if there is an attribute held only by own node that Writer does not have. */
            attrd_current_only_attribute_update(peer, xml);
        }
    }
}
Пример #3
0
void
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
{
    if ((kind == crm_status_nstate) || (kind == crm_status_rstate)) {
        if (safe_str_eq(peer->state, CRM_NODE_MEMBER)) {
            /* If we're the writer, send new peers a list of all attributes
             * (unless it's a remote node, which doesn't run its own attrd)
             */
            if ((election_state(writer) == election_won)
                && !is_set(peer->flags, crm_remote_node)) {
                attrd_peer_sync(peer, NULL);
            }
        } else {
            /* Remove all attribute values associated with lost nodes */
            attrd_peer_remove(peer->uname, FALSE, "peer loss");
            if (peer_writer && safe_str_eq(peer->uname, peer_writer)) {
                free(peer_writer);
                peer_writer = NULL;
                crm_notice("Lost attribute writer %s", peer->uname);
            }
        }
    }
}
Пример #4
0
void
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
{
    bool remove_voter = FALSE;

    switch (kind) {
        case crm_status_uname:
            break;

        case crm_status_processes:
            if (is_not_set(peer->processes, crm_get_cluster_proc())) {
                remove_voter = TRUE;
            }
            break;

        case crm_status_nstate:
            if (safe_str_eq(peer->state, CRM_NODE_MEMBER)) {
                /* If we're the writer, send new peers a list of all attributes
                 * (unless it's a remote node, which doesn't run its own attrd)
                 */
                if (attrd_election_won()
                    && !is_set(peer->flags, crm_remote_node)) {
                    attrd_peer_sync(peer, NULL);
                }
            } else {
                // Remove all attribute values associated with lost nodes
                attrd_peer_remove(peer->uname, FALSE, "loss");
                remove_voter = TRUE;
            }
            break;
    }

    // In case an election is in progress, remove any vote by the node
    if (remove_voter) {
        attrd_remove_voter(peer);
    }
}
Пример #5
0
void
attrd_peer_message(crm_node_t *peer, xmlNode *xml)
{
    int peer_state = 0;
    const char *op = crm_element_value(xml, F_ATTRD_TASK);
    const char *election_op = crm_element_value(xml, F_CRM_TASK);

    if(election_op) {
        enum election_result rc = 0;

        crm_xml_add(xml, F_CRM_HOST_FROM, peer->uname);
        rc = election_count_vote(writer, xml, TRUE);
        switch(rc) {
            case election_start:
                free(peer_writer);
                peer_writer = NULL;
                election_vote(writer);
                break;
            case election_lost:
                free(peer_writer);
                peer_writer = strdup(peer->uname);
                break;
            default:
                election_check(writer);
                break;
        }
        return;
    }

    crm_element_value_int(xml, F_ATTRD_WRITER, &peer_state);
    if(election_state(writer) == election_won
       && peer_state == election_won
       && safe_str_neq(peer->uname, attrd_cluster->uname)) {
        crm_notice("Detected another attribute writer: %s", peer->uname);
        election_vote(writer);

    } else if(peer_state == election_won) {
        if(peer_writer == NULL) {
            peer_writer = strdup(peer->uname);
            crm_notice("Recorded attribute writer: %s", peer->uname);

        } else if(safe_str_neq(peer->uname, peer_writer)) {
            crm_notice("Recorded new attribute writer: %s (was %s)", peer->uname, peer_writer);
            free(peer_writer);
            peer_writer = strdup(peer->uname);
        }
    }

    if(safe_str_eq(op, "update")) {
        attrd_peer_update(peer, xml, FALSE);

    } else if(safe_str_eq(op, "sync")) {
        attrd_peer_sync(peer, xml);

    } else if(safe_str_eq(op, "peer-remove")) {
        const char *host = crm_element_value(xml, F_ATTRD_HOST);
        attrd_peer_remove(host, peer->uname);

    } else if(safe_str_eq(op, "sync-response")
              && safe_str_neq(peer->uname, attrd_cluster->uname)) {
        xmlNode *child = NULL;

        crm_notice("Processing %s from %s", op, peer->uname);
        for (child = __xml_first_child(xml); child != NULL; child = __xml_next(child)) {
            attrd_peer_update(peer, child, TRUE);
        }
    }
}
Пример #6
0
void
attrd_peer_message(crm_node_t *peer, xmlNode *xml)
{
    int peer_state = 0;
    const char *v = crm_element_value(xml, F_ATTRD_VERSION);
    const char *op = crm_element_value(xml, F_ATTRD_TASK);
    const char *election_op = crm_element_value(xml, F_CRM_TASK);
    const char *host = crm_element_value(xml, F_ATTRD_HOST);

    if(election_op) {
        enum election_result rc = 0;

        crm_xml_add(xml, F_CRM_HOST_FROM, peer->uname);
        rc = election_count_vote(writer, xml, TRUE);
        switch(rc) {
            case election_start:
                free(peer_writer);
                peer_writer = NULL;
                election_vote(writer);
                break;
            case election_lost:
                free(peer_writer);
                peer_writer = strdup(peer->uname);
                break;
            default:
                election_check(writer);
                break;
        }
        return;

    } else if(v == NULL) {
        /* From the non-atomic version */
        if (safe_str_eq(op, ATTRD_OP_UPDATE)) {
            const char *name = crm_element_value(xml, F_ATTRD_ATTRIBUTE);

            crm_trace("Compatibility update of %s from %s", name, peer->uname);
            attrd_peer_update(peer, xml, host, FALSE);

        } else if (safe_str_eq(op, ATTRD_OP_FLUSH)) {
            const char *name = crm_element_value(xml, F_ATTRD_ATTRIBUTE);
            attribute_t *a = g_hash_table_lookup(attributes, name);

            if(a) {
                crm_trace("Compatibility write-out of %s for %s from %s", a->id, op, peer->uname);
                write_or_elect_attribute(a);
            }

        } else if (safe_str_eq(op, ATTRD_OP_REFRESH)) {
            GHashTableIter aIter;
            attribute_t *a = NULL;

            g_hash_table_iter_init(&aIter, attributes);
            while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
                crm_trace("Compatibility write-out of %s for %s from %s", a->id, op, peer->uname);
                write_or_elect_attribute(a);
            }
        }
    }

    crm_element_value_int(xml, F_ATTRD_WRITER, &peer_state);
    if(election_state(writer) == election_won
       && peer_state == election_won
       && safe_str_neq(peer->uname, attrd_cluster->uname)) {
        crm_notice("Detected another attribute writer: %s", peer->uname);
        election_vote(writer);

    } else if(peer_state == election_won) {
        if(peer_writer == NULL) {
            peer_writer = strdup(peer->uname);
            crm_notice("Recorded attribute writer: %s", peer->uname);

        } else if(safe_str_neq(peer->uname, peer_writer)) {
            crm_notice("Recorded new attribute writer: %s (was %s)", peer->uname, peer_writer);
            free(peer_writer);
            peer_writer = strdup(peer->uname);
        }
    }

    if (safe_str_eq(op, ATTRD_OP_UPDATE) || safe_str_eq(op, ATTRD_OP_UPDATE_BOTH) || safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
        attrd_peer_update(peer, xml, host, FALSE);

    } else if (safe_str_eq(op, ATTRD_OP_SYNC)) {
        attrd_peer_sync(peer, xml);

    } else if (safe_str_eq(op, ATTRD_OP_PEER_REMOVE)) {
        attrd_peer_remove(host, TRUE, peer->uname);

    } else if (safe_str_eq(op, ATTRD_OP_SYNC_RESPONSE)
              && safe_str_neq(peer->uname, attrd_cluster->uname)) {
        xmlNode *child = NULL;

        crm_info("Processing %s from %s", op, peer->uname);
        for (child = __xml_first_child(xml); child != NULL; child = __xml_next(child)) {
            host = crm_element_value(child, F_ATTRD_HOST);
            attrd_peer_update(peer, child, host, TRUE);
        }
    }
}