c2c8228d30
This commit does not have any functional or performance change. This change adds -std=c++11 compile option to Makefiles to enalbe using C++11 standard features. This change also cleans errors that c++11 standard complains: Werror=literal-suffix, e.g: "msg_seq=%"PRIi64"." error: invalid suffix on literal; C++11 requires a space between literal and identifier changed to: "msg_seq=%" PRIi64 "." Story: 2003493 Task: 24770 Change-Id: I0225a4326ff8320f36246cc5678698781e903617 Signed-off-by: Bin Qian <bin.qian@windriver.com>
345 lines
14 KiB
C
345 lines
14 KiB
C
//
|
|
// Copyright (c) 2014 Wind River Systems, Inc.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
#include "sm_service_domain_neighbor_exchange_start_state.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "sm_types.h"
|
|
#include "sm_debug.h"
|
|
#include "sm_service_domain_neighbor_fsm.h"
|
|
#include "sm_service_domain_utils.h"
|
|
#include "sm_service_domain_assignment_table.h"
|
|
#include "sm_failover.h"
|
|
|
|
static const int MIN_EXCHANGE_START_INTERVAL_MS = 100;
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start - Clear Assignments
|
|
// ==========================================================
|
|
static void sm_service_domain_neighbor_exchange_start_clear_assignments(
|
|
void* user_data[], SmServiceDomainAssignmentT* assignment )
|
|
{
|
|
assignment->exchanged = false;
|
|
}
|
|
// ****************************************************************************
|
|
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start - Timeout
|
|
// ================================================
|
|
static bool sm_service_domain_neighbor_exchange_start_timeout(
|
|
SmTimerIdT timer_id, int64_t user_data )
|
|
{
|
|
char reason_text[SM_LOG_REASON_TEXT_MAX_CHAR] = "";
|
|
int64_t id = user_data;
|
|
SmServiceDomainNeighborT* neighbor;
|
|
SmServiceDomainNeighborEventT event;
|
|
SmErrorT error;
|
|
|
|
neighbor = sm_service_domain_neighbor_table_read_by_id( id );
|
|
if( NULL == neighbor )
|
|
{
|
|
DPRINTFE( "Failed to read neighbor (%" PRIi64 "), error=%s.", id,
|
|
sm_error_str(SM_NOT_FOUND) );
|
|
return( true );
|
|
}
|
|
|
|
event = SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_EXCHANGE_START_TIMER;
|
|
|
|
snprintf( reason_text, sizeof(reason_text), "exchange-start timeout for %s",
|
|
neighbor->service_domain );
|
|
|
|
error = sm_service_domain_neighbor_fsm_event_handler( neighbor->name,
|
|
neighbor->service_domain, event, NULL,
|
|
reason_text );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Service domain (%s) neighbor (%s) unable to handle "
|
|
"event (%s), error=%s.", neighbor->service_domain,
|
|
neighbor->name, sm_service_domain_neighbor_event_str( event ),
|
|
sm_error_str( error ) );
|
|
return( true );
|
|
}
|
|
|
|
return( true );
|
|
}
|
|
// ****************************************************************************
|
|
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start State - Entry
|
|
// ====================================================
|
|
SmErrorT sm_service_domain_neighbor_exchange_start_state_entry(
|
|
SmServiceDomainNeighborT* neighbor )
|
|
{
|
|
char timer_name[80] = "";
|
|
SmTimerIdT exchange_timer_id;
|
|
SmErrorT error;
|
|
|
|
error = sm_service_domain_utils_update_own_assignments(
|
|
neighbor->service_domain );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to update own assignments for service domain "
|
|
"(%s), error=%s.", neighbor->service_domain,
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
|
|
sm_service_domain_assignment_table_foreach_node_in_service_domain(
|
|
neighbor->service_domain, neighbor->name, NULL,
|
|
sm_service_domain_neighbor_exchange_start_clear_assignments );
|
|
|
|
snprintf( timer_name, sizeof(timer_name), "neighbor %s exchange start",
|
|
neighbor->name );
|
|
|
|
if( neighbor->exchange_master )
|
|
{
|
|
error = sm_timer_register( timer_name, neighbor->exchange_interval,
|
|
sm_service_domain_neighbor_exchange_start_timeout,
|
|
neighbor->id, &exchange_timer_id );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to create exchange start timer for service "
|
|
"domain (%s) neighbor (%s), error=%s.",
|
|
neighbor->service_domain, neighbor->name,
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
|
|
++neighbor->exchange_seq;
|
|
neighbor->exchange_timer_id = exchange_timer_id;
|
|
|
|
error = sm_service_domain_utils_send_exchange_start(
|
|
neighbor->service_domain, neighbor, neighbor->exchange_seq );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to send exchange start for service domain (%s) "
|
|
"neighbor (%s), error=%s.", neighbor->service_domain,
|
|
neighbor->name, sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
} else {
|
|
error = sm_timer_register( timer_name, neighbor->exchange_interval*4,
|
|
sm_service_domain_neighbor_exchange_start_timeout,
|
|
neighbor->id, &exchange_timer_id );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to create exchange start timer for service "
|
|
"domain (%s) neighbor (%s), error=%s.",
|
|
neighbor->service_domain, neighbor->name,
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
|
|
neighbor->exchange_seq = 0;
|
|
neighbor->exchange_timer_id = exchange_timer_id;
|
|
}
|
|
|
|
return( SM_OKAY );
|
|
}
|
|
// ****************************************************************************
|
|
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start State - Exit
|
|
// ===================================================
|
|
SmErrorT sm_service_domain_neighbor_exchange_start_state_exit(
|
|
SmServiceDomainNeighborT* neighbor )
|
|
{
|
|
SmErrorT error;
|
|
|
|
if( SM_TIMER_ID_INVALID != neighbor->exchange_timer_id )
|
|
{
|
|
error = sm_timer_deregister( neighbor->exchange_timer_id );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to cancel exchange start timer for service "
|
|
"domain (%s) neighbor (%s), error=%s.",
|
|
neighbor->service_domain, neighbor->name,
|
|
sm_error_str( error ) );
|
|
}
|
|
|
|
neighbor->exchange_timer_id = SM_TIMER_ID_INVALID;
|
|
}
|
|
|
|
return( SM_OKAY );
|
|
}
|
|
// ****************************************************************************
|
|
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start State - Transition
|
|
// =========================================================
|
|
SmErrorT sm_service_domain_neighbor_exchange_start_state_transition(
|
|
SmServiceDomainNeighborT* neighbor,
|
|
SmServiceDomainNeighborStateT from_state )
|
|
{
|
|
return( SM_OKAY );
|
|
}
|
|
// ****************************************************************************
|
|
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start State - Event Handler
|
|
// ============================================================
|
|
SmErrorT sm_service_domain_neighbor_exchange_start_state_event_handler(
|
|
SmServiceDomainNeighborT* neighbor, SmServiceDomainNeighborEventT event,
|
|
void* event_data[] )
|
|
{
|
|
int exchange_seq;
|
|
SmServiceDomainNeighborStateT state = SM_SERVICE_DOMAIN_NEIGHBOR_STATE_NIL;
|
|
SmErrorT error;
|
|
|
|
switch( event )
|
|
{
|
|
case SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_HELLO_MSG:
|
|
sm_failover_hello_msg_restore();
|
|
error = sm_service_domain_neighbor_fsm_restart_dead_timer( neighbor );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to restart dead timer for service domain (%s) "
|
|
"neighbor (%s), error=%s.", neighbor->service_domain,
|
|
neighbor->name, sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
break;
|
|
|
|
case SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_EXCHANGE_START_MSG:
|
|
exchange_seq = *(int*)
|
|
event_data[SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_DATA_MSG_EXCHANGE_SEQ];
|
|
|
|
if( neighbor->exchange_master )
|
|
{
|
|
if( exchange_seq == neighbor->exchange_seq )
|
|
{
|
|
state = SM_SERVICE_DOMAIN_NEIGHBOR_STATE_EXCHANGE;
|
|
|
|
} else {
|
|
error = sm_service_domain_utils_send_exchange_start_throttle(
|
|
neighbor->service_domain,
|
|
neighbor,
|
|
neighbor->exchange_seq,
|
|
MIN_EXCHANGE_START_INTERVAL_MS);
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to send exchange start for service "
|
|
"domain (%s) neighbor (%s), error=%s.",
|
|
neighbor->service_domain, neighbor->name,
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
}
|
|
} else {
|
|
state = SM_SERVICE_DOMAIN_NEIGHBOR_STATE_EXCHANGE;
|
|
|
|
error = sm_service_domain_utils_send_exchange_start(
|
|
neighbor->service_domain,
|
|
neighbor, exchange_seq );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to send exchange start for service "
|
|
"domain (%s) neighbor (%s), error=%s.",
|
|
neighbor->service_domain, neighbor->name,
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
}
|
|
|
|
if( SM_SERVICE_DOMAIN_NEIGHBOR_STATE_EXCHANGE == state )
|
|
{
|
|
error = sm_service_domain_neighbor_fsm_set_state( neighbor->name,
|
|
neighbor->service_domain, state );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Service domain neighbor (%s) set state (%s) "
|
|
"failed, error=%s.", neighbor->name,
|
|
sm_service_domain_neighbor_state_str( state ),
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_EXCHANGE_START_TIMER:
|
|
if( neighbor->exchange_master )
|
|
{
|
|
++neighbor->exchange_seq;
|
|
|
|
error = sm_service_domain_utils_send_exchange_start(
|
|
neighbor->service_domain,
|
|
neighbor,
|
|
neighbor->exchange_seq );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to send exchange start for service "
|
|
"domain (%s) neighbor (%s), error=%s.",
|
|
neighbor->service_domain, neighbor->name,
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
} else {
|
|
error = sm_service_domain_utils_send_exchange_start(
|
|
neighbor->service_domain,
|
|
neighbor, 0 );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Failed to send exchange start for service "
|
|
"domain (%s) neighbor (%s), error=%s.",
|
|
neighbor->service_domain, neighbor->name,
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_EXCHANGE_MSG:
|
|
case SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_EXCHANGE_TIMEOUT:
|
|
// Ignore.
|
|
break;
|
|
|
|
case SM_SERVICE_DOMAIN_NEIGHBOR_EVENT_DOWN:
|
|
state = SM_SERVICE_DOMAIN_NEIGHBOR_STATE_DOWN;
|
|
|
|
error = sm_service_domain_neighbor_fsm_set_state( neighbor->name,
|
|
neighbor->service_domain, state );
|
|
if( SM_OKAY != error )
|
|
{
|
|
DPRINTFE( "Service domain neighbor (%s) set state (%s) "
|
|
"failed, error=%s.", neighbor->name,
|
|
sm_service_domain_neighbor_state_str( state ),
|
|
sm_error_str( error ) );
|
|
return( error );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DPRINTFD( "Neighbor (%s) ignoring event (%s).", neighbor->name,
|
|
sm_service_domain_neighbor_event_str( event ) );
|
|
break;
|
|
}
|
|
|
|
return( SM_OKAY );
|
|
}
|
|
// ****************************************************************************
|
|
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start State - Initialize
|
|
// =========================================================
|
|
SmErrorT sm_service_domain_neighbor_exchange_start_state_initialize(
|
|
void )
|
|
{
|
|
return( SM_OKAY );
|
|
}
|
|
// ****************************************************************************
|
|
|
|
// ****************************************************************************
|
|
// Service Domain Neighbor Exchange Start State - Finalize
|
|
// =======================================================
|
|
SmErrorT sm_service_domain_neighbor_exchange_start_state_finalize( void )
|
|
{
|
|
return( SM_OKAY );
|
|
}
|
|
// ****************************************************************************
|