Exemplo n.º 1
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.º 2
0
void
initialize_join(gboolean before)
{
    /* clear out/reset a bunch of stuff */
    crm_debug("join-%d: Initializing join data (flag=%s)",
              current_join_id, before ? "true" : "false");

    g_hash_table_destroy(welcomed_nodes);
    g_hash_table_destroy(integrated_nodes);
    g_hash_table_destroy(finalized_nodes);
    g_hash_table_destroy(confirmed_nodes);

    if (before) {
        if (max_generation_from != NULL) {
            free(max_generation_from);
            max_generation_from = NULL;
        }
        if (max_generation_xml != NULL) {
            free_xml(max_generation_xml);
            max_generation_xml = NULL;
        }
        clear_bit_inplace(fsa_input_register, R_HAVE_CIB);
        clear_bit_inplace(fsa_input_register, R_CIB_ASKED);
    }

    welcomed_nodes = g_hash_table_new_full(crm_str_hash, g_str_equal,
                                           g_hash_destroy_str, g_hash_destroy_str);
    integrated_nodes = g_hash_table_new_full(crm_str_hash, g_str_equal,
                                             g_hash_destroy_str, g_hash_destroy_str);
    finalized_nodes = g_hash_table_new_full(crm_str_hash, g_str_equal,
                                            g_hash_destroy_str, g_hash_destroy_str);
    confirmed_nodes = g_hash_table_new_full(crm_str_hash, g_str_equal,
                                            g_hash_destroy_str, g_hash_destroy_str);
}
/*
	DCノード状態の解放処理
*/
void
do_dc_release(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)
{
	if(action & A_DC_RELEASE) {
		crm_debug("Releasing the role of DC");
		/* フラグのDCをクリア */
		clear_bit_inplace(fsa_input_register, R_THE_DC);
		
	} else if (action & A_DC_RELEASED) {
		crm_info("DC role released");
#if 0
		if( are there errors ) {
			/* we cant stay up if not healthy */
			/* or perhaps I_ERROR and go to S_RECOVER? */
			result = I_SHUTDOWN;
		}
#endif
		/* I_RELEASE_SUCCESSへ */
		register_fsa_input(C_FSA_INTERNAL, I_RELEASE_SUCCESS, NULL);
		
	} else {
		crm_err("Unknown action %s", fsa_action2string(action));
	}

	crm_debug_2("Am I still the DC? %s", AM_I_DC?XML_BOOLEAN_YES:XML_BOOLEAN_NO);

}
/*
	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.º 5
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_start(transition_timer);
                } else {
                    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;
            }
    }

    te_log_action(LOG_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_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);
    }
}
Exemplo n.º 6
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);
    }
}
Exemplo n.º 7
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);
    }
}
/*
	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
/*
 * 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);
 	const char *value = crm_element_value(
		data_set->input, XML_ATTR_HAVE_QUORUM);
	
	crm_debug_3("Beginning unpack");
	
	/* reset remaining global variables */
	
	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_resources(cib_resources, data_set);
 	unpack_status(cib_status, data_set);
	
	return TRUE;
}
Exemplo n.º 10
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.º 11
0
enum pe_action_flags
group_action_flags(action_t * action, node_t * node)
{
    GListPtr gIter = NULL;
    enum pe_action_flags flags = (pe_action_optional | pe_action_runnable | pe_action_pseudo);

    for (gIter = action->rsc->children; gIter != NULL; gIter = gIter->next) {
        resource_t *child = (resource_t *) gIter->data;
        enum action_tasks task = get_complex_task(child, action->task, TRUE);
        const char *task_s = task2text(task);
        action_t *child_action = find_first_action(child->actions, NULL, task_s, node);

        if (child_action) {
            enum pe_action_flags child_flags = child->cmds->action_flags(child_action, node);

            if (is_set(flags, pe_action_optional)
                && is_set(child_flags, pe_action_optional) == FALSE) {
                crm_trace("%s is manditory because of %s", action->uuid, child_action->uuid);
                clear_bit_inplace(flags, pe_action_optional);
                clear_bit_inplace(action->flags, pe_action_optional);
            }
            if (safe_str_neq(task_s, action->task)
                && is_set(flags, pe_action_runnable)
                && is_set(child_flags, pe_action_runnable) == FALSE) {
                crm_trace("%s is not runnable because of %s", action->uuid, child_action->uuid);
                clear_bit_inplace(flags, pe_action_runnable);
                clear_bit_inplace(action->flags, pe_action_runnable);
            }

        } else if (task != stop_rsc) {
            crm_trace("%s is not runnable because of %s (not found in %s)", action->uuid, task_s,
                      child->id);
            clear_bit_inplace(flags, pe_action_runnable);
        }
    }

    return flags;
}
Exemplo n.º 12
0
void
cleanup_calculations(pe_working_set_t * data_set)
{
    pe_dataset = NULL;
    if (data_set == NULL) {
        return;
    }

    clear_bit_inplace(data_set->flags, pe_flag_have_status);
    if (data_set->config_hash != NULL) {
        g_hash_table_destroy(data_set->config_hash);
    }

    if (data_set->tickets) {
        g_hash_table_destroy(data_set->tickets);
    }

    if (data_set->template_rsc_sets) {
        g_hash_table_destroy(data_set->template_rsc_sets);
    }

    crm_free(data_set->dc_uuid);

    crm_trace("deleting resources");
    pe_free_resources(data_set->resources);

    crm_trace("deleting actions");
    pe_free_actions(data_set->actions);

    if (data_set->domains) {
        g_hash_table_destroy(data_set->domains);
    }

    crm_trace("deleting nodes");
    pe_free_nodes(data_set->nodes);

    free_xml(data_set->graph);
    free_ha_date(data_set->now);
    free_xml(data_set->input);
    free_xml(data_set->failed);

    set_working_set_defaults(data_set);

    CRM_CHECK(data_set->ordering_constraints == NULL,;);
Exemplo n.º 13
0
gboolean
shutdown_constraints(node_t * node, action_t * shutdown_op, pe_working_set_t * data_set)
{
    /* add the stop to the before lists so it counts as a pre-req
     * for the shutdown
     */
    GListPtr lpc = NULL;

    for (lpc = data_set->actions; lpc != NULL; lpc = lpc->next) {
        action_t *action = (action_t *) lpc->data;

        if (action->rsc == NULL || action->node == NULL) {
            continue;
        } else if(action->node->details != node->details) {
            continue;
        } else if(is_set(data_set->flags, pe_flag_maintenance_mode)) {
            crm_trace("Skipping %s: maintainence mode", action->uuid);
            continue;
        } else if(safe_str_neq(action->task, RSC_STOP)) {
            continue;
        } else if(is_not_set(action->rsc->flags, pe_rsc_managed)
                  && is_not_set(action->rsc->flags, pe_rsc_block)) {
            /*
             * If another action depends on this one, we may still end up blocking
             */
            crm_trace("Skipping %s: unmanaged", action->uuid);
            continue;
        }

        crm_trace("Ordering %s before shutdown on %s", action->uuid, node->details->uname);
        clear_bit_inplace(action->flags, pe_action_optional);
        custom_action_order(action->rsc, NULL, action,
                            NULL, crm_strdup(CRM_OP_SHUTDOWN), shutdown_op,
                            pe_order_optional|pe_order_runnable_left, data_set);
    }

    return TRUE;
}
Exemplo n.º 14
0
gboolean
update_action(action_t * then)
{
    GListPtr lpc = NULL;
    enum pe_graph_flags changed = pe_graph_none;
    int last_flags = then->flags;

    crm_trace("Processing %s (%s %s %s)",
              then->uuid,
              is_set(then->flags, pe_action_optional) ? "optional" : "required",
              is_set(then->flags, pe_action_runnable) ? "runnable" : "unrunnable",
              is_set(then->flags,
                     pe_action_pseudo) ? "pseudo" : then->node ? then->node->details->uname : "");


    if (is_set(then->flags, pe_action_requires_any)) {
        clear_bit_inplace(then->flags, pe_action_runnable);
    }

    for (lpc = then->actions_before; lpc != NULL; lpc = lpc->next) {
        action_wrapper_t *other = (action_wrapper_t *) lpc->data;
        action_t *first = other->action;

        node_t *then_node = then->node;
        node_t *first_node = first->node;

        enum pe_action_flags then_flags = 0;
        enum pe_action_flags first_flags = 0;

        if (first->rsc && first->rsc->variant == pe_group && safe_str_eq(first->task, RSC_START)) {
            first_node = first->rsc->fns->location(first->rsc, NULL, FALSE);
            if (first_node) {
                crm_trace("First: Found node %s for %s", first_node->details->uname, first->uuid);
            }
        }

        if (then->rsc && then->rsc->variant == pe_group && safe_str_eq(then->task, RSC_START)) {
            then_node = then->rsc->fns->location(then->rsc, NULL, FALSE);
            if (then_node) {
                crm_trace("Then: Found node %s for %s", then_node->details->uname, then->uuid);
            }
        }

        clear_bit_inplace(changed, pe_graph_updated_first);

        if (first->rsc != then->rsc
            && first->rsc != NULL && then->rsc != NULL && first->rsc != then->rsc->parent) {
            first = rsc_expand_action(first);
        }
        if (first != other->action) {
            crm_trace("Ordering %s afer %s instead of %s", then->uuid, first->uuid,
                      other->action->uuid);
        }

        first_flags = get_action_flags(first, then_node);
        then_flags = get_action_flags(then, first_node);

        crm_trace("Checking %s (%s %s %s) against %s (%s %s %s) 0x%.6x",
                  then->uuid,
                  is_set(then_flags, pe_action_optional) ? "optional" : "required",
                  is_set(then_flags, pe_action_runnable) ? "runnable" : "unrunnable",
                  is_set(then_flags,
                         pe_action_pseudo) ? "pseudo" : then->node ? then->node->details->
                  uname : "", first->uuid, is_set(first_flags,
                                                  pe_action_optional) ? "optional" : "required",
                  is_set(first_flags, pe_action_runnable) ? "runnable" : "unrunnable",
                  is_set(first_flags,
                         pe_action_pseudo) ? "pseudo" : first->node ? first->node->details->
                  uname : "", other->type);

        if (first == other->action) {
            clear_bit_inplace(first_flags, pe_action_pseudo);
            changed |= graph_update_action(first, then, then->node, first_flags, other->type);

        } else if (order_actions(first, then, other->type)) {
            /* Start again to get the new actions_before list */
            changed |= (pe_graph_updated_then | pe_graph_disable);
        }

        if (changed & pe_graph_disable) {
            crm_trace("Disabled constraint %s -> %s", other->action->uuid, then->uuid);
            clear_bit_inplace(changed, pe_graph_disable);
            other->type = pe_order_none;
        }

        if (changed & pe_graph_updated_first) {
            GListPtr lpc2 = NULL;

            crm_trace("Updated %s (first %s %s %s), processing dependants ",
                      first->uuid,
                      is_set(first->flags, pe_action_optional) ? "optional" : "required",
                      is_set(first->flags, pe_action_runnable) ? "runnable" : "unrunnable",
                      is_set(first->flags,
                             pe_action_pseudo) ? "pseudo" : first->node ? first->node->details->
                      uname : "");
            for (lpc2 = first->actions_after; lpc2 != NULL; lpc2 = lpc2->next) {
                action_wrapper_t *other = (action_wrapper_t *) lpc2->data;

                update_action(other->action);
            }
            update_action(first);
        }
    }

    if (is_set(then->flags, pe_action_requires_any)) {
        if (last_flags != then->flags) {
            changed |= pe_graph_updated_then;
        } else {
            clear_bit_inplace(changed, pe_graph_updated_then);
        }
    }

    if (changed & pe_graph_updated_then) {
        crm_trace("Updated %s (then %s %s %s), processing dependants ",
                  then->uuid,
                  is_set(then->flags, pe_action_optional) ? "optional" : "required",
                  is_set(then->flags, pe_action_runnable) ? "runnable" : "unrunnable",
                  is_set(then->flags,
                         pe_action_pseudo) ? "pseudo" : then->node ? then->node->details->
                  uname : "");

        update_action(then);
        for (lpc = then->actions_after; lpc != NULL; lpc = lpc->next) {
            action_wrapper_t *other = (action_wrapper_t *) lpc->data;

            update_action(other->action);
        }
    }

    return FALSE;
}
Exemplo n.º 15
0
enum crmd_fsa_state
s_crmd_fsa(enum crmd_fsa_cause cause)
{
    fsa_data_t *fsa_data = NULL;
    long long register_copy = fsa_input_register;
    long long new_actions = A_NOTHING;
    enum crmd_fsa_state last_state = fsa_state;

    crm_trace("FSA invoked with Cause: %s\tState: %s",
                fsa_cause2string(cause), fsa_state2string(fsa_state));

    do_fsa_stall = FALSE;
    if (is_message() == FALSE && fsa_actions != A_NOTHING) {
        /* fake the first message so we can get into the loop */
        crm_malloc0(fsa_data, sizeof(fsa_data_t));
        fsa_data->fsa_input = I_NULL;
        fsa_data->fsa_cause = C_FSA_INTERNAL;
        fsa_data->origin = __FUNCTION__;
        fsa_data->data_type = fsa_dt_none;
        fsa_message_queue = g_list_append(fsa_message_queue, fsa_data);
        fsa_data = NULL;
    }
    while (is_message() && do_fsa_stall == FALSE) {
        crm_trace("Checking messages (%d remaining)", g_list_length(fsa_message_queue));

        fsa_data = get_message();
        CRM_CHECK(fsa_data != NULL, continue);

        log_fsa_input(fsa_data);

        /* add any actions back to the queue */
        fsa_actions |= fsa_data->actions;

        /* get the next batch of actions */
        new_actions = crmd_fsa_actions[fsa_data->fsa_input][fsa_state];
        fsa_actions |= new_actions;

        if (fsa_data->fsa_input != I_NULL && fsa_data->fsa_input != I_ROUTER) {
            crm_debug("Processing %s: [ state=%s cause=%s origin=%s ]",
                      fsa_input2string(fsa_data->fsa_input),
                      fsa_state2string(fsa_state),
                      fsa_cause2string(fsa_data->fsa_cause), fsa_data->origin);
        }
#ifdef FSA_TRACE
        if (new_actions != A_NOTHING) {
            crm_trace("Adding FSA actions %.16llx for %s/%s",
                        new_actions, fsa_input2string(fsa_data->fsa_input),
                        fsa_state2string(fsa_state));
            fsa_dump_actions(new_actions, "\tFSA scheduled");

        } else if (fsa_data->fsa_input != I_NULL && new_actions == A_NOTHING) {
            crm_debug("No action specified for input,state (%s,%s)",
                      fsa_input2string(fsa_data->fsa_input), fsa_state2string(fsa_state));
        }
        if (fsa_data->actions != A_NOTHING) {
            crm_trace("Adding input actions %.16llx for %s/%s",
                        new_actions, fsa_input2string(fsa_data->fsa_input),
                        fsa_state2string(fsa_state));
            fsa_dump_actions(fsa_data->actions, "\tInput scheduled");
        }
#endif

        /* logging : *before* the state is changed */
        if (is_set(fsa_actions, A_ERROR)) {
            do_fsa_action(fsa_data, A_ERROR, do_log);
        }
        if (is_set(fsa_actions, A_WARN)) {
            do_fsa_action(fsa_data, A_WARN, do_log);
        }
        if (is_set(fsa_actions, A_LOG)) {
            do_fsa_action(fsa_data, A_LOG, do_log);
        }

        /* update state variables */
        last_state = fsa_state;
        fsa_state = crmd_fsa_state[fsa_data->fsa_input][fsa_state];

        /*
         * Remove certain actions during shutdown
         */
        if (fsa_state == S_STOPPING || ((fsa_input_register & R_SHUTDOWN) == R_SHUTDOWN)) {
            clear_bit_inplace(fsa_actions, startup_actions);
        }

        /*
         * Hook for change of state.
         * Allows actions to be added or removed when entering a state
         */
        if (last_state != fsa_state) {
            fsa_actions = do_state_transition(fsa_actions, last_state, fsa_state, fsa_data);
        } else {
            do_dot_log(DOT_PREFIX "\t// FSA input: State=%s \tCause=%s"
                       " \tInput=%s \tOrigin=%s() \tid=%d",
                       fsa_state2string(fsa_state),
                       fsa_cause2string(fsa_data->fsa_cause),
                       fsa_input2string(fsa_data->fsa_input), fsa_data->origin, fsa_data->id);
        }

        /* start doing things... */
        s_crmd_fsa_actions(fsa_data);
        delete_fsa_input(fsa_data);
        fsa_data = NULL;
    }

    if (g_list_length(fsa_message_queue) > 0 || fsa_actions != A_NOTHING || do_fsa_stall) {
        crm_debug("Exiting the FSA: queue=%d, fsa_actions=0x%llx, stalled=%s",
                  g_list_length(fsa_message_queue), fsa_actions, do_fsa_stall ? "true" : "false");
    } else {
        crm_trace("Exiting the FSA");
    }

    /* cleanup inputs? */
    if (register_copy != fsa_input_register) {
        long long same = register_copy & fsa_input_register;

        fsa_dump_inputs(LOG_DEBUG, "Added input:", fsa_input_register ^ same);
        fsa_dump_inputs(LOG_DEBUG, "Removed input:", register_copy ^ same);
    }

    fsa_dump_queue(LOG_DEBUG);

    return fsa_state;
}
Exemplo n.º 16
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.º 17
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;
		}
	}
}