Exemplo n.º 1
0
gboolean
crm_cluster_connect(crm_cluster_t * cluster)
{
    enum cluster_type_e type = get_cluster_type();

    crm_notice("Connecting to cluster infrastructure: %s", name_for_cluster_type(type));
#if SUPPORT_COROSYNC
    if (is_openais_cluster()) {
        crm_peer_init();
        return init_cs_connection(cluster);
    }
#endif

#if SUPPORT_HEARTBEAT
    if (is_heartbeat_cluster()) {
        int rv;

        /* coverity[var_deref_op] False positive */
        if (cluster->hb_conn == NULL) {
            /* No object passed in, create a new one. */
            ll_cluster_t *(*new_cluster) (const char *llctype) =
                find_library_function(&hb_library, HEARTBEAT_LIBRARY, "ll_cluster_new", 1);

            cluster->hb_conn = (*new_cluster) ("heartbeat");
            /* dlclose(handle); */

        } else {
            /* Object passed in. Disconnect first, then reconnect below. */
            cluster->hb_conn->llc_ops->signoff(cluster->hb_conn, FALSE);
        }

        /* make sure we are disconnected first with the old object, if any. */
        if (heartbeat_cluster && heartbeat_cluster != cluster->hb_conn) {
            heartbeat_cluster->llc_ops->signoff(heartbeat_cluster, FALSE);
        }

        CRM_ASSERT(cluster->hb_conn != NULL);
        heartbeat_cluster = cluster->hb_conn;

        rv = register_heartbeat_conn(cluster);
        if (rv) {
            /* we'll benefit from a bigger queue length on heartbeat side.
             * Otherwise, if peers send messages faster than we can consume
             * them right now, heartbeat messaging layer will kick us out once
             * it's (small) default queue fills up :(
             * If we fail to adjust the sendq length, that's not yet fatal, though.
             */
            if (HA_OK != heartbeat_cluster->llc_ops->set_sendq_len(heartbeat_cluster, 1024)) {
                crm_warn("Cannot set sendq length: %s",
                         heartbeat_cluster->llc_ops->errmsg(heartbeat_cluster));
            }
        }
        return rv;
    }
#endif
    crm_info("Unsupported cluster stack: %s", getenv("HA_cluster_type"));
    return FALSE;
}
Exemplo n.º 2
0
int
crmd_init(void)
{
    int exit_code = 0;
    enum crmd_fsa_state state;

    fsa_state = S_STARTING;
    fsa_input_register = 0;     /* zero out the regester */

    init_dotfile();
    crm_debug("Starting %s", crm_system_name);
    register_fsa_input(C_STARTUP, I_STARTUP, NULL);

    crm_peer_init();
    state = s_crmd_fsa(C_STARTUP);

    if (state == S_PENDING || state == S_STARTING) {
        /* Create the mainloop and run it... */
        crmd_mainloop = g_main_new(FALSE);
        crm_trace("Starting %s's mainloop", crm_system_name);

#ifdef REALTIME_SUPPORT
        static int crm_realtime = 1;

        if (crm_realtime == 1) {
            cl_enable_realtime();
        } else if (crm_realtime == 0) {
            cl_disable_realtime();
        }
        cl_make_realtime(SCHED_RR, 5, 64, 64);
#endif
        g_main_run(crmd_mainloop);
        if (is_set(fsa_input_register, R_STAYDOWN)) {
            crm_info("Inhibiting respawn by Heartbeat");
            exit_code = 100;
        }

    } else {
        crm_err("Startup of %s failed.  Current state: %s",
                crm_system_name, fsa_state2string(state));
        exit_code = 1;
    }

    crm_info("[%s] stopped (%d)", crm_system_name, exit_code);
    qb_log_fini();

    return exit_code;
}
Exemplo n.º 3
0
crm_node_t *
crm_get_peer_full(unsigned int id, const char *uname, int flags)
{
    crm_node_t *node = NULL;

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

    crm_peer_init();

    if (flags & CRM_GET_PEER_REMOTE) {
        node = g_hash_table_lookup(crm_remote_peer_cache, uname);
    }

    if (node == NULL && (flags & CRM_GET_PEER_CLUSTER)) {
        node = crm_get_peer(id, uname);
    }
    return node;
}
Exemplo n.º 4
0
gboolean
init_cs_connection_once(crm_cluster_t * cluster)
{
    const char *uuid = NULL;
    crm_node_t *peer = NULL;
    enum cluster_type_e stack = get_cluster_type();

    crm_peer_init();

    /* Here we just initialize comms */
    if (stack != pcmk_cluster_corosync) {
        crm_err("Invalid cluster type: %s (%d)", name_for_cluster_type(stack), stack);
        return FALSE;
    }

    if (cluster_connect_cpg(cluster) == FALSE) {
        return FALSE;
    }
    crm_info("Connection to '%s': established", name_for_cluster_type(stack));

    cluster->nodeid = get_local_nodeid(0);
    if(cluster->nodeid == 0) {
        crm_err("Could not establish local nodeid");
        return FALSE;
    }

    cluster->uname = get_node_name(0);
    if(cluster->uname == NULL) {
        crm_err("Could not establish local node name");
        return FALSE;
    }

    /* Ensure the local node always exists */
    peer = crm_get_peer(cluster->nodeid, cluster->uname);
    uuid = get_corosync_uuid(peer);

    if(uuid) {
        cluster->uuid = strdup(uuid);
    }

    return TRUE;
}
Exemplo n.º 5
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_peer_init();
    crm_debug("Creating entry for node %s/%u", uname, id);

    node = calloc(1, sizeof(crm_node_t));
    node->state = 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 = 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 (node->uuid == NULL) {
            const char *uuid = get_node_uuid(id, node->uname);

            if (node->uuid) {
                crm_info("Node %u has uuid %s", id, node->uuid);
            } else {
                node->uuid = strdup(uuid);
            }
        }

        if (crm_status_callback) {
            crm_status_callback(crm_status_uname, node, NULL);
        }
    }

    return node;
}
Exemplo n.º 6
0
void
crmd_init(void)
{
    crm_exit_t exit_code = CRM_EX_OK;
    enum crmd_fsa_state state;

    log_deprecation_warnings();

    fsa_state = S_STARTING;
    fsa_input_register = 0;     /* zero out the regester */

    init_dotfile();
    register_fsa_input(C_STARTUP, I_STARTUP, NULL);

    crm_peer_init();
    state = s_crmd_fsa(C_STARTUP);

    if (state == S_PENDING || state == S_STARTING) {
        /* Create the mainloop and run it... */
        crm_trace("Starting %s's mainloop", crm_system_name);
        g_main_loop_run(crmd_mainloop);
        if (is_set(fsa_input_register, R_STAYDOWN)) {
            crm_info("Inhibiting automated respawn");
            exit_code = CRM_EX_FATAL;
        }

    } else {
        crm_err("Startup of %s failed.  Current state: %s",
                crm_system_name, fsa_state2string(state));
        exit_code = CRM_EX_ERROR;
    }

    crm_info("%s[%lu] exiting with status %d (%s)",
             crm_system_name, (unsigned long) getpid(), exit_code,
             crm_exit_str(exit_code));
    crmd_fast_exit(exit_code);
}
Exemplo n.º 7
0
int
main(int argc, char **argv)
{
    int flag;
    int rc = 0;
    int index = 0;
    int argerr = 0;
    struct passwd *pwentry = NULL;

    crm_log_preinit(NULL, argc, argv);
    crm_set_options(NULL, "[options]",
                    long_options, "Daemon for storing and replicating the cluster configuration");

    crm_peer_init();

    mainloop_add_signal(SIGTERM, cib_shutdown);
    mainloop_add_signal(SIGPIPE, cib_enable_writes);

    cib_writer = mainloop_add_trigger(G_PRIORITY_LOW, write_cib_contents, NULL);

    while (1) {
        flag = crm_get_option(argc, argv, &index);
        if (flag == -1)
            break;

        switch (flag) {
            case 'V':
                crm_bump_log_level(argc, argv);
                break;
            case 's':
                stand_alone = TRUE;
                preserve_status = TRUE;
                cib_writes_enabled = FALSE;

                pwentry = getpwnam(CRM_DAEMON_USER);
                CRM_CHECK(pwentry != NULL,
                          crm_perror(LOG_ERR, "Invalid uid (%s) specified", CRM_DAEMON_USER);
                          return CRM_EX_FATAL);

                rc = setgid(pwentry->pw_gid);
                if (rc < 0) {
                    crm_perror(LOG_ERR, "Could not set group to %d", pwentry->pw_gid);
                    return CRM_EX_FATAL;
                }

                rc = initgroups(CRM_DAEMON_USER, pwentry->pw_gid);
                if (rc < 0) {
                    crm_perror(LOG_ERR, "Could not setup groups for user %d", pwentry->pw_uid);
                    return CRM_EX_FATAL;
                }

                rc = setuid(pwentry->pw_uid);
                if (rc < 0) {
                    crm_perror(LOG_ERR, "Could not set user to %d", pwentry->pw_uid);
                    return CRM_EX_FATAL;
                }
                break;
            case '?':          /* Help message */
                crm_help(flag, CRM_EX_OK);
                break;
            case 'w':
                cib_writes_enabled = TRUE;
                break;
            case 'r':
                cib_root = optarg;
                break;
            case 'm':
                cib_metadata();
                return CRM_EX_OK;
            default:
                ++argerr;
                break;
        }
    }
    if (argc - optind == 1 && safe_str_eq("metadata", argv[optind])) {
        cib_metadata();
        return CRM_EX_OK;
    }

    if (optind > argc) {
        ++argerr;
    }

    if (argerr) {
        crm_help('?', CRM_EX_USAGE);
    }

    crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);

    if (cib_root == NULL) {
        cib_root = CRM_CONFIG_DIR;
    } else {
        crm_notice("Using custom config location: %s", cib_root);
    }

    if (pcmk__daemon_can_write(cib_root, NULL) == FALSE) {
        crm_err("Terminating due to bad permissions on %s", cib_root);
        fprintf(stderr, "ERROR: Bad permissions on %s (see logs for details)\n",
                cib_root);
        fflush(stderr);
        return CRM_EX_FATAL;
    }

    /* read local config file */
    cib_init();

    // This should not be reachable
    CRM_CHECK(crm_hash_table_size(client_connections) == 0,
              crm_warn("Not all clients gone at exit"));
    g_hash_table_foreach(client_connections, log_cib_client, NULL);
    cib_cleanup();

    crm_info("Done");
    return CRM_EX_OK;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
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 (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 == NULL) {
        node = crm_new_peer(id, uname);
        if(uname) {
            const char *uuid = get_uuid(uname);
            crm_update_peer(__FUNCTION__, 0, 0, 0, -1, 0, uuid, uname, NULL, NULL);
        }
    }

    CRM_ASSERT(node);

    if (node && uname && node->uname == NULL) {
        node->uname = 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 && node->uname && node->uuid == NULL) {
        const char *uuid = get_node_uuid(id, node->uname);

        if (node->uuid) {
            crm_info("Node %u has uuid %s", id, node->uuid);
        } else if (uuid) {
            node->uuid = strdup(uuid);
        }
    }

    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;
}
Exemplo n.º 12
0
/*
  crmd起動初期処理


 C_で表現さえる原因は以下が用意されている
 
enum crmd_fsa_cause
{
	C_UNKNOWN = 0,
	C_STARTUP,
	C_IPC_MESSAGE,
	C_HA_MESSAGE,
	C_CCM_CALLBACK,
	C_CRMD_STATUS_CALLBACK,
	C_LRM_OP_CALLBACK,
	C_LRM_MONITOR_CALLBACK,
	C_TIMER_POPPED,
	C_SHUTDOWN,
	C_HEARTBEAT_FAILED,
	C_SUBSYSTEM_CONNECT,
	C_HA_DISCONNECT,
	C_FSA_INTERNAL,
	C_ILLEGAL
};
*/
int
crmd_init(void)
{
    int exit_code = 0;
    enum crmd_fsa_state state;

	/* 最初のfsa_stateをS_STARTINGにセット */
    fsa_state = S_STARTING;
    fsa_input_register = 0; /* zero out the regester */

    init_dotfile();
    crm_info("Starting %s", crm_system_name);
	/* Start時の自処理入力データを作成する */
	/*
	fsa_data->id        = last_data_id;
	fsa_data->fsa_input = I_STARTUP;
	fsa_data->fsa_cause = C_STARTUP;
	fsa_data->origin    = raised_from;
	fsa_data->data      = NULL;
	fsa_data->data_type = fsa_dt_none;
	fsa_data->actions   = with_actions;
	
	 #define register_fsa_input(cause, input, data) register_fsa_input_adv(cause, input, data, A_NOTHING, FALSE, __FUNCTION__)
	*/
    register_fsa_input(C_STARTUP, I_STARTUP, NULL);

    crm_peer_init();
    
    /* 最初のS_STARTING/C_STARTUP/I_STARTUP状態を処理する */
    state = s_crmd_fsa(C_STARTUP);
    
    if (state == S_PENDING || state == S_STARTING) {
	    /* Create the mainloop and run it... */
	    crmd_mainloop = g_main_new(FALSE);
	    crm_info("Starting %s's mainloop", crm_system_name);
	    
#ifdef REALTIME_SUPPORT
	    static int  crm_realtime = 1;
	    if (crm_realtime == 1){
		    cl_enable_realtime();
	    }else if (crm_realtime == 0){
		    cl_disable_realtime();
	    }
	    cl_make_realtime(SCHED_RR, 5, 64, 64);
#endif
		/* メインループ開始 */
	    g_main_run(crmd_mainloop);
	    if(is_set(fsa_input_register, R_STAYDOWN)) {
		    crm_info("Inhibiting respawn by Heartbeat");
		    exit_code = 100;
	    }

    } else {
	    crm_err("Startup of %s failed.  Current state: %s",
		    crm_system_name, fsa_state2string(state));
	    exit_code = 1;
    }
    
    crm_info("[%s] stopped (%d)", crm_system_name, exit_code);
    return exit_code;
}
Exemplo n.º 13
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;
}