Ejemplo n.º 1
0
void
crm_update_peer_proc(const char *source, crm_node_t *node, uint32_t flag, const char *status)
{
    uint32_t last = 0;
    gboolean changed = FALSE;

    CRM_CHECK(node != NULL, crm_err("%s: Could not set %s to %s for NULL",
                                    source, peer2text(flag), status);
              return);

    last = node->processes;
    if (safe_str_eq(status, ONLINESTATUS)) {
        if ((node->processes & flag) == 0) {
            set_bit_inplace(node->processes, flag);
            changed = TRUE;
        }

    } else if (node->processes & flag) {
        clear_bit_inplace(node->processes, flag);
        changed = TRUE;
    }

    if (changed) {
        crm_info("%s: %s.%d.%s is now %s", source, node->uname, node->id, peer2text(flag), status);
        if (crm_status_callback) {
            crm_status_callback(crm_status_processes, node, &last);
        }
    } else {
        crm_trace("%s: %s.%d.%s is unchanged %s", source, node->uname, node->id, peer2text(flag), status);
    }
}
Ejemplo n.º 2
0
void
crm_update_peer_state(const char *source, crm_node_t * node, const char *state, int membership)
{
    char *last = NULL;
    gboolean changed = FALSE;

    CRM_CHECK(node != NULL, crm_err("%s: Could not set 'state' to %s", source, state);
              return);

    last = node->state;
    if (state != NULL && safe_str_neq(node->state, state)) {
        node->state = strdup(state);
        changed = TRUE;
    }

    if (membership != 0 && safe_str_eq(node->state, CRM_NODE_MEMBER)) {
        node->last_seen = membership;
    }

    if (changed) {
        crm_notice("%s: Node %s[%u] - state is now %s (was %s)", source, node->uname, node->id, state, last);
        if (crm_status_callback) {
            enum crm_status_type status_type = crm_status_nstate;
            if (is_set(node->flags, crm_remote_node)) {
                status_type = crm_status_rstate;
            }
            crm_status_callback(status_type, node, last);
        }
        free(last);
    } else {
        crm_trace("%s: Node %s[%u] - state is unchanged (%s)", source, node->uname, node->id,
                  state);
    }
}
Ejemplo n.º 3
0
static crm_node_t *crm_new_peer(unsigned int id, const char *uname)
{
    crm_node_t *node = NULL;
    CRM_CHECK(uname != NULL || id > 0, return NULL);

    crm_debug("Creating entry for node %s/%u", uname, id);
    
    crm_malloc0(node, sizeof(crm_node_t));
    node->state = crm_strdup("unknown");

    if(id > 0) {
	node->id = id;
	crm_info("Node %s now has id: %u", crm_str(uname), id);
	g_hash_table_replace(crm_peer_id_cache, GUINT_TO_POINTER(node->id), node);
    }
    
    if(uname) {
	node->uname = crm_strdup(uname);
	CRM_ASSERT(node->uname != NULL);
	crm_info("Node %u is now known as %s", id, node->uname);
	g_hash_table_replace(crm_peer_cache, node->uname, node);

	if(is_openais_cluster()) {
	    node->uuid = crm_strdup(node->uname);
	}

	if(crm_status_callback) {
	    crm_status_callback(crm_status_uname, node, NULL);
	}	
    }
    
    return node;
}
Ejemplo n.º 4
0
void
crm_update_peer_proc(const char *source, crm_node_t * node, uint32_t flag, const char *status)
{
    uint32_t last = 0;
    gboolean changed = FALSE;

    CRM_CHECK(node != NULL, crm_err("%s: Could not set %s to %s for NULL",
                                    source, peer2text(flag), status); return);

    last = node->processes;
    if (status == NULL) {
        node->processes = flag;
        if (node->processes != last) {
            changed = TRUE;
        }

    } else if (safe_str_eq(status, ONLINESTATUS)) {
        if ((node->processes & flag) == 0) {
            set_bit(node->processes, flag);
            changed = TRUE;
        }
#if SUPPORT_PLUGIN
    } else if (safe_str_eq(status, CRM_NODE_MEMBER)) {
        if (flag > 0 && node->processes != flag) {
            node->processes = flag;
            changed = TRUE;
        }
#endif

    } else if (node->processes & flag) {
        clear_bit(node->processes, flag);
        changed = TRUE;
    }

    if (changed) {
        if (status == NULL && flag <= crm_proc_none) {
            crm_info("%s: Node %s[%u] - all processes are now offline", source, node->uname,
                     node->id);
        } else {
            crm_info("%s: Node %s[%u] - %s is now %s", source, node->uname, node->id,
                     peer2text(flag), status);
        }

        if (crm_status_callback) {
            crm_status_callback(crm_status_processes, node, &last);
        }
    } else {
        crm_trace("%s: Node %s[%u] - %s is unchanged (%s)", source, node->uname, node->id,
                  peer2text(flag), status);
    }
}
Ejemplo n.º 5
0
crm_node_t *crm_get_peer(unsigned int id, const char *uname)
{
    crm_node_t *node = NULL;
    if(uname != NULL) {
	node = g_hash_table_lookup(crm_peer_cache, uname);
    }
    
    if(node == NULL && id > 0) {
	node = g_hash_table_lookup(crm_peer_id_cache, GUINT_TO_POINTER(id));
	if(node && node->uname && uname) {
	    crm_crit("Node %s and %s share the same cluster node id '%u'!",
		     node->uname, uname, id);
	    
	    /* NOTE: Calling crm_new_peer() means the entry in 
	     * crm_peer_id_cache will point to the new entity
	     */

	    /* TODO: Replace the old uname instead? */
	    node = crm_new_peer(id, uname);
	    CRM_ASSERT(node->uname != NULL);
	}
    }

    if(node && uname && node->uname == NULL) {
	node->uname = crm_strdup(uname);
	crm_info("Node %u is now known as %s", id, uname);	
	g_hash_table_insert(crm_peer_cache, node->uname, node);
	if(crm_status_callback) {
	    crm_status_callback(crm_status_uname, node, NULL);
	}
	
    }

    if(node && id > 0 && id != node->id) {
	g_hash_table_remove(crm_peer_id_cache, GUINT_TO_POINTER(node->id));
	g_hash_table_insert(crm_peer_id_cache, GUINT_TO_POINTER(id), node);
	node->id = id;
	crm_info("Node %s now has id: %u", crm_str(uname), id);	
    }
    
    return node;
}
Ejemplo n.º 6
0
/* coverity[-alloc] Memory is referenced in one or both hashtables */
crm_node_t *
crm_get_peer(unsigned int id, const char *uname)
{
    GHashTableIter iter;
    crm_node_t *node = NULL;
    crm_node_t *by_id = NULL;
    crm_node_t *by_name = NULL;

    CRM_ASSERT(id > 0 || uname != NULL);

    crm_peer_init();

    if (uname != NULL) {
        g_hash_table_iter_init(&iter, crm_peer_cache);
        while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
            if(node->uname && strcasecmp(node->uname, uname) == 0) {
                crm_trace("Name match: %s = %p", node->uname, node);
                by_name = node;
                break;
            }
        }
    }

    if (id > 0) {
        g_hash_table_iter_init(&iter, crm_peer_cache);
        while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
            if(node->id == id) {
                crm_trace("ID match: %u = %p", node->id, node);
                by_id = node;
                break;
            }
        }
    }

    node = by_id; /* Good default */
    if(by_id == by_name) {
        /* Nothing to do if they match (both NULL counts) */
        crm_trace("Consistent: %p for %u/%s", by_id, id, uname);

    } else if(by_id == NULL && by_name) {
        crm_trace("Only one: %p for %u/%s", by_name, id, uname);

        if(id && by_name->id) {
            crm_dump_peer_hash(LOG_WARNING, __FUNCTION__);
            crm_crit("Node %u and %u share the same name '%s'",
                     id, by_name->id, uname);
            node = NULL; /* Create a new one */

        } else {
            node = by_name;
        }

    } else if(by_name == NULL && by_id) {
        crm_trace("Only one: %p for %u/%s", by_id, id, uname);

        if(uname && by_id->uname) {
            crm_dump_peer_hash(LOG_WARNING, __FUNCTION__);
            crm_crit("Node '%s' and '%s' share the same cluster nodeid %u: assuming '%s' is correct",
                     uname, by_id->uname, id, uname);
        }

    } else if(uname && by_id->uname) {
        crm_warn("Node '%s' and '%s' share the same cluster nodeid: %u", by_id->uname, by_name->uname, id);

    } else if(id && by_name->id) {
        crm_warn("Node %u and %u share the same name: '%s'", by_id->id, by_name->id, uname);

    } else {
        /* Simple merge */

        /* Only corosync based clusters use nodeid's
         *
         * The functions that call crm_update_peer_state() only know nodeid
         * so 'by_id' is authorative when merging
         *
         * Same for crm_update_peer_proc()
         */
        crm_dump_peer_hash(LOG_DEBUG, __FUNCTION__);

        crm_info("Merging %p into %p", by_name, by_id);
        g_hash_table_foreach_remove(crm_peer_cache, crm_hash_find_by_data, by_name);
    }

    if (node == NULL) {
        char *uniqueid = crm_generate_uuid();

        node = calloc(1, sizeof(crm_node_t));
        CRM_ASSERT(node);

        crm_info("Created entry %s/%p for node %s/%u (%d total)",
                 uniqueid, node, uname, id, 1 + g_hash_table_size(crm_peer_cache));
        g_hash_table_replace(crm_peer_cache, uniqueid, node);
    }

    if(id > 0 && uname && (node->id == 0 || node->uname == NULL)) {
        crm_info("Node %u is now known as %s", id, uname);
    }

    if(id > 0 && node->id == 0) {
        node->id = id;
    }

    if(uname && node->uname == NULL) {
        int lpc, len = strlen(uname);

        for (lpc = 0; lpc < len; lpc++) {
            if (uname[lpc] >= 'A' && uname[lpc] <= 'Z') {
                crm_warn("Node names with capitals are discouraged, consider changing '%s' to something else",
                         uname);
                break;
            }
        }

        node->uname = strdup(uname);
        if (crm_status_callback) {
            crm_status_callback(crm_status_uname, node, NULL);
        }
    }

    if(node->uuid == NULL) {
        const char *uuid = crm_peer_uuid(node);

        if (uuid) {
            crm_info("Node %u has uuid %s", id, uuid);

        } else {
            crm_info("Cannot obtain a UUID for node %d/%s", id, node->uname);
        }
    }

    return node;
}
Ejemplo n.º 7
0
/* coverity[-alloc] Memory is referenced in one or both hashtables */
crm_node_t *
crm_get_peer(unsigned int id, const char *uname)
{
    crm_node_t *node = NULL;
    CRM_ASSERT(id > 0 || uname != NULL);

    crm_peer_init();

    if (node == NULL && uname != NULL) {
        node = g_hash_table_lookup(crm_peer_cache, uname);
    }

    if (node == NULL && id > 0) {
        node = g_hash_table_lookup(crm_peer_id_cache, GUINT_TO_POINTER(id));

        if (node && node->uname && uname) {
            crm_crit("Node %s and %s share the same cluster node id '%u'!", node->uname, uname, id);
            
            /* NOTE: Calling crm_new_peer() means the entry in 
             * crm_peer_id_cache will point to the new entity
             *
             * TO-DO: Replace the old uname instead?
             */
            node = NULL;
        }
    }

    if (node == NULL) {
        crm_debug("Creating entry for node %s/%u", uname, id);

        node = calloc(1, sizeof(crm_node_t));
        CRM_ASSERT(node);
    }

    if (id > 0 && node->id != id) {
        node->id = id;
        crm_info("Node %s now has id: %u", crm_str(uname), id);
        g_hash_table_replace(crm_peer_id_cache, GUINT_TO_POINTER(node->id), node);
    }

    if (uname && node->uname == NULL) {
        node->uname = strdup(uname);
        crm_info("Node %u is now known as %s", id, uname);
        g_hash_table_replace(crm_peer_cache, node->uname, node);
        if (crm_status_callback) {
            crm_status_callback(crm_status_uname, node, NULL);
        }
    }

    if (node && node->uname && node->uuid == NULL) {
        const char *uuid = get_node_uuid(id, node->uname);

        if(uuid) {
            node->uuid = strdup(uuid);
            crm_info("Node %u has uuid %s", id, node->uuid);
        } else {
            crm_warn("Cannot obtain a UUID for node %d/%s", id, node->uname);
        }
    }

    return node;
}
Ejemplo n.º 8
0
crm_node_t *
crm_update_peer(const char *source, unsigned int id, uint64_t born, uint64_t seen, int32_t votes, uint32_t children,
                const char *uuid, const char *uname, const char *addr, const char *state)
{
    gboolean addr_changed = FALSE;
    gboolean state_changed = FALSE;
    gboolean procs_changed = FALSE;
    gboolean votes_changed = FALSE;

    crm_node_t *node = NULL;

    id = get_corosync_id(id, uuid);

    CRM_CHECK(uname != NULL || id > 0, return NULL);
    CRM_ASSERT(crm_peer_cache != NULL);
    CRM_ASSERT(crm_peer_id_cache != NULL);

    node = crm_get_peer(id, uname);
    if (node == NULL) {
        crm_trace("No node found for %d/%s", id, uname);
        node = crm_new_peer(id, uname);

        CRM_LOG_ASSERT(node != NULL);
        if (node == NULL) {
            crm_err("Insufficient information to create node %d/%s", id, uname);
            return NULL;
        }

        /* do it now so we don't get '(new)' everywhere */
        node->votes = votes;
        node->processes = children;
        if (addr) {
            node->addr = strdup(addr);
        }
    }

    if (votes > 0 && node->votes != votes) {
        votes_changed = TRUE;
        node->votes = votes;
    }

    if (node->uuid == NULL) {
        if (is_openais_cluster()) {
            /* Yes, overrule whatever was passed in */
            node->uuid = get_corosync_uuid(id, uname);

        } else if (uuid != NULL) {
            node->uuid = strdup(uuid);
        }
    }

    if (children > 0 && children != node->processes) {
        uint32_t last = node->processes;

        node->processes = children;
        procs_changed = TRUE;

        if (crm_status_callback) {
            crm_status_callback(crm_status_processes, node, &last);
        }
    }

    if (born != 0) {
        node->born = born;
    }

    if (state != NULL && safe_str_neq(node->state, state)) {
        char *last = node->state;

        node->state = strdup(state);
        state_changed = TRUE;

        if (crm_status_callback) {
            crm_status_callback(crm_status_nstate, node, last);
        }
        free(last);
    }

    if (seen != 0 && safe_str_eq(node->state, CRM_NODE_MEMBER)) {
        node->last_seen = seen;
    }

    if (addr != NULL) {
        if (node->addr == NULL || crm_str_eq(node->addr, addr, FALSE) == FALSE) {
            addr_changed = TRUE;
            free(node->addr);
            node->addr = strdup(addr);
        }
    }

    if (state_changed || addr_changed || votes_changed) {
        do_crm_log_unlikely(state_changed?LOG_NOTICE:LOG_INFO,
                   "%s: Node %s: id=%u state=%s%s addr=%s%s votes=%d%s born=" U64T " seen=" U64T
                   " proc=%.32x%s", source, node->uname, node->id, node->state, state_changed ? " (new)" : "",
                   node->addr, addr_changed ? " (new)" : "", node->votes,
                   votes_changed ? " (new)" : "", node->born, node->last_seen, node->processes,
                   procs_changed ? " (new)" : "");

    } else if (procs_changed) {
        crm_debug("%s: Node %s: id=%u seen=" U64T
                  " proc=%.32x (new)", source, node->uname, node->id, node->last_seen, node->processes);
    }

    return node;
}
Ejemplo n.º 9
0
crm_node_t *crm_update_peer(
    unsigned int id, uint64_t born, uint64_t seen, int32_t votes, uint32_t children,
    const char *uuid, const char *uname, const char *addr, const char *state) 
{
    gboolean state_changed = FALSE;
    gboolean addr_changed = FALSE;
    gboolean procs_changed = FALSE;
    gboolean votes_changed = FALSE;
    
    crm_node_t *node = NULL;
    CRM_CHECK(uname != NULL || id > 0, return NULL);
    CRM_ASSERT(crm_peer_cache != NULL);
    CRM_ASSERT(crm_peer_id_cache != NULL);

    node = crm_get_peer(id, uname);
    if(node == NULL) {
	node = crm_new_peer(id, uname);

	/* do it now so we don't get '(new)' everywhere */
	node->votes = votes;
	node->processes = children;
	if(addr) {
	    node->addr = crm_strdup(addr);
	}
    }

    if(votes > 0 && node->votes != votes) {
	votes_changed = TRUE;
	node->votes = votes;
    }
    
    if(node->uuid == NULL) {
	if(uuid != NULL) {
	    node->uuid = crm_strdup(uuid);
	    
	} else if(node->uname != NULL && is_openais_cluster()) {
	    node->uuid = crm_strdup(node->uname);
	}
    }

    if(children > 0 && children != node->processes) {
	uint32_t last = node->processes;
	node->processes = children;
	procs_changed = TRUE;

	if(crm_status_callback) {
	    crm_status_callback(crm_status_processes, node, &last);
	}
    }

    if(born != 0) {
	node->born = born;
    }

    if(state != NULL && safe_str_neq(node->state, state)) {
	char *last = node->state;
	node->state = crm_strdup(state);
	state_changed = TRUE;

	if(crm_status_callback) {
	    crm_status_callback(crm_status_nstate, node, last);
	}
	crm_free(last);
    }

    if(seen != 0 && crm_is_member_active(node)) {
	node->last_seen = seen;
    }
    
    if(addr != NULL) {
	if(node->addr == NULL || crm_str_eq(node->addr, addr, FALSE) == FALSE) {
	    addr_changed = TRUE;
	    crm_free(node->addr);
	    node->addr = crm_strdup(addr);
	}
    }

    if(state_changed || addr_changed || votes_changed || procs_changed) {
	crm_info("Node %s: id=%u state=%s%s addr=%s%s votes=%d%s born="U64T" seen="U64T" proc=%.32x%s",
		 node->uname, node->id, 
		 node->state, state_changed?" (new)":"",
		 node->addr, addr_changed?" (new)":"",
		 node->votes, votes_changed?" (new)":"",
		 node->born, node->last_seen,
		 node->processes, procs_changed?" (new)":""
	);
    }
    
    return node;
}