/*
	welcomed_nodesハッシュテーブルのサイズが0(すべての認識済みのノードからCRM_OP_JOIN_REQUESTを受信した)の場合
*/
void
do_dc_join_finalize(long long action,
		    enum crmd_fsa_cause cause,
		    enum crmd_fsa_state cur_state,
		    enum crmd_fsa_input current_input,
		    fsa_data_t *msg_data)
{
	char *sync_from = NULL;
	enum cib_errors rc = cib_ok;

	/* This we can do straight away and avoid clients timing us out
	 *  while we compute the latest CIB
	 */
	crm_debug("Finializing join-%d for %d clients",
		  current_join_id, g_hash_table_size(integrated_nodes));
	if(g_hash_table_size(integrated_nodes) == 0) {
		/* integrated_nodesハッシュテーブルにまだ、welcom_nodesハッシュテーブルからデータが1つも移送されていない場合 */
		/* は、I_ELECTION_DCへ戻る */
		/* 認識済みのメンバーから、どのノードからもCRM_OP_JOIN_REQUESTを受信し終わっていない状態ということになる */
	    /* If we don't even have ourself, start again */
	    register_fsa_error_adv(
		C_FSA_INTERNAL, I_ELECTION_DC, NULL, NULL, __FUNCTION__);
	    return;
	}
	
	clear_bit_inplace(fsa_input_register, R_HAVE_CIB);
	if(max_generation_from == NULL
	   || safe_str_eq(max_generation_from, fsa_our_uname)){
		set_bit_inplace(fsa_input_register, R_HAVE_CIB);
	}

	if(is_set(fsa_input_register, R_IN_TRANSITION)) {
		crm_warn("join-%d: We are still in a transition."
			 "  Delaying until the TE completes.", current_join_id);
		crmd_fsa_stall(NULL);
		return;
	}
	
	if(is_set(fsa_input_register, R_HAVE_CIB) == FALSE) {
		/* ask for the agreed best CIB */
		sync_from = crm_strdup(max_generation_from);
		crm_log_xml_debug(max_generation_xml, "Requesting version");
		set_bit_inplace(fsa_input_register, R_CIB_ASKED);

	} else {
		/* Send _our_ CIB out to everyone */
		sync_from = crm_strdup(fsa_our_uname);
	}

	crm_info("join-%d: Syncing the CIB from %s to the rest of the cluster",
		 current_join_id, sync_from);
	/* CIBにsync_from処理を実行する */
	rc = fsa_cib_conn->cmds->sync_from(
	    fsa_cib_conn, sync_from, NULL,cib_quorum_override);
	/* sync_from処理のコールバックをセットする */
	/* 		コールバック内からCRM_OP_JOIN_ACKNAKメッセージを送信する	*/
	fsa_cib_conn->cmds->register_callback(
		    fsa_cib_conn, rc, 60, FALSE, sync_from,
		    "finalize_sync_callback", finalize_sync_callback);
}
Exemplo n.º 2
0
/*
 * Unpack everything
 * At the end you'll have:
 *  - A list of nodes
 *  - A list of resources (each with any dependencies on other resources)
 *  - A list of constraints between resources and nodes
 *  - A list of constraints between start/stop actions
 *  - A list of nodes that need to be stonith'd
 *  - A list of nodes that need to be shutdown
 *  - A list of the possible stop/start actions (without dependencies)
 */
gboolean
cluster_status(pe_working_set_t * data_set)
{
    xmlNode *config = get_object_root(XML_CIB_TAG_CRMCONFIG, data_set->input);
    xmlNode *cib_nodes = get_object_root(XML_CIB_TAG_NODES, data_set->input);
    xmlNode *cib_resources = get_object_root(XML_CIB_TAG_RESOURCES, data_set->input);
    xmlNode *cib_status = get_object_root(XML_CIB_TAG_STATUS, data_set->input);
    xmlNode *cib_domains = get_object_root(XML_CIB_TAG_DOMAINS, data_set->input);
    const char *value = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM);

    crm_trace("Beginning unpack");
    pe_dataset = data_set;

    /* reset remaining global variables */
    data_set->failed = create_xml_node(NULL, "failed-ops");

    if (data_set->input == NULL) {
        return FALSE;
    }

    if (data_set->now == NULL) {
        data_set->now = new_ha_date(TRUE);
    }

    if (data_set->input != NULL && crm_element_value(data_set->input, XML_ATTR_DC_UUID) != NULL) {
        /* this should always be present */
        data_set->dc_uuid = crm_element_value_copy(data_set->input, XML_ATTR_DC_UUID);
    }

    clear_bit_inplace(data_set->flags, pe_flag_have_quorum);
    if (crm_is_true(value)) {
        set_bit_inplace(data_set->flags, pe_flag_have_quorum);
    }

    data_set->op_defaults = get_object_root(XML_CIB_TAG_OPCONFIG, data_set->input);
    data_set->rsc_defaults = get_object_root(XML_CIB_TAG_RSCCONFIG, data_set->input);

    unpack_config(config, data_set);

    if (is_set(data_set->flags, pe_flag_have_quorum) == FALSE
        && data_set->no_quorum_policy != no_quorum_ignore) {
        crm_warn("We do not have quorum" " - fencing and resource management disabled");
    }

    unpack_nodes(cib_nodes, data_set);
    unpack_domains(cib_domains, data_set);
    unpack_resources(cib_resources, data_set);
    unpack_status(cib_status, data_set);

    set_bit_inplace(data_set->flags, pe_flag_have_status);
    return TRUE;
}
Exemplo n.º 3
0
/*	A_DC_JOIN_FINALIZE	*/
void
do_dc_join_finalize(long long action,
                    enum crmd_fsa_cause cause,
                    enum crmd_fsa_state cur_state,
                    enum crmd_fsa_input current_input, fsa_data_t * msg_data)
{
    char *sync_from = NULL;
    int rc = pcmk_ok;

