// // Copyright (c) 2018 Wind River Systems, Inc. // // SPDX-License-Identifier: Apache-2.0 // #include "sm_failover_normal_state.h" #include #include "sm_limits.h" #include "sm_types.h" #include "sm_debug.h" #include "sm_node_api.h" #include "sm_node_utils.h" #include "sm_failover_utils.h" #include "sm_failover_fsm.h" #include "sm_failover_ss.h" #include "sm_cluster_hbs_info_msg.h" SmErrorT SmFailoverNormalState::event_handler(SmFailoverEventT event, const ISmFSMEventData* event_data) { switch (event) { case SM_FAILOVER_EVENT_IF_STATE_CHANGED: if(NULL != event_data && SmIFStateChangedEventData::SmIFStateChangedEventDataType == event_data->get_event_data_type()) { const SmIFStateChangedEventData* data = (const SmIFStateChangedEventData*) event_data; SmFailoverInterfaceStateT oam_state, mgmt_state, infra_state; oam_state = data->get_interface_state(SM_INTERFACE_OAM); mgmt_state = data->get_interface_state(SM_INTERFACE_MGMT); infra_state = data->get_interface_state(SM_INTERFACE_INFRA); if(oam_state != SM_FAILOVER_INTERFACE_OK || mgmt_state != SM_FAILOVER_INTERFACE_OK || (infra_state != SM_FAILOVER_INTERFACE_OK && infra_state != SM_FAILOVER_INTERFACE_UNKNOWN)) { this->fsm.set_state(SM_FAILOVER_STATE_FAIL_PENDING); } }else { DPRINTFE("Runtime error: receive invalid event data type"); } break; default: DPRINTFE("Runtime error, unexpected event %s, at state %s", sm_failover_event_str(event), sm_failover_state_str(this->fsm.get_state())); } return SM_OKAY; } SmErrorT SmFailoverNormalState::exit_state() { SmSystemFailoverStatus& failover_status = SmSystemFailoverStatus::get_status(); char host_name[SM_NODE_NAME_MAX_CHAR]; SmErrorT error = sm_node_utils_get_hostname(host_name); if( SM_OKAY != error ) { DPRINTFE( "Failed to get hostname, error=%s.", sm_error_str( error ) ); failover_status.set_host_pre_failure_schedule_state(SM_NODE_STATE_UNKNOWN); }else { SmNodeScheduleStateT host_state = sm_get_controller_state(host_name); DPRINTFI("Blind guess pre failure host state %s", sm_node_schedule_state_str(host_state)); failover_status.set_host_pre_failure_schedule_state(host_state); } char peer_name[SM_NODE_NAME_MAX_CHAR]; error = sm_node_api_get_peername(peer_name); if( SM_OKAY != error ) { DPRINTFE( "Failed to get peername, error=%s.", sm_error_str( error ) ); failover_status.set_peer_pre_failure_schedule_state(SM_NODE_STATE_UNKNOWN); }else { SmNodeScheduleStateT peer_state = sm_get_controller_state(peer_name); failover_status.set_peer_pre_failure_schedule_state(peer_state); } const SmClusterHbsStateT& cluster_hbs_state_cur = SmClusterHbsInfoMsg::get_current_state(); const SmClusterHbsStateT& cluster_hbs_state_pre = SmClusterHbsInfoMsg::get_previous_state(); SmClusterHbsStateT pre_failure_cluster_hsb_state; if(!is_valid(cluster_hbs_state_cur)) { DPRINTFE("No cluster hbs state available"); }else { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); if(ts.tv_sec - cluster_hbs_state_cur.last_update <= 1 && cluster_hbs_state_pre.last_update != 0) { // cluster hbs state changed within past 1 second, take the pre state as pre-failure state. pre_failure_cluster_hsb_state = cluster_hbs_state_pre; }else { pre_failure_cluster_hsb_state = cluster_hbs_state_cur; } log_cluster_hbs_state(pre_failure_cluster_hsb_state); failover_status.set_pre_failure_cluster_hbs_state(pre_failure_cluster_hsb_state); } SmFSMState::exit_state(); return SM_OKAY; }