Example #1
0
gboolean
corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode * xml_parent)
{
    int lpc = 0;
    int rc = CS_OK;
    int retries = 0;
    gboolean any = FALSE;
    cmap_handle_t cmap_handle;

    do {
        rc = cmap_initialize(&cmap_handle);
        if (rc != CS_OK) {
            retries++;
            crm_debug("API connection setup failed: %s.  Retrying in %ds", cs_strerror(rc),
                      retries);
            sleep(retries);
        }

    } while (retries < 5 && rc != CS_OK);

    if (rc != CS_OK) {
        crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
        return FALSE;
    }

    crm_peer_init();
    crm_trace("Initializing corosync nodelist");
    for (lpc = 0;; lpc++) {
        uint32_t nodeid = 0;
        char *name = NULL;
        char *key = NULL;

        key = g_strdup_printf("nodelist.node.%d.nodeid", lpc);
        rc = cmap_get_uint32(cmap_handle, key, &nodeid);
        g_free(key);

        if (rc != CS_OK) {
            break;
        }

        name = corosync_node_name(cmap_handle, nodeid);
        if (name != NULL) {
            GHashTableIter iter;
            crm_node_t *node = NULL;

            g_hash_table_iter_init(&iter, crm_peer_cache);
            while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
                if(node && node->uname && strcasecmp(node->uname, name) == 0) {
                    if (node->id && node->id != nodeid) {
                        crm_crit("Nodes %u and %u share the same name '%s': shutting down", node->id,
                                 nodeid, name);
                        crm_exit(DAEMON_RESPAWN_STOP);
                    }
                }
            }
        }

        if (nodeid > 0 || name != NULL) {
            crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
            crm_get_peer(nodeid, name);
        }

        if (nodeid > 0 && name != NULL) {
            any = TRUE;

            if (xml_parent) {
                xmlNode *node = create_xml_node(xml_parent, XML_CIB_TAG_NODE);

                crm_xml_add_int(node, XML_ATTR_ID, nodeid);
                crm_xml_add(node, XML_ATTR_UNAME, name);
                if (force_member) {
                    crm_xml_add(node, XML_ATTR_TYPE, CRM_NODE_MEMBER);
                }
            }
        }

        free(name);
    }
    cmap_finalize(cmap_handle);
    return any;
}
Example #2
0
static void
pcmk_quorum_notification(quorum_handle_t handle,
                         uint32_t quorate,
                         uint64_t ring_id, uint32_t view_list_entries, uint32_t * view_list)
{
    int i;
    GHashTableIter iter;
    crm_node_t *node = NULL;
    static gboolean init_phase = TRUE;

    if (quorate != crm_have_quorum) {
        crm_notice("Membership " U64T ": quorum %s (%lu)", ring_id,
                   quorate ? "acquired" : "lost", (long unsigned int)view_list_entries);
        crm_have_quorum = quorate;

    } else {
        crm_info("Membership " U64T ": quorum %s (%lu)", ring_id,
                 quorate ? "retained" : "still lost", (long unsigned int)view_list_entries);
    }

    if (view_list_entries == 0 && init_phase) {
        crm_info("Corosync membership is still forming, ignoring");
        return;
    }

    init_phase = FALSE;

    g_hash_table_iter_init(&iter, crm_peer_cache);
    while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
        node->last_seen = 0;
    }

    for (i = 0; i < view_list_entries; i++) {
        uint32_t id = view_list[i];
        char *name = NULL;

        crm_debug("Member[%d] %u ", i, id);

        node = crm_get_peer(id, NULL);
        if (node->uname == NULL) {
            crm_info("Obtaining name for new node %u", id);
            name = corosync_node_name(0, id);
            node = crm_get_peer(id, name);
        }

        crm_update_peer_state(__FUNCTION__, node, CRM_NODE_MEMBER, ring_id);
        free(name);
    }

    crm_trace("Reaping unseen nodes...");
    g_hash_table_iter_init(&iter, crm_peer_cache);
    while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
        if (node->last_seen != ring_id && node->state) {
            crm_update_peer_state(__FUNCTION__, node, CRM_NODE_LOST, 0);
        } else if (node->last_seen != ring_id) {
            crm_info("State of node %s[%u] is still unknown", node->uname, node->id);
        }
    }

    if (quorum_app_callback) {
        quorum_app_callback(ring_id, quorate);
    }
}
Example #3
0
static void
pcmk_quorum_notification(quorum_handle_t handle,
                         uint32_t quorate,
                         uint64_t ring_id, uint32_t view_list_entries, uint32_t * view_list)
{
    int i;
    GHashTableIter iter;
    crm_node_t *node = NULL;
    static gboolean init_phase = TRUE;

    if (quorate != crm_have_quorum) {
        if (quorate) {
            crm_notice("Quorum acquired " CRM_XS " membership=%" U64T " members=%lu",
                       ring_id, (long unsigned int)view_list_entries);
        } else {
            crm_warn("Quorum lost " CRM_XS " membership=%" U64T " members=%lu",
                     ring_id, (long unsigned int)view_list_entries);
        }
        crm_have_quorum = quorate;

    } else {
        crm_info("Quorum %s " CRM_XS " membership=%" U64T " members=%lu",
                 (quorate? "retained" : "still lost"), ring_id,
                 (long unsigned int)view_list_entries);
    }

    if (view_list_entries == 0 && init_phase) {
        crm_info("Corosync membership is still forming, ignoring");
        return;
    }

    init_phase = FALSE;

    /* Reset last_seen for all cached nodes so we can tell which ones aren't
     * in the view list */
    g_hash_table_iter_init(&iter, crm_peer_cache);
    while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
        node->last_seen = 0;
    }

    /* Update the peer cache for each node in view list */
    for (i = 0; i < view_list_entries; i++) {
        uint32_t id = view_list[i];

        crm_debug("Member[%d] %u ", i, id);

        /* Get this node's peer cache entry (adding one if not already there) */
        node = crm_get_peer(id, NULL);
        if (node->uname == NULL) {
            char *name = corosync_node_name(0, id);

            crm_info("Obtaining name for new node %u", id);
            node = crm_get_peer(id, name);
            free(name);
        }

        /* Update the node state (including updating last_seen to ring_id) */
        crm_update_peer_state(__FUNCTION__, node, CRM_NODE_MEMBER, ring_id);
    }

    /* Remove any peer cache entries we didn't update */
    crm_reap_unseen_nodes(ring_id);

    if (quorum_app_callback) {
        quorum_app_callback(ring_id, quorate);
    }
}
Example #4
0
char *
get_node_name(uint32_t nodeid)
{
    char *name = NULL;
    const char *isolation_host = NULL;
    enum cluster_type_e stack;

    if (nodeid == 0) {
        isolation_host = getenv("OCF_RESKEY_"CRM_META"_isolation_host");
        if (isolation_host) {
            return strdup(isolation_host);
        }
    }

    stack = get_cluster_type();
    switch (stack) {
        case pcmk_cluster_heartbeat:
            break;

#if SUPPORT_PLUGIN
        case pcmk_cluster_classic_ais:
            name = classic_node_name(nodeid);
            break;
#else
#  if SUPPORT_COROSYNC
        case pcmk_cluster_corosync:
            name = corosync_node_name(0, nodeid);
            break;
#  endif
#endif

#if SUPPORT_CMAN
        case pcmk_cluster_cman:
            name = cman_node_name(nodeid);
            break;
#endif

        default:
            crm_err("Unknown cluster type: %s (%d)", name_for_cluster_type(stack), stack);
    }

    if(name == NULL && nodeid == 0) {
        struct utsname res;
        int rc = uname(&res);

        if (rc == 0) {
            crm_notice("Defaulting to uname -n for the local %s node name",
                       name_for_cluster_type(stack));
            name = strdup(res.nodename);
        }

        if (name == NULL) {
            crm_err("Could not obtain the local %s node name", name_for_cluster_type(stack));
            crm_exit(DAEMON_RESPAWN_STOP);
        }
    }

    if (name == NULL) {
        crm_notice("Could not obtain a node name for %s nodeid %u",
                   name_for_cluster_type(stack), nodeid);
    }
    return name;
}
Example #5
0
gboolean
corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode * xml_parent)
{
    int lpc = 0;
    cs_error_t rc = CS_OK;
    int retries = 0;
    gboolean any = FALSE;
    cmap_handle_t cmap_handle;
    int fd = -1;
    uid_t found_uid = 0;
    gid_t found_gid = 0;
    pid_t found_pid = 0;
    int rv;

    do {
        rc = cmap_initialize(&cmap_handle);
        if (rc != CS_OK) {
            retries++;
            crm_debug("API connection setup failed: %s.  Retrying in %ds", cs_strerror(rc),
                      retries);
            sleep(retries);
        }

    } while (retries < 5 && rc != CS_OK);

    if (rc != CS_OK) {
        crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
        return FALSE;
    }

    rc = cmap_fd_get(cmap_handle, &fd);
    if (rc != CS_OK) {
        crm_err("Could not obtain the CMAP API connection: %s (%d)",
                cs_strerror(rc), rc);
        goto bail;
    }

    /* CMAP provider run as root (in given user namespace, anyway)? */
    if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
                                            &found_uid, &found_gid))) {
        crm_err("CMAP provider is not authentic:"
                " process %lld (uid: %lld, gid: %lld)",
                (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
                (long long) found_uid, (long long) found_gid);
        goto bail;
    } else if (rv < 0) {
        crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
                strerror(-rv), -rv);
        goto bail;
    }

    crm_peer_init();
    crm_trace("Initializing corosync nodelist");
    for (lpc = 0; TRUE; lpc++) {
        uint32_t nodeid = 0;
        char *name = NULL;
        char *key = NULL;

        key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
        rc = cmap_get_uint32(cmap_handle, key, &nodeid);
        free(key);

        if (rc != CS_OK) {
            break;
        }

        name = corosync_node_name(cmap_handle, nodeid);
        if (name != NULL) {
            GHashTableIter iter;
            crm_node_t *node = NULL;

            g_hash_table_iter_init(&iter, crm_peer_cache);
            while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
                if(node && node->uname && strcasecmp(node->uname, name) == 0) {
                    if (node->id && node->id != nodeid) {
                        crm_crit("Nodes %u and %u share the same name '%s': shutting down", node->id,
                                 nodeid, name);
                        crm_exit(CRM_EX_FATAL);
                    }
                }
            }
        }

        if (nodeid > 0 || name != NULL) {
            crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
            crm_get_peer(nodeid, name);
        }

        if (nodeid > 0 && name != NULL) {
            any = TRUE;

            if (xml_parent) {
                xmlNode *node = create_xml_node(xml_parent, XML_CIB_TAG_NODE);

                crm_xml_set_id(node, "%u", nodeid);
                crm_xml_add(node, XML_ATTR_UNAME, name);
                if (force_member) {
                    crm_xml_add(node, XML_ATTR_TYPE, CRM_NODE_MEMBER);
                }
            }
        }

        free(name);
    }
bail:
    cmap_finalize(cmap_handle);
    return any;
}