    /* This we can do straight away and avoid clients timing us out
     *  while we compute the latest CIB
     */
    crm_debug("Finializing join-%d for %d clients",
              current_join_id, g_hash_table_size(integrated_nodes));
    if (g_hash_table_size(integrated_nodes) == 0) {
        /* If we don't even have ourself, start again */
        register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION_DC, NULL, NULL, __FUNCTION__);
        return;
    }

    clear_bit_inplace(fsa_input_register, R_HAVE_CIB);
    if (max_generation_from == NULL || safe_str_eq(max_generation_from, fsa_our_uname)) {
        set_bit_inplace(fsa_input_register, R_HAVE_CIB);
    }

    if (is_set(fsa_input_register, R_IN_TRANSITION)) {
        crm_warn("join-%d: We are still in a transition."
                 "  Delaying until the TE completes.", current_join_id);
        crmd_fsa_stall(NULL);
        return;
    }

    if (is_set(fsa_input_register, R_HAVE_CIB) == FALSE) {
        /* ask for the agreed best CIB */
        sync_from = strdup(max_generation_from);
        crm_log_xml_debug(max_generation_xml, "Requesting version");
        set_bit_inplace(fsa_input_register, R_CIB_ASKED);

    } else {
        /* Send _our_ CIB out to everyone */
        sync_from = strdup(fsa_our_uname);
    }

    crm_info("join-%d: Syncing the CIB from %s to the rest of the cluster",
             current_join_id, sync_from);

    rc = fsa_cib_conn->cmds->sync_from(fsa_cib_conn, sync_from, NULL, cib_quorum_override);

    fsa_cib_conn->cmds->register_callback(fsa_cib_conn, rc, 60, FALSE, sync_from,
                                          "finalize_sync_callback", finalize_sync_callback);
}
Exemplo n.º 4
0
static enum pe_action_flags
get_action_flags(action_t * action, node_t * node)
{
    enum pe_action_flags flags = action->flags;

    if (action->rsc) {
        flags = action->rsc->cmds->action_flags(action, NULL);

        if (action->rsc->variant >= pe_clone && node) {

            /* We only care about activity on $node */
            enum pe_action_flags clone_flags = action->rsc->cmds->action_flags(action, node);

            /* Go to great lengths to ensure the correct value for pe_action_runnable...
             *
             * If we are a clone, then for _ordering_ constraints, its only relevant
             * if we are runnable _anywhere_.
             *
             * This only applies to _runnable_ though, and only for ordering constraints.
             * If this function is ever used during colocation, then we'll need additional logic
             *
             * Not very satisfying, but its logical and appears to work well.
             */
            if (is_not_set(clone_flags, pe_action_runnable)
                && is_set(flags, pe_action_runnable)) {
                crm_trace("Fixing up runnable flag for %s", action->uuid);
                set_bit_inplace(clone_flags, pe_action_runnable);
            }
            flags = clone_flags;
        }
    }
    return flags;
}
Exemplo n.º 5
0
void
finalize_sync_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
{
    CRM_LOG_ASSERT(-EPERM != rc);
    clear_bit_inplace(fsa_input_register, R_CIB_ASKED);
    if (rc != pcmk_ok) {
        do_crm_log((rc == -pcmk_err_old_data ? LOG_WARNING : LOG_ERR),
                   "Sync from %s failed: %s",
                   (char *)user_data, pcmk_strerror(rc));

        /* restart the whole join process */
        register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION_DC, NULL, NULL, __FUNCTION__);

    } else if (AM_I_DC && fsa_state == S_FINALIZE_JOIN) {
        set_bit_inplace(fsa_input_register, R_HAVE_CIB);
        clear_bit_inplace(fsa_input_register, R_CIB_ASKED);

        /* make sure dc_uuid is re-set to us */
        if (check_join_state(fsa_state, __FUNCTION__) == FALSE) {
            crm_debug("Notifying %d clients of join-%d results",
                      g_hash_table_size(integrated_nodes), current_join_id);
            g_hash_table_foreach_remove(integrated_nodes, finalize_join_for, NULL);
        }

    } else {
        crm_debug("No longer the DC in S_FINALIZE_JOIN: %s/%s",
                  AM_I_DC ? "DC" : "CRMd", fsa_state2string(fsa_state));
    }

    free(user_data);
}
Exemplo n.º 6
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);
    }
}
Exemplo n.º 7
0
void crm_update_peer_proc(const char *uname, uint32_t flag, const char *status) 
{
    crm_node_t *node = NULL;
    gboolean changed = FALSE;
    CRM_ASSERT(crm_peer_cache != NULL);

    CRM_CHECK(uname != NULL, return);
    node = g_hash_table_lookup(crm_peer_cache, uname);	
    CRM_CHECK(node != NULL,
	      crm_err("Could not set %s.%s to %s", uname, peer2text(flag), status);
	      return);

    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 is now %s", uname, peer2text(flag), status);
    }
}
/*
	CIBへのsync_from処理のコールバック処理
		CRM_OP_JOIN_ACKNAKメッセージを送信する
*/
void
finalize_sync_callback(xmlNode *msg, int call_id, int rc,
		       xmlNode *output, void *user_data) 
{
	CRM_DEV_ASSERT(cib_not_master != rc);
	clear_bit_inplace(fsa_input_register, R_CIB_ASKED);
	if(rc != cib_ok) {
		do_crm_log((rc==cib_old_data?LOG_WARNING:LOG_ERR),
			      "Sync from %s resulted in an error: %s",
			      (char*)user_data, cib_error2string(rc));

		/* restart the whole join process */
		/* コールバックがcib_okではない場合は、I_ELECTION_DCに戻る */
		register_fsa_error_adv(
			C_FSA_INTERNAL, I_ELECTION_DC,NULL,NULL,__FUNCTION__);

	} else if(AM_I_DC && fsa_state == S_FINALIZE_JOIN) {
		/* 自ノードがDCノードで、fsa_stateがS_FINALIZE_JOINの場合 */
	    set_bit_inplace(fsa_input_register, R_HAVE_CIB);
	    clear_bit_inplace(fsa_input_register, R_CIB_ASKED);
	    
	    /* make sure dc_uuid is re-set to us */
	    /* JOIN状態チェック処理 */
	    if(check_join_state(fsa_state, __FUNCTION__) == FALSE) {
			crm_debug("Notifying %d clients of join-%d results",
			  g_hash_table_size(integrated_nodes), current_join_id);
			
			/*
				ノードをCIBのnodeエントリに追加して、CRM_OP_JOIN_ACKNAKメッセージを送信する
				また、クラスタメンバーとして認識したノードは、finalized_nodesハッシュテーブルに追加する	
				そして、integrated_nodesハッシュテーブルから削除する
			*/
			g_hash_table_foreach_remove(
		    	integrated_nodes, finalize_join_for, NULL);
	    }
		
	} else {
		crm_debug("No longer the DC in S_FINALIZE_JOIN: %s/%s",
			  AM_I_DC?"DC":"CRMd", fsa_state2string(fsa_state));
	}
	
	crm_free(user_data);
}
Exemplo n.º 9
0
gboolean
crm_connect_corosync(void)
{
    gboolean rc = FALSE;

    if (is_openais_cluster()) {
        crm_set_status_callback(&ais_status_callback);
        rc = crm_cluster_connect(&fsa_our_uname, &fsa_our_uuid, crmd_ais_dispatch, crmd_ais_destroy,
                                 NULL);
    }

    if (rc && is_corosync_cluster()) {
        init_quorum_connection(crmd_cman_dispatch, crmd_quorum_destroy);
    }

    if (rc && is_cman_cluster()) {
        init_cman_connection(crmd_cman_dispatch, crmd_cman_destroy);
        set_bit_inplace(fsa_input_register, R_CCM_DATA);
    }
    return rc;
}
Exemplo n.º 10
0
gboolean
crmd_authorize_message(xmlNode * client_msg, crmd_client_t * curr_client)
{
    /* check the best case first */
    const char *sys_from = crm_element_value(client_msg, F_CRM_SYS_FROM);
    char *uuid = NULL;
    char *client_name = NULL;
    char *major_version = NULL;
    char *minor_version = NULL;
    const char *filtered_from;
    gpointer table_key = NULL;
    gboolean auth_result = FALSE;
    struct crm_subsystem_s *the_subsystem = NULL;
    gboolean can_reply = FALSE; /* no-one has registered with this id */

    xmlNode *xml = NULL;
    const char *op = crm_element_value(client_msg, F_CRM_TASK);

    if (safe_str_neq(CRM_OP_HELLO, op)) {

        if (sys_from == NULL) {
            crm_warn("Message [%s] was had no value for %s... discarding",
                     crm_element_value(client_msg, XML_ATTR_REFERENCE), F_CRM_SYS_FROM);
            return FALSE;
        }

        filtered_from = sys_from;

        /* The CIB can have two names on the DC */
        if (strcasecmp(sys_from, CRM_SYSTEM_DCIB) == 0)
            filtered_from = CRM_SYSTEM_CIB;

        if (g_hash_table_lookup(ipc_clients, filtered_from) != NULL) {
            can_reply = TRUE;   /* reply can be routed */
        }

        crm_debug_2("Message reply can%s be routed from %s.", can_reply ? "" : " not", sys_from);

        if (can_reply == FALSE) {
            crm_warn("Message [%s] not authorized",
                     crm_element_value(client_msg, XML_ATTR_REFERENCE));
        }

        return can_reply;
    }

    crm_debug_3("received client join msg");
    crm_log_xml(LOG_MSG, "join", client_msg);
    xml = get_message_xml(client_msg, F_CRM_DATA);
    auth_result = process_hello_message(xml, &uuid, &client_name, &major_version, &minor_version);

    if (auth_result == TRUE) {
        if (client_name == NULL || uuid == NULL) {
            crm_err("Bad client details (client_name=%s, uuid=%s)",
                    crm_str(client_name), crm_str(uuid));
            auth_result = FALSE;
        }
    }

    if (auth_result == TRUE) {
        /* check version */
        int mav = atoi(major_version);
        int miv = atoi(minor_version);

        crm_debug_3("Checking client version number");
        if (mav < 0 || miv < 0) {
            crm_err("Client version (%d:%d) is not acceptable", mav, miv);
            auth_result = FALSE;
        }
        crm_free(major_version);
        crm_free(minor_version);
    }

    if (safe_str_eq(CRM_SYSTEM_PENGINE, client_name)) {
        the_subsystem = pe_subsystem;

    } else if (safe_str_eq(CRM_SYSTEM_TENGINE, client_name)) {
        the_subsystem = te_subsystem;
    }

    /* TODO: Is this code required anymore?? */
    if (auth_result == TRUE && the_subsystem != NULL) {
        /* if we already have one of those clients
         * only applies to te, pe etc.  not admin clients
         */
        crm_err("Checking if %s is required/already connected", client_name);

        table_key = (gpointer) crm_strdup(client_name);

        if (is_set(fsa_input_register, the_subsystem->flag_connected)) {
            auth_result = FALSE;
            crm_free(table_key);
            table_key = NULL;
            crm_warn("Bit\t%.16llx set in %.16llx",
                     the_subsystem->flag_connected, fsa_input_register);
            crm_err("Client %s is already connected", client_name);

        } else if (FALSE == is_set(fsa_input_register, the_subsystem->flag_required)) {
            crm_warn("Bit\t%.16llx not set in %.16llx",
                     the_subsystem->flag_connected, fsa_input_register);
            crm_warn("Client %s joined but we dont need it", client_name);
            stop_subsystem(the_subsystem, TRUE);

        } else {
            the_subsystem->ipc = curr_client->client_channel;
            set_bit_inplace(fsa_input_register, the_subsystem->flag_connected);
        }

    } else {
        table_key = (gpointer) generate_hash_key(client_name, uuid);
    }

    if (auth_result == TRUE) {
        crm_debug_2("Accepted client %s", crm_str(table_key));

        curr_client->table_key = table_key;
        curr_client->sub_sys = crm_strdup(client_name);
        curr_client->uuid = crm_strdup(uuid);

        g_hash_table_insert(ipc_clients, table_key, curr_client->client_channel);

        send_hello_message(curr_client->client_channel, "n/a", CRM_SYSTEM_CRMD, "0", "1");

        crm_debug_3("Updated client list with %s", crm_str(table_key));

        crm_debug_3("Triggering FSA: %s", __FUNCTION__);
        mainloop_set_trigger(fsa_source);

        if (the_subsystem != NULL) {
            CRM_CHECK(the_subsystem->client == NULL,
                      process_client_disconnect(the_subsystem->client));
            the_subsystem->client = curr_client;
        }

    } else {
        crm_free(table_key);
        crm_warn("Rejected client logon request");
        curr_client->client_channel->ch_status = IPC_DISC_PENDING;
    }

    if (uuid != NULL)
        crm_free(uuid);
    if (minor_version != NULL)
        crm_free(minor_version);
    if (major_version != NULL)
        crm_free(major_version);
    if (client_name != NULL)
        crm_free(client_name);

    /* hello messages should never be processed further */
    return FALSE;
}
Exemplo n.º 11
0
int
main(int argc, char **argv)
{
    GListPtr lpc = NULL;
    gboolean process = TRUE;
    gboolean all_good = TRUE;
    enum transition_status graph_rc = -1;
    crm_graph_t *transition = NULL;
    ha_time_t *a_date = NULL;
    cib_t *cib_conn = NULL;

    xmlNode *cib_object = NULL;
    int argerr = 0;
    int flag;

    char *msg_buffer = NULL;
    gboolean optional = FALSE;
    pe_working_set_t data_set;

    const char *source = NULL;
    const char *xml_file = NULL;
    const char *dot_file = NULL;
    const char *graph_file = NULL;
    const char *input_file = NULL;
    const char *input_xml = NULL;

    /* disable glib's fancy allocators that can't be free'd */
    GMemVTable vtable;

    vtable.malloc = malloc;
    vtable.realloc = realloc;
    vtable.free = free;
    vtable.calloc = calloc;
    vtable.try_malloc = malloc;
    vtable.try_realloc = realloc;

    g_mem_set_vtable(&vtable);

    crm_log_init_quiet(NULL, LOG_CRIT, FALSE, FALSE, argc, argv);
    crm_set_options(NULL, "[-?Vv] -[Xxp] {other options}", long_options,
                    "Calculate the cluster's response to the supplied cluster state\n"
                    "\nSuperceeded by crm_simulate and likely to be removed in a future release\n\n");

    while (1) {
        int option_index = 0;

        flag = crm_get_option(argc, argv, &option_index);
        if (flag == -1)
            break;

        switch (flag) {
            case 'S':
                do_simulation = TRUE;
                break;
            case 'a':
                all_actions = TRUE;
                break;
            case 'w':
                inhibit_exit = TRUE;
                break;
            case 'X':
                /*use_stdin = TRUE;*/
                input_xml = optarg;
                break;
            case 's':
                show_scores = TRUE;
                break;
            case 'U':
                show_utilization = TRUE;
                break;
            case 'x':
                xml_file = optarg;
                break;
            case 'd':
                use_date = optarg;
                break;
            case 'D':
                dot_file = optarg;
                break;
            case 'G':
                graph_file = optarg;
                break;
            case 'I':
                input_file = optarg;
                break;
            case 'V':
                crm_bump_log_level();
                break;
            case 'L':
                USE_LIVE_CIB = TRUE;
                break;
            case '$':
            case '?':
                crm_help(flag, 0);
                break;
            default:
                fprintf(stderr, "Option -%c is not yet supported\n", flag);
                ++argerr;
                break;
        }
    }

    if (optind < argc) {
        printf("non-option ARGV-elements: ");
        while (optind < argc) {
            printf("%s ", argv[optind++]);
        }
        printf("\n");
    }

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

    if (argerr) {
        crm_err("%d errors in option parsing", argerr);
        crm_help('?', 1);
    }

    update_all_trace_data();    /* again, so we see which trace points got updated */

    if (USE_LIVE_CIB) {
        int rc = cib_ok;

        source = "live cib";
        cib_conn = cib_new();
        rc = cib_conn->cmds->signon(cib_conn, "ptest", cib_command);

        if (rc == cib_ok) {
            crm_info("Reading XML from: live cluster");
            cib_object = get_cib_copy(cib_conn);

        } else {
            fprintf(stderr, "Live CIB query failed: %s\n", cib_error2string(rc));
            return 3;
        }
        if (cib_object == NULL) {
            fprintf(stderr, "Live CIB query failed: empty result\n");
            return 3;
        }

    } else if (xml_file != NULL) {
        source = xml_file;
        cib_object = filename2xml(xml_file);

    } else if (use_stdin) {
        source = "stdin";
        cib_object = filename2xml(NULL);
    } else if (input_xml) {
        source = "input string";
        cib_object = string2xml(input_xml);
    }

    if (cib_object == NULL && source) {
        fprintf(stderr, "Could not parse configuration input from: %s\n", source);
        return 4;

    } else if (cib_object == NULL) {
        fprintf(stderr, "No configuration specified\n");
        crm_help('?', 1);
    }

    if (get_object_root(XML_CIB_TAG_STATUS, cib_object) == NULL) {
        create_xml_node(cib_object, XML_CIB_TAG_STATUS);
    }

    if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) {
        free_xml(cib_object);
        return cib_STALE;
    }

    if (validate_xml(cib_object, NULL, FALSE) != TRUE) {
        free_xml(cib_object);
        return cib_dtd_validation;
    }

    if (input_file != NULL) {
        FILE *input_strm = fopen(input_file, "w");

        if (input_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", input_file);
        } else {
            msg_buffer = dump_xml_formatted(cib_object);
            if (fprintf(input_strm, "%s\n", msg_buffer) < 0) {
                crm_perror(LOG_ERR, "Write to %s failed", input_file);
            }
            fflush(input_strm);
            fclose(input_strm);
            crm_free(msg_buffer);
        }
    }

    if (use_date != NULL) {
        a_date = parse_date(&use_date);
        log_date(LOG_WARNING, "Set fake 'now' to", a_date, ha_log_date | ha_log_time);
        log_date(LOG_WARNING, "Set fake 'now' to (localtime)",
                 a_date, ha_log_date | ha_log_time | ha_log_local);
    }

    set_working_set_defaults(&data_set);
    if (process) {
        if (show_scores && show_utilization) {
            fprintf(stdout, "Allocation scores and utilization information:\n");
        } else if (show_scores) {
            fprintf(stdout, "Allocation scores:\n");
        } else if (show_utilization) {
            fprintf(stdout, "Utilization information:\n");
        }
        do_calculations(&data_set, cib_object, a_date);
    }

    msg_buffer = dump_xml_formatted(data_set.graph);
    if (safe_str_eq(graph_file, "-")) {
        fprintf(stdout, "%s\n", msg_buffer);
        fflush(stdout);
    } else if (graph_file != NULL) {
        FILE *graph_strm = fopen(graph_file, "w");

        if (graph_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", graph_file);
        } else {
            if (fprintf(graph_strm, "%s\n\n", msg_buffer) < 0) {
                crm_perror(LOG_ERR, "Write to %s failed", graph_file);
            }
            fflush(graph_strm);
            fclose(graph_strm);
        }
    }
    crm_free(msg_buffer);

    if (dot_file != NULL) {
        dot_strm = fopen(dot_file, "w");
        if (dot_strm == NULL) {
            crm_perror(LOG_ERR, "Could not open %s for writing", dot_file);
        }
    }

    if (dot_strm == NULL) {
        goto simulate;
    }

    init_dotfile();
    for (lpc = data_set.actions; lpc != NULL; lpc = lpc->next) {
        action_t *action = (action_t *) lpc->data;
        const char *style = "filled";
        const char *font = "black";
        const char *color = "black";
        const char *fill = NULL;
        char *action_name = create_action_name(action);

        crm_trace("Action %d: %p", action->id, action);

        if (is_set(action->flags, pe_action_pseudo)) {
            font = "orange";
        }

        style = "dashed";
        if (is_set(action->flags, pe_action_dumped)) {
            style = "bold";
            color = "green";

        } else if (action->rsc != NULL && is_not_set(action->rsc->flags, pe_rsc_managed)) {
            color = "purple";
            if (all_actions == FALSE) {
                goto dont_write;
            }

        } else if (is_set(action->flags, pe_action_optional)) {
            color = "blue";
            if (all_actions == FALSE) {
                goto dont_write;
            }

        } else {
            color = "red";
            CRM_CHECK(is_set(action->flags, pe_action_runnable) == FALSE,;
                );
        }

        set_bit_inplace(action->flags, pe_action_dumped);
        dot_write("\"%s\" [ style=%s color=\"%s\" fontcolor=\"%s\"  %s%s]",
                  action_name, style, color, font, fill ? "fillcolor=" : "", fill ? fill : "");
  dont_write:
        crm_free(action_name);
    }
