示例#1
0
void
notify_crmd(crm_graph_t * graph)
{
    const char *type = "unknown";
    enum crmd_fsa_input event = I_NULL;

    crm_debug("Processing transition completion in state %s", fsa_state2string(fsa_state));

    CRM_CHECK(graph->complete, graph->complete = TRUE);

    switch (graph->completion_action) {
        case tg_stop:
            type = "stop";
            /* fall through */
        case tg_done:
            type = "done";
            if (fsa_state == S_TRANSITION_ENGINE) {
                event = I_TE_SUCCESS;
            }
            break;

        case tg_restart:
            type = "restart";
            if (fsa_state == S_TRANSITION_ENGINE) {
                if (transition_timer->period_ms > 0) {
                    crm_timer_stop(transition_timer);
                    crm_timer_start(transition_timer);
                } else if (too_many_st_failures() == FALSE) {
                    event = I_PE_CALC;
                }

            } else if (fsa_state == S_POLICY_ENGINE) {
                register_fsa_action(A_PE_INVOKE);
            }
            break;

        case tg_shutdown:
            type = "shutdown";
            if (is_set(fsa_input_register, R_SHUTDOWN)) {
                event = I_STOP;

            } else {
                crm_err("We didn't ask to be shut down, yet our" " PE is telling us too.");
                event = I_TERMINATE;
            }
    }

    crm_debug("Transition %d status: %s - %s", graph->id, type, crm_str(graph->abort_reason));

    graph->abort_reason = NULL;
    graph->completion_action = tg_done;
    clear_bit(fsa_input_register, R_IN_TRANSITION);

    if (event != I_NULL) {
        register_fsa_input(C_FSA_INTERNAL, event, NULL);

    } else if (fsa_source) {
        mainloop_set_trigger(fsa_source);
    }
}
示例#2
0
/*	A_DC_TIMER_STOP, A_DC_TIMER_START,
 *	A_FINALIZE_TIMER_STOP, A_FINALIZE_TIMER_START
 *	A_INTEGRATE_TIMER_STOP, A_INTEGRATE_TIMER_START
 */