Exemplo n.º 12
0
/*	 A_TE_START, A_TE_STOP, A_TE_RESTART	*/
void
do_te_control(long long action,
	      enum crmd_fsa_cause cause,
	      enum crmd_fsa_state cur_state,
	      enum crmd_fsa_input current_input,
	      fsa_data_t *msg_data)
{
    int dummy;
    gboolean init_ok = TRUE;
	
    cl_uuid_t new_uuid;
    char uuid_str[UU_UNPARSE_SIZEOF];
	
    if(action & A_TE_STOP) {
	if(transition_graph) {
	    destroy_graph(transition_graph);
	    transition_graph = NULL;
	}

	if(fsa_cib_conn && cib_ok != fsa_cib_conn->cmds->del_notify_callback(
	       fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff)) {
	    crm_err("Could not unset CIB notification callback");
	}

	clear_bit_inplace(fsa_input_register, te_subsystem->flag_connected);
	crm_info("Transitioner is now inactive");
	
	if(stonith_src) {
	    GCHSource *source = stonith_src;
	    crm_info("Disconnecting STONITH...");
	    stonith_src = NULL; /* so that we don't try to reconnect */
	    G_main_del_IPC_Channel(source);
	    stonithd_signoff();	    
	}
    }

    if((action & A_TE_START) == 0) {
	return;

    } else if(is_set(fsa_input_register, te_subsystem->flag_connected)) {
	crm_debug("The transitioner is already active");
	return;

    } else if((action & A_TE_START) && cur_state == S_STOPPING) {
	crm_info("Ignoring request to start %s while shutting down",
		 te_subsystem->name);
	return;
    }	

    cl_uuid_generate(&new_uuid);
    cl_uuid_unparse(&new_uuid, uuid_str);
    te_uuid = crm_strdup(uuid_str);
    crm_info("Registering TE UUID: %s", te_uuid);
	
    if(transition_trigger == NULL) {
	transition_trigger = mainloop_add_trigger(
	    G_PRIORITY_LOW, te_graph_trigger, NULL);
    }

    if(stonith_reconnect == NULL) {
	stonith_reconnect = mainloop_add_trigger(
	    G_PRIORITY_LOW, te_connect_stonith, &dummy);
    }
		    
    if(cib_ok != fsa_cib_conn->cmds->add_notify_callback(
	   fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff)) {
	crm_err("Could not set CIB notification callback");
	init_ok = FALSE;
    }

    if(cib_ok != fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn, global_cib_callback)) {
	crm_err("Could not set CIB global callback");
	init_ok = FALSE;
    }
    
    if(init_ok) {
	mainloop_set_trigger(stonith_reconnect);

	set_graph_functions(&te_graph_fns);

	if(transition_graph) {
	    destroy_graph(transition_graph);			    
	}
			
	/* create a blank one */
	crm_debug("Transitioner is now active");
	transition_graph = create_blank_graph();
	set_bit_inplace(fsa_input_register, te_subsystem->flag_connected);
    }
}
Exemplo n.º 13
0
/*	 A_CIB_STOP, A_CIB_START, A_CIB_RESTART,	*/
void
do_cib_control(long long action,
	       enum crmd_fsa_cause cause,
	       enum crmd_fsa_state cur_state,
	       enum crmd_fsa_input current_input,
	       fsa_data_t *msg_data)
{
	struct crm_subsystem_s *this_subsys = cib_subsystem;
	
	long long stop_actions = A_CIB_STOP;
	long long start_actions = A_CIB_START;

	if(action & stop_actions) {

		if (fsa_cib_conn->state != cib_disconnected && last_resource_update != 0) {
		    crm_info("Waiting for resource update %d to complete", last_resource_update);
		    crmd_fsa_stall(NULL);
		    return;
		}

		crm_info("Disconnecting CIB");
		clear_bit_inplace(fsa_input_register, R_CIB_CONNECTED);
		CRM_ASSERT(fsa_cib_conn != NULL);

		fsa_cib_conn->cmds->del_notify_callback(
		    fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated);

		if(fsa_cib_conn->state != cib_disconnected) {
			fsa_cib_conn->cmds->set_slave(
				fsa_cib_conn, cib_scope_local);
			fsa_cib_conn->cmds->signoff(fsa_cib_conn);
		}
	}

	if(action & start_actions) {
		int rc = cib_ok;
		
		CRM_ASSERT(fsa_cib_conn != NULL);
		
		if(cur_state == S_STOPPING) {
			crm_err("Ignoring request to start %s after shutdown",
				this_subsys->name);
			return;
		}

		rc = fsa_cib_conn->cmds->signon(
			fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command);

		if(rc != cib_ok) {
			/* a short wait that usually avoids stalling the FSA */
			sleep(1); 
			rc = fsa_cib_conn->cmds->signon(
				fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command);
		}
		
		if(rc != cib_ok){
			crm_info("Could not connect to the CIB service: %s", cib_error2string(rc));

		} else if(cib_ok != fsa_cib_conn->cmds->set_connection_dnotify(
				  fsa_cib_conn, crmd_cib_connection_destroy)) {
			crm_err("Could not set dnotify callback");
			
		} else if(cib_ok != fsa_cib_conn->cmds->add_notify_callback(
				  fsa_cib_conn, T_CIB_REPLACE_NOTIFY,
				  do_cib_replaced)) {
			crm_err("Could not set CIB notification callback");

		} else if(cib_ok != fsa_cib_conn->cmds->add_notify_callback(
			      fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated)) {
		    crm_err("Could not set CIB notification callback");
			
		} else {
			set_bit_inplace(
				fsa_input_register, R_CIB_CONNECTED);
		}
		
		if(is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) {
			
			cib_retries++;
			crm_warn("Couldn't complete CIB registration %d"
				 " times... pause and retry",
				 cib_retries);
			
			if(cib_retries < 30) {
				crm_timer_start(wait_timer);
				crmd_fsa_stall(NULL);
				
			} else {
				crm_err("Could not complete CIB"
					" registration  %d times..."
					" hard error", cib_retries);
				register_fsa_error(
					C_FSA_INTERNAL, I_ERROR, NULL);
			}
		} else {
			int call_id = 0;
			
			crm_info("CIB connection established");
			
			call_id = fsa_cib_conn->cmds->query(
				fsa_cib_conn, NULL, NULL, cib_scope_local);
			
			add_cib_op_callback(fsa_cib_conn, call_id, FALSE, NULL,
					    revision_check_callback);
			cib_retries = 0;
		}
	}
}
Exemplo n.º 14
0
int
register_fsa_input_adv(
    enum crmd_fsa_cause cause, enum crmd_fsa_input input,
    void *data, long long with_actions,
    gboolean prepend, const char *raised_from)
{
    unsigned  old_len = g_list_length(fsa_message_queue);
    fsa_data_t *fsa_data = NULL;

    last_data_id++;
    CRM_CHECK(raised_from != NULL, raised_from = "<unknown>");

    crm_debug("%s %s FSA input %d (%s) (cause=%s) %s data",
              raised_from, prepend?"prepended":"appended",last_data_id, fsa_input2string(input),
              fsa_cause2string(cause), data?"with":"without");

    if(input == I_WAIT_FOR_EVENT) {
        do_fsa_stall = TRUE;
        crm_debug("Stalling the FSA pending further input: cause=%s",
                  fsa_cause2string(cause));
        if(old_len > 0) {
            crm_warn("%s stalled the FSA with pending inputs",
                     raised_from);
            fsa_dump_queue(LOG_DEBUG);
        }
        if(data == NULL) {
            set_bit_inplace(fsa_actions, with_actions);
            with_actions = A_NOTHING;
            return 0;
        }
        crm_err("%s stalled the FSA with data - this may be broken",
                raised_from);
    }

    if(old_len == 0) {
        last_was_vote = FALSE;
    }

    if(input == I_NULL && with_actions == A_NOTHING /* && data == NULL */) {
        /* no point doing anything */
        crm_err("Cannot add entry to queue: no input and no action");
        return 0;

    } else if(data == NULL) {
        last_was_vote = FALSE;

#if 0
    } else if(last_was_vote && cause == C_HA_MESSAGE && input == I_ROUTER) {
        const char *op = cl_get_string(
                             ((ha_msg_input_t*)data)->msg, F_CRM_TASK);
        if(safe_str_eq(op, CRM_OP_VOTE)) {
            /* It is always safe to treat N successive votes as
             *    a single one
             *
             * If all the discarded votes are more "loosing" than
             *    the first then the result is accurate
             *    (win or loose).
             *
             * If any of the discarded votes are less "loosing"
             *    than the first then we will cast our vote and the
             *    eventual winner will vote us down again (which
             *    even in the case that N=2, is no worse than if we
             *    had not disarded the vote).
             */
            crm_debug_2("Vote compression: %d", old_len);
            return 0;
        }
#endif
    } else if (cause == C_HA_MESSAGE && input == I_ROUTER) {
        const char *op = cl_get_string(
                             ((ha_msg_input_t*)data)->msg, F_CRM_TASK);
        if(safe_str_eq(op, CRM_OP_VOTE)) {
            last_was_vote = TRUE;
            crm_debug_3("Added vote: %d", old_len);
        }

    } else {
        last_was_vote = FALSE;
    }

    crm_malloc0(fsa_data, sizeof(fsa_data_t));
    fsa_data->id        = last_data_id;
    fsa_data->fsa_input = input;
    fsa_data->fsa_cause = cause;
    fsa_data->origin    = raised_from;
    fsa_data->data      = NULL;
    fsa_data->data_type = fsa_dt_none;
    fsa_data->actions   = with_actions;

    if(with_actions != A_NOTHING) {
        crm_debug_3("Adding actions %.16llx to input", with_actions);
    }

    if(data != NULL) {
        switch(cause) {
        case C_FSA_INTERNAL:
        case C_CRMD_STATUS_CALLBACK:
        case C_IPC_MESSAGE:
        case C_HA_MESSAGE:
            crm_debug_3("Copying %s data from %s as a HA msg",
                        fsa_cause2string(cause),
                        raised_from);
            fsa_data->data = copy_ha_msg_input(data);
            fsa_data->data_type = fsa_dt_ha_msg;
            break;

        case C_LRM_OP_CALLBACK:
            crm_debug_3("Copying %s data from %s as lrm_op_t",
                        fsa_cause2string(cause),
                        raised_from);
            fsa_data->data = copy_lrm_op((lrm_op_t*)data);
            fsa_data->data_type = fsa_dt_lrm;
            break;

        case C_CCM_CALLBACK:
            crm_debug_3("Copying %s data from %s as CCM data",
                        fsa_cause2string(cause),
                        raised_from);
            fsa_data->data = copy_ccm_data(data);
            fsa_data->data_type = fsa_dt_ccm;
            break;

        case C_SUBSYSTEM_CONNECT:
        case C_LRM_MONITOR_CALLBACK:
        case C_TIMER_POPPED:
        case C_SHUTDOWN:
        case C_HEARTBEAT_FAILED:
        case C_HA_DISCONNECT:
        case C_ILLEGAL:
        case C_UNKNOWN:
        case C_STARTUP:
            crm_err("Copying %s data (from %s)"
                    " not yet implemented",
                    fsa_cause2string(cause), raised_from);
            exit(1);
            break;
        }
        crm_debug_4("%s data copied",
                    fsa_cause2string(fsa_data->fsa_cause));
    }

    /* make sure to free it properly later */
    if(prepend) {
        crm_debug_2("Prepending input");
        fsa_message_queue = g_list_prepend(fsa_message_queue, fsa_data);
    } else {
        fsa_message_queue = g_list_append(fsa_message_queue, fsa_data);
    }

    crm_debug_2("Queue len: %d", g_list_length(fsa_message_queue));

    fsa_dump_queue(LOG_DEBUG_2);

    if(old_len == g_list_length(fsa_message_queue)) {
        crm_err("Couldnt add message to the queue");
    }

    if(fsa_source) {
        crm_debug_3("Triggering FSA: %s", __FUNCTION__);
        G_main_set_trigger(fsa_source);
    }
    return last_data_id;
}
/*
	DCノード開始処理
*/
void
do_dc_takeover(long long action,
	       enum crmd_fsa_cause cause,
	       enum crmd_fsa_state cur_state,
	       enum crmd_fsa_input current_input,
	       fsa_data_t *msg_data)
{
	int rc = cib_ok;
	xmlNode *cib = NULL;
	static const char *cluster_type = NULL;
	
	if(cluster_type == NULL) {
	    cluster_type = getenv("HA_cluster_type");
	}
	if(cluster_type == NULL) {
	    cluster_type = "Heartbeat";
	}
	
	crm_info("Taking over DC status for this partition");
	/* -------- ★★★★★★★★フラグ的な意味あいでの、DCノードはここでセット --------- */
	set_bit_inplace(fsa_input_register, R_THE_DC);

#if SUPPORT_AIS
	if(is_openais_cluster()) {
	    send_ais_text(crm_class_quorum, NULL, TRUE, NULL, crm_msg_ais);
	}
#endif
	
	if(voted != NULL) {
		/* votedハッシュテーブルを破棄する */
		crm_debug_2("Destroying voted hash");
		g_hash_table_destroy(voted);
		voted = NULL;
	}
	
	/* R_JOIN_OK, R_INVOKE_PEフラグセット */
	set_bit_inplace(fsa_input_register, R_JOIN_OK);
	set_bit_inplace(fsa_input_register, R_INVOKE_PE);
	
	/* CIBのset_master処理を実行する */
	fsa_cib_conn->cmds->set_master(fsa_cib_conn, cib_scope_local);
	
	/* 初期CIBのXMLを生成する */
	cib = create_xml_node(NULL, XML_TAG_CIB);
	/* 生成したXMLにCRM_FEATURE_SETをセットする */
	crm_xml_add(cib, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET);
	/* CIBを生成した初期XMLで更新する */
	fsa_cib_update(XML_TAG_CIB, cib, cib_quorum_override, rc);
	/* 更新コールバックをセットする */
	add_cib_op_callback(fsa_cib_conn, rc, FALSE, NULL, feature_update_callback);

	/* CIBの"dc-version","cluster-infrastructure"属性を更新する */
	update_attr(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
		    NULL, NULL, NULL, "dc-version", VERSION"-"BUILD_VERSION, FALSE);

	update_attr(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
		    NULL, NULL, NULL, "cluster-infrastructure", cluster_type, FALSE);
	
	/* config_readトリガーを叩く */
	mainloop_set_trigger(config_read);
	
	free_xml(cib);
}
Exemplo n.º 16
0
static gboolean
crmd_ais_dispatch(AIS_Message * wrapper, char *data, int sender)
{
    int seq = 0;
    xmlNode *xml = NULL;
    const char *seq_s = NULL;

    xml = string2xml(data);
    if (xml == NULL) {
        crm_err("Could not parse message content (%d): %.100s", wrapper->header.id, data);
        return TRUE;
    }

    switch (wrapper->header.id) {
        case crm_class_members:
            seq_s = crm_element_value(xml, "id");
            seq = crm_int_helper(seq_s, NULL);
            set_bit_inplace(fsa_input_register, R_PEER_DATA);
            post_cache_update(seq);

            /* fall through */
        case crm_class_quorum:
            crm_update_quorum(crm_have_quorum, FALSE);
            if (AM_I_DC) {
                const char *votes = crm_element_value(xml, "expected");

                if (votes == NULL || check_number(votes) == FALSE) {
                    crm_log_xml_err(xml, "Invalid quorum/membership update");

                } else {
                    int rc = update_attr(fsa_cib_conn,
                                         cib_quorum_override | cib_scope_local | cib_inhibit_notify,
                                         XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
                                         XML_ATTR_EXPECTED_VOTES, votes, FALSE);

                    crm_info("Setting expected votes to %s", votes);
                    if (cib_ok > rc) {
                        crm_err("Quorum update failed: %s", cib_error2string(rc));
                    }
                }
            }
            break;

        case crm_class_cluster:
            crm_xml_add(xml, F_ORIG, wrapper->sender.uname);
            crm_xml_add_int(xml, F_SEQ, wrapper->id);
            crmd_ha_msg_filter(xml);
            break;

        case crm_class_rmpeer:
            /* Ignore */
            break;

        case crm_class_notify:
        case crm_class_nodeid:
            crm_err("Unexpected message class (%d): %.100s", wrapper->header.id, data);
            break;

        default:
            crm_err("Invalid message class (%d): %.100s", wrapper->header.id, data);
    }

    free_xml(xml);
    return TRUE;
}
Exemplo n.º 17
0
void
group_create_actions(resource_t * rsc, pe_working_set_t * data_set)
{
    action_t *op = NULL;
    const char *value = NULL;
    GListPtr gIter = rsc->children;

    crm_debug_2("Creating actions for %s", rsc->id);

    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child_rsc = (resource_t *) gIter->data;

        child_rsc->cmds->create_actions(child_rsc, data_set);
        group_update_pseudo_status(rsc, child_rsc);
    }

    op = start_action(rsc, NULL, TRUE /* !group_data->child_starting */ );
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    op = custom_action(rsc, started_key(rsc),
                       RSC_STARTED, NULL, TRUE /* !group_data->child_starting */ , TRUE, data_set);
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    op = stop_action(rsc, NULL, TRUE /* !group_data->child_stopping */ );
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    op = custom_action(rsc, stopped_key(rsc),
                       RSC_STOPPED, NULL, TRUE /* !group_data->child_stopping */ , TRUE, data_set);
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    value = g_hash_table_lookup(rsc->meta, "stateful");
    if (crm_is_true(value)) {
        op = custom_action(rsc, demote_key(rsc), RSC_DEMOTE, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);
        op = custom_action(rsc, demoted_key(rsc), RSC_DEMOTED, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);

        op = custom_action(rsc, promote_key(rsc), RSC_PROMOTE, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);
        op = custom_action(rsc, promoted_key(rsc), RSC_PROMOTED, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);
    }
}
Exemplo n.º 18
0
int
register_fsa_input_adv(enum crmd_fsa_cause cause, enum crmd_fsa_input input,
                       void *data, long long with_actions,
                       gboolean prepend, const char *raised_from)
{
    unsigned old_len = g_list_length(fsa_message_queue);
    fsa_data_t *fsa_data = NULL;

    last_data_id++;
    CRM_CHECK(raised_from != NULL, raised_from = "<unknown>");

    crm_debug_2("%s %s FSA input %d (%s) (cause=%s) %s data",
                raised_from, prepend ? "prepended" : "appended", last_data_id,
                fsa_input2string(input), fsa_cause2string(cause), data ? "with" : "without");

    if (input == I_WAIT_FOR_EVENT) {
        do_fsa_stall = TRUE;
        crm_debug("Stalling the FSA pending further input: cause=%s", fsa_cause2string(cause));
        if (old_len > 0) {
            crm_warn("%s stalled the FSA with pending inputs", raised_from);
            fsa_dump_queue(LOG_DEBUG);
        }
        if (data == NULL) {
            set_bit_inplace(fsa_actions, with_actions);
            with_actions = A_NOTHING;
            return 0;
        }
        crm_err("%s stalled the FSA with data - this may be broken", raised_from);
    }

    if (input == I_NULL && with_actions == A_NOTHING /* && data == NULL */ ) {
        /* no point doing anything */
        crm_err("Cannot add entry to queue: no input and no action");
        return 0;
    }

    crm_malloc0(fsa_data, sizeof(fsa_data_t));
    fsa_data->id = last_data_id;
    fsa_data->fsa_input = input;
    fsa_data->fsa_cause = cause;
    fsa_data->origin = raised_from;
    fsa_data->data = NULL;
    fsa_data->data_type = fsa_dt_none;
    fsa_data->actions = with_actions;

    if (with_actions != A_NOTHING) {
        crm_debug_3("Adding actions %.16llx to input", with_actions);
    }

    if (data != NULL) {
        switch (cause) {
            case C_FSA_INTERNAL:
            case C_CRMD_STATUS_CALLBACK:
            case C_IPC_MESSAGE:
            case C_HA_MESSAGE:
                crm_debug_3("Copying %s data from %s as a HA msg",
                            fsa_cause2string(cause), raised_from);
                CRM_CHECK(((ha_msg_input_t *) data)->msg != NULL,
                          crm_err("Bogus data from %s", raised_from));
                fsa_data->data = copy_ha_msg_input(data);
                fsa_data->data_type = fsa_dt_ha_msg;
                break;

            case C_LRM_OP_CALLBACK:
                crm_debug_3("Copying %s data from %s as lrm_op_t",
                            fsa_cause2string(cause), raised_from);
                fsa_data->data = copy_lrm_op((lrm_op_t *) data);
                fsa_data->data_type = fsa_dt_lrm;
                break;

            case C_CCM_CALLBACK:
            case C_SUBSYSTEM_CONNECT:
            case C_LRM_MONITOR_CALLBACK:
            case C_TIMER_POPPED:
            case C_SHUTDOWN:
            case C_HEARTBEAT_FAILED:
            case C_HA_DISCONNECT:
            case C_ILLEGAL:
            case C_UNKNOWN:
            case C_STARTUP:
                crm_err("Copying %s data (from %s)"
                        " not yet implemented", fsa_cause2string(cause), raised_from);
                exit(1);
                break;
        }
        crm_debug_4("%s data copied", fsa_cause2string(fsa_data->fsa_cause));
    }

    /* make sure to free it properly later */
    if (prepend) {
        crm_debug_2("Prepending input");
        fsa_message_queue = g_list_prepend(fsa_message_queue, fsa_data);
    } else {
        fsa_message_queue = g_list_append(fsa_message_queue, fsa_data);
    }

    crm_debug_2("Queue len: %d", g_list_length(fsa_message_queue));

    fsa_dump_queue(LOG_DEBUG_2);

    if (old_len == g_list_length(fsa_message_queue)) {
        crm_err("Couldnt add message to the queue");
    }

    if (fsa_source) {
        crm_debug_3("Triggering FSA: %s", __FUNCTION__);
        mainloop_set_trigger(fsa_source);
    }
    return last_data_id;
}
Exemplo n.º 19
0
enum crmd_fsa_input
handle_request(xmlNode * stored_msg)
{
    xmlNode *msg = NULL;
    const char *op = crm_element_value(stored_msg, F_CRM_TASK);

    /* Optimize this for the DC - it has the most to do */

    if (op == NULL) {
        crm_log_xml(LOG_ERR, "Bad message", stored_msg);
        return I_NULL;
    }

    /*========== DC-Only Actions ==========*/
    if (AM_I_DC) {
        if (strcmp(op, CRM_OP_JOIN_ANNOUNCE) == 0) {
            return I_NODE_JOIN;

        } else if (strcmp(op, CRM_OP_JOIN_REQUEST) == 0) {
            return I_JOIN_REQUEST;

        } else if (strcmp(op, CRM_OP_JOIN_CONFIRM) == 0) {
            return I_JOIN_RESULT;

        } else if (strcmp(op, CRM_OP_SHUTDOWN) == 0) {
            const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM);
            gboolean dc_match = safe_str_eq(host_from, fsa_our_dc);

            if (is_set(fsa_input_register, R_SHUTDOWN)) {
                crm_info("Shutting ourselves down (DC)");
                return I_STOP;

            } else if (dc_match) {
                crm_err("We didnt ask to be shut down, yet our"
                        " TE is telling us too." " Better get out now!");
                return I_TERMINATE;

            } else if (fsa_state != S_STOPPING) {
                crm_err("Another node is asking us to shutdown" " but we think we're ok.");
                return I_ELECTION;
            }

        } else if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) {
            /* a slave wants to shut down */
            /* create cib fragment and add to message */
            return handle_shutdown_request(stored_msg);
        }
    }

    /*========== common actions ==========*/
    if (strcmp(op, CRM_OP_NOVOTE) == 0) {
        ha_msg_input_t fsa_input;

        fsa_input.msg = stored_msg;
        register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input,
                               A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__);

    } else if (strcmp(op, CRM_OP_CLEAR_FAILCOUNT) == 0) {
        return handle_failcount_op(stored_msg);

    } else if (strcmp(op, CRM_OP_VOTE) == 0) {
        /* count the vote and decide what to do after that */
        ha_msg_input_t fsa_input;

        fsa_input.msg = stored_msg;
        register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input,
                               A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__);

        /* Sometimes we _must_ go into S_ELECTION */
        if (fsa_state == S_HALT) {
            crm_debug("Forcing an election from S_HALT");
            return I_ELECTION;
#if 0
        } else if (AM_I_DC) {
            /* This is the old way of doing things but what is gained? */
            return I_ELECTION;
#endif
        }

    } else if (strcmp(op, CRM_OP_JOIN_OFFER) == 0) {
        crm_debug("Raising I_JOIN_OFFER: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID));
        return I_JOIN_OFFER;

    } else if (strcmp(op, CRM_OP_JOIN_ACKNAK) == 0) {
        crm_debug("Raising I_JOIN_RESULT: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID));
        return I_JOIN_RESULT;

    } else if (strcmp(op, CRM_OP_LRM_DELETE) == 0
               || strcmp(op, CRM_OP_LRM_FAIL) == 0
               || strcmp(op, CRM_OP_LRM_REFRESH) == 0 || strcmp(op, CRM_OP_REPROBE) == 0) {

        crm_xml_add(stored_msg, F_CRM_SYS_TO, CRM_SYSTEM_LRMD);
        return I_ROUTER;

    } else if (strcmp(op, CRM_OP_NOOP) == 0) {
        return I_NULL;

    } else if (strcmp(op, CRM_OP_LOCAL_SHUTDOWN) == 0) {

        crm_shutdown(SIGTERM);
        /*return I_SHUTDOWN; */
        return I_NULL;

        /*========== (NOT_DC)-Only Actions ==========*/
    } else if (AM_I_DC == FALSE && strcmp(op, CRM_OP_SHUTDOWN) == 0) {

        const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM);
        gboolean dc_match = safe_str_eq(host_from, fsa_our_dc);

        if (dc_match || fsa_our_dc == NULL) {
            if (is_set(fsa_input_register, R_SHUTDOWN) == FALSE) {
                crm_err("We didn't ask to be shut down, yet our" " DC is telling us too.");
                set_bit_inplace(fsa_input_register, R_STAYDOWN);
                return I_STOP;
            }
            crm_info("Shutting down");
            return I_STOP;

        } else {
            crm_warn("Discarding %s op from %s", op, host_from);
        }

    } else if (strcmp(op, CRM_OP_PING) == 0) {
        /* eventually do some stuff to figure out
         * if we /are/ ok
         */
        const char *sys_to = crm_element_value(stored_msg, F_CRM_SYS_TO);
        xmlNode *ping = createPingAnswerFragment(sys_to, "ok");

        crm_xml_add(ping, "crmd_state", fsa_state2string(fsa_state));

        crm_info("Current ping state: %s", fsa_state2string(fsa_state));

        msg = create_reply(stored_msg, ping);
        relay_message(msg, TRUE);

        free_xml(ping);
        free_xml(msg);

        /* probably better to do this via signals on the
         * local node
         */
    } else if (strcmp(op, CRM_OP_DEBUG_UP) == 0) {
        crm_bump_log_level();
        crm_info("Debug set to %d", get_crm_log_level());

    } else if (strcmp(op, CRM_OP_DEBUG_DOWN) == 0) {
        alter_debug(DEBUG_DEC);
        crm_info("Debug set to %d", get_crm_log_level());

    } else {
        crm_err("Unexpected request (%s) sent to %s", op, AM_I_DC ? "the DC" : "non-DC node");
        crm_log_xml(LOG_ERR, "Unexpected", stored_msg);
    }

    return I_NULL;
}