void
do_timer_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)
{
    gboolean timer_op_ok = TRUE;

    if (action & A_DC_TIMER_STOP) {
        timer_op_ok = crm_timer_stop(election_trigger);

    } else if (action & A_FINALIZE_TIMER_STOP) {
        timer_op_ok = crm_timer_stop(finalization_timer);

    } else if (action & A_INTEGRATE_TIMER_STOP) {
        timer_op_ok = crm_timer_stop(integration_timer);

/* 	} else if(action & A_ELECTION_TIMEOUT_STOP) { */
/* 		timer_op_ok = crm_timer_stop(election_timeout); */
    }

    /* dont start a timer that wasnt already running */
    if (action & A_DC_TIMER_START && timer_op_ok) {
        crm_timer_start(election_trigger);
        if (AM_I_DC) {
            /* there can be only one */
            register_fsa_input(cause, I_ELECTION, NULL);
        }

    } else if (action & A_FINALIZE_TIMER_START) {
        crm_timer_start(finalization_timer);

    } else if (action & A_INTEGRATE_TIMER_START) {
        crm_timer_start(integration_timer);

/* 	} else if(action & A_ELECTION_TIMEOUT_START) { */
/* 		crm_timer_start(election_timeout); */
    }
}
示例#3
0
void
abort_transition_graph(int abort_priority, enum transition_action abort_action,
                       const char *abort_text, xmlNode * reason, const char *fn, int line)
{
    int add[] = { 0, 0, 0 };
    int del[] = { 0, 0, 0 };
    int level = LOG_INFO;
    xmlNode *diff = NULL;
    xmlNode *change = NULL;

    CRM_CHECK(transition_graph != NULL, return);

    switch (fsa_state) {
        case S_STARTING:
        case S_PENDING:
        case S_NOT_DC:
        case S_HALT:
        case S_ILLEGAL:
        case S_STOPPING:
        case S_TERMINATE:
            crm_info("Abort %s suppressed: state=%s (complete=%d)",
                     abort_text, fsa_state2string(fsa_state), transition_graph->complete);
            return;
        default:
            break;
    }

    /* Make sure any queued calculations are discarded ASAP */
    free(fsa_pe_ref);
    fsa_pe_ref = NULL;

    if (transition_graph->complete == FALSE) {
        if(update_abort_priority(transition_graph, abort_priority, abort_action, abort_text)) {
            level = LOG_NOTICE;
        }
    }

    if(reason) {
        xmlNode *search = NULL;

        for(search = reason; search; search = search->parent) {
            if (safe_str_eq(XML_TAG_DIFF, TYPE(search))) {
                diff = search;
                break;
            }
        }

        if(diff) {
            xml_patch_versions(diff, add, del);
            for(search = reason; search; search = search->parent) {
                if (safe_str_eq(XML_DIFF_CHANGE, TYPE(search))) {
                    change = search;
                    break;
                }
            }
        }
    }

    if(reason == NULL) {
        do_crm_log(level, "Transition aborted: %s (source=%s:%d, %d)",
                   abort_text, fn, line, transition_graph->complete);

    } else if(change == NULL) {
        char *local_path = xml_get_path(reason);

        do_crm_log(level, "Transition aborted by %s.%s: %s (cib=%d.%d.%d, source=%s:%d, path=%s, %d)",
                   TYPE(reason), ID(reason), abort_text, add[0], add[1], add[2], fn, line, local_path, transition_graph->complete);
        free(local_path);

    } else {
        const char *kind = NULL;
        const char *op = crm_element_value(change, XML_DIFF_OP);
        const char *path = crm_element_value(change, XML_DIFF_PATH);

        if(change == reason) {
            if(strcmp(op, "create") == 0) {
                reason = reason->children;

            } else if(strcmp(op, "modify") == 0) {
                reason = first_named_child(reason, XML_DIFF_RESULT);
                if(reason) {
                    reason = reason->children;
                }
            }
        }

        kind = TYPE(reason);
        if(strcmp(op, "delete") == 0) {
            const char *shortpath = strrchr(path, '/');

            do_crm_log(level, "Transition aborted by deletion of %s: %s (cib=%d.%d.%d, source=%s:%d, path=%s, %d)",
                       shortpath?shortpath+1:path, abort_text, add[0], add[1], add[2], fn, line, path, transition_graph->complete);

        } else if (safe_str_eq(XML_CIB_TAG_NVPAIR, kind)) { 
            do_crm_log(level, "Transition aborted by %s, %s=%s: %s (%s cib=%d.%d.%d, source=%s:%d, path=%s, %d)",
                       crm_element_value(reason, XML_ATTR_ID),
                       crm_element_value(reason, XML_NVPAIR_ATTR_NAME),
                       crm_element_value(reason, XML_NVPAIR_ATTR_VALUE),
                       abort_text, op, add[0], add[1], add[2], fn, line, path, transition_graph->complete);

        } else if (safe_str_eq(XML_LRM_TAG_RSC_OP, kind)) {
            const char *magic = crm_element_value(reason, XML_ATTR_TRANSITION_MAGIC);

            do_crm_log(level, "Transition aborted by %s '%s' on %s: %s (magic=%s, cib=%d.%d.%d, source=%s:%d, %d)",
                       crm_element_value(reason, XML_LRM_ATTR_TASK_KEY), op,
                       crm_element_value(reason, XML_LRM_ATTR_TARGET), abort_text,
                       magic, add[0], add[1], add[2], fn, line, transition_graph->complete);

        } else if (safe_str_eq(XML_CIB_TAG_STATE, kind)
                   || safe_str_eq(XML_CIB_TAG_NODE, kind)) {
            const char *uname = crm_peer_uname(ID(reason));

            do_crm_log(level, "Transition aborted by %s '%s' on %s: %s (cib=%d.%d.%d, source=%s:%d, %d)",
                       kind, op, uname ? uname : ID(reason), abort_text,
                       add[0], add[1], add[2], fn, line, transition_graph->complete);

        } else {
            do_crm_log(level, "Transition aborted by %s.%s '%s': %s (cib=%d.%d.%d, source=%s:%d, path=%s, %d)",
                       TYPE(reason), ID(reason), op?op:"change", abort_text, add[0], add[1], add[2], fn, line, path, transition_graph->complete);
        }
    }

    if (transition_graph->complete) {
        if (transition_timer->period_ms > 0) {
            crm_timer_stop(transition_timer);
            crm_timer_start(transition_timer);
        } else {
            register_fsa_input(C_FSA_INTERNAL, I_PE_CALC, NULL);
        }
        return;
    }

    mainloop_set_trigger(transition_trigger);
}
示例#4
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;
		}
	}
}
void
notify_crmd(crm_graph_t *graph)
{
	int log_level = LOG_DEBUG;
	const char *type = "unknown";
	enum crmd_fsa_input event = I_NULL;
	
	crm_debug("Processing transition completion in state %s", fsa_state2string(fsa_state));
	
	CRM_CHECK(graph->complete, graph->complete = TRUE);

	switch(graph->completion_action) {
		case tg_stop:
		    type = "stop";
		    /* fall through */
		case tg_done:
		    type = "done";
		    log_level = LOG_INFO;
		    if(fsa_state == S_TRANSITION_ENGINE) {
			event = I_TE_SUCCESS;
		    }
		    break;
		    
		case tg_restart:
		    type = "restart";
		    if(fsa_state == S_TRANSITION_ENGINE) {
			if(transition_timer->period_ms > 0) {
			    crm_timer_start(transition_timer);
			} else {
			    event = I_PE_CALC;
			}

		    } else if(fsa_state == S_POLICY_ENGINE) {
				/* fsa_actionにA_PE_INVOKEアクションを追加して、fsa_sourceトリガーを叩いてcrmdに通知する */
				register_fsa_action(A_PE_INVOKE);
		    }
		    break;

		case tg_shutdown:
		    type = "shutdown";
		    if(is_set(fsa_input_register, R_SHUTDOWN)) {
			event = I_STOP;			
			
		    } else {
			event = I_TERMINATE;
		    }
	}

	te_log_action(log_level, "Transition %d status: %s - %s",
		      graph->id, type, crm_str(graph->abort_reason));

	graph->abort_reason = NULL;
	graph->completion_action = tg_done;
	clear_bit_inplace(fsa_input_register, R_IN_TRANSITION);

	if(event != I_NULL) {
	    register_fsa_input(C_FSA_INTERNAL, event, NULL);

	} else if(fsa_source) {
	    mainloop_set_trigger(fsa_source);
	}
}
示例#6
0
/*	A_ELECTION_VOTE	*/
void
do_election_vote(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 timeval age;
    xmlNode *vote = NULL;
    gboolean not_voting = FALSE;

    /* don't vote if we're in one of these states or wanting to shut down */
    switch (cur_state) {
        case S_STARTING:
        case S_RECOVERY:
        case S_STOPPING:
        case S_TERMINATE:
            crm_warn("Not voting in election, we're in state %s", fsa_state2string(cur_state));
            not_voting = TRUE;
            break;
        default:
            break;
    }

    if (not_voting == FALSE) {
        if (is_set(fsa_input_register, R_STARTING)) {
            not_voting = TRUE;
        }
    }

    if (not_voting) {
        if (AM_I_DC) {
            register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);

        } else {
            register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
        }
        return;
    }

    vote = create_request(CRM_OP_VOTE, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL);

    current_election_id++;
    crm_xml_add(vote, F_CRM_ELECTION_OWNER, fsa_our_uuid);
    crm_xml_add_int(vote, F_CRM_ELECTION_ID, current_election_id);

    crm_uptime(&age);
    crm_xml_add_int(vote, F_CRM_ELECTION_AGE_S, age.tv_sec);
    crm_xml_add_int(vote, F_CRM_ELECTION_AGE_US, age.tv_usec);

    send_cluster_message(NULL, crm_msg_crmd, vote, TRUE);
    free_xml(vote);

    crm_debug("Started election %d", current_election_id);
    if (voted) {
        g_hash_table_destroy(voted);
    }
    voted = NULL;

    if (cur_state == S_ELECTION || cur_state == S_RELEASE_DC) {
        crm_timer_start(election_timeout);

    } else if (cur_state != S_INTEGRATION) {
        crm_err("Broken? Voting in state %s", fsa_state2string(cur_state));
    }

    return;
}
示例#7
0
void
abort_transition_graph(int abort_priority, enum transition_action abort_action,
                       const char *abort_text, xmlNode * reason, const char *fn, int line)
{
    int log_level = LOG_INFO;
    const char *magic = NULL;

    CRM_CHECK(transition_graph != NULL, return);

    if (reason) {
        int diff_add_updates = 0;
        int diff_add_epoch = 0;
        int diff_add_admin_epoch = 0;

        int diff_del_updates = 0;
        int diff_del_epoch = 0;
        int diff_del_admin_epoch = 0;
        xmlNode *diff = get_xpath_object("//" F_CIB_UPDATE_RESULT "//diff", reason, LOG_DEBUG_2);

        magic = crm_element_value(reason, XML_ATTR_TRANSITION_MAGIC);

        if (diff) {
            cib_diff_version_details(diff,
                                     &diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates,
                                     &diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates);
            if (crm_str_eq(TYPE(reason), XML_CIB_TAG_NVPAIR, TRUE)) {
                do_crm_log(log_level,
                           "%s:%d - Triggered transition abort (complete=%d, tag=%s, id=%s, name=%s, value=%s, magic=%s, cib=%d.%d.%d) : %s",
                           fn, line, transition_graph->complete, TYPE(reason), ID(reason),
                           NAME(reason), VALUE(reason), magic ? magic : "NA", diff_add_admin_epoch,
                           diff_add_epoch, diff_add_updates, abort_text);
            } else {
                do_crm_log(log_level,
                           "%s:%d - Triggered transition abort (complete=%d, tag=%s, id=%s, magic=%s, cib=%d.%d.%d) : %s",
                           fn, line, transition_graph->complete, TYPE(reason), ID(reason),
                           magic ? magic : "NA", diff_add_admin_epoch, diff_add_epoch,
                           diff_add_updates, abort_text);
            }

        } else {
            do_crm_log(log_level,
                       "%s:%d - Triggered transition abort (complete=%d, tag=%s, id=%s, magic=%s) : %s",
                       fn, line, transition_graph->complete, TYPE(reason), ID(reason),
                       magic ? magic : "NA", abort_text);
        }

    } else {
        do_crm_log(log_level,
                   "%s:%d - Triggered transition abort (complete=%d) : %s",
                   fn, line, transition_graph->complete, abort_text);
    }

    switch (fsa_state) {
    case S_STARTING:
    case S_PENDING:
    case S_NOT_DC:
    case S_HALT:
    case S_ILLEGAL:
    case S_STOPPING:
    case S_TERMINATE:
        do_crm_log(log_level,
                   "Abort suppressed: state=%s (complete=%d)",
                   fsa_state2string(fsa_state), transition_graph->complete);
        return;
    default:
        break;
    }

    if (magic == NULL && reason != NULL) {
        crm_log_xml(log_level + 1, "Cause", reason);
    }

    /* Make sure any queued calculations are discarded ASAP */
    crm_free(fsa_pe_ref);
    fsa_pe_ref = NULL;

    if (transition_graph->complete) {
        if (transition_timer->period_ms > 0) {
            crm_timer_start(transition_timer);
        } else {
            register_fsa_input(C_FSA_INTERNAL, I_PE_CALC, NULL);
        }
        return;
    }

    update_abort_priority(transition_graph, abort_priority, abort_action, abort_text);

    mainloop_set_trigger(transition_trigger);
}