ha/service-mgmt/sm/src/sm_service_enabling_throttl...

263 lines
8.8 KiB
C

//
// Copyright (c) 2018 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include "sm_service_enabling_throttle_state.h"
#include <stdio.h>
#include <string.h>
#include "sm_types.h"
#include "sm_debug.h"
#include "sm_service_fsm.h"
#include "sm_service_go_active.h"
#include "sm_service_enable.h"
#include "sm_service_dependency.h"
#define SM_SERVICE_ENABLING_THROTTLE_TIMEOUT_IN_MS 25
// Check if a service is ready to go enable from throttling
static SmErrorT sm_service_enabling_throttle_check( SmServiceT* service, bool& goahead );
// ****************************************************************************
// Service Enabling Throttle State - Timeout Timer
// ======================================
static bool sm_service_enabling_throttle_state_timeout_timer( SmTimerIdT timer_id,
int64_t user_data )
{
int64_t id = user_data;
SmServiceT* service;
SmErrorT error;
service = sm_service_table_read_by_id( id );
if( NULL == service )
{
DPRINTFE( "Failed to read service %d, error=%s.",
id, sm_error_str(SM_NOT_FOUND) );
// service no longer exists, deprovisioned?
service->action_state_timer_id = SM_TIMER_ID_INVALID;
return( false );
}
bool goahead;
error = sm_service_enabling_throttle_check(service, goahead);
if( SM_OKAY != error )
{
DPRINTFE( "Failed to check service %s throttling state, error=%s.",
service->name, sm_error_str( error ) );
// retry next time
return true;
}
if ( goahead )
{
error = sm_service_fsm_set_state( service,
SM_SERVICE_STATE_ENABLING );
if( SM_OKAY != error )
{
DPRINTFE( "Set state (%s) of service (%s) failed, error=%s.",
sm_service_state_str( SM_SERVICE_STATE_ENABLING ),
service->name, sm_error_str( error ) );
// retry next time
return true;
}
}else
{
DPRINTFD("%s dependency not met", service->name);
// cannot goahead enable the service, wait for next attempt
return true;
}
// set to enabling state, timer is no more needed
service->action_state_timer_id = SM_TIMER_ID_INVALID;
return( false );
}
// ****************************************************************************
// ****************************************************************************
// Service Enabling Throttle State - check if a service is ready to enable
// ==============================
SmErrorT sm_service_enabling_throttle_check( SmServiceT* service, bool& goahead )
{
bool dependency_met;
SmErrorT error;
// Are enable dependencies met?
goahead = false;
error = sm_service_dependency_enable_met( service, &dependency_met );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to check service (%s) dependencies, error=%s.",
service->name, sm_error_str( error ) );
return( error );
}
if( !dependency_met )
{
DPRINTFD( "Some dependencies for service (%s) were not met.", service->name );
return( SM_OKAY );
}
DPRINTFD( "All dependencies for service (%s) were met.Attempt to enable service ",
service->name );
goahead = sm_service_enable_throttle_check();
return SM_OKAY;
}
// ****************************************************************************
// ****************************************************************************
// Service Enabling Throttle State - Entry
// ==============================
SmErrorT sm_service_enabling_throttle_state_entry( SmServiceT* service )
{
char timer_name[80] = "";
SmTimerIdT action_state_timer_id;
SmErrorT error;
int timeout = SM_SERVICE_ENABLING_THROTTLE_TIMEOUT_IN_MS;
if( SM_TIMER_ID_INVALID != service->action_state_timer_id )
{
error = sm_timer_deregister( service->action_state_timer_id );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to cancel enabling overall timer, error=%s.",
sm_error_str( error ) );
}
service->action_state_timer_id = SM_TIMER_ID_INVALID;
}
snprintf( timer_name, sizeof(timer_name), "%s wait for enabling",
service->name );
error = sm_timer_register( timer_name,
timeout,
sm_service_enabling_throttle_state_timeout_timer,
service->id, &action_state_timer_id );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to create enabling throttle timer for service "
"(%s), error=%s.", service->name, sm_error_str( error ) );
return( error );
}
service->action_state_timer_id = action_state_timer_id;
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Service Enabling Throttle State - Exit
// =============================
SmErrorT sm_service_enabling_throttle_state_exit( SmServiceT* service )
{
SmErrorT error;
if( SM_TIMER_ID_INVALID != service->action_state_timer_id )
{
error = sm_timer_deregister( service->action_state_timer_id );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to cancel enabling overall timer, error=%s.",
sm_error_str( error ) );
}
service->action_state_timer_id = SM_TIMER_ID_INVALID;
}
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Service Enabling Throttle State - Transition
// ===================================
SmErrorT sm_service_enabling_throttle_state_transition( SmServiceT* service,
SmServiceStateT from_state )
{
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Service Enabling Throttle State - Event Handler
// ======================================
SmErrorT sm_service_enabling_throttle_state_event_handler( SmServiceT* service,
SmServiceEventT event, void* event_data[] )
{
SmErrorT error;
switch( event )
{
case SM_SERVICE_EVENT_ENABLE_THROTTLE:
// ignore. already in this state
break;
break;
case SM_SERVICE_EVENT_ENABLE:
error = sm_service_fsm_set_state( service,
SM_SERVICE_STATE_ENABLING );
if( SM_OKAY != error )
{
DPRINTFE( "Set state (%s) of service (%s) failed, error=%s.",
sm_service_state_str( SM_SERVICE_STATE_ENABLING ),
service->name, sm_error_str( error ) );
return( error );
}
break;
case SM_SERVICE_EVENT_DISABLE:
error = sm_service_fsm_set_state( service,
SM_SERVICE_STATE_DISABLING );
if( SM_OKAY != error )
{
DPRINTFE( "Set state (%s) of service (%s) failed, error=%s.",
sm_service_state_str( SM_SERVICE_STATE_DISABLING ),
service->name, sm_error_str( error ) );
return( error );
}
break;
case SM_SERVICE_EVENT_SHUTDOWN:
error = sm_service_fsm_set_state( service,
SM_SERVICE_STATE_SHUTDOWN );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to set service (%s) state (%s), error=%s.",
service->name,
sm_service_state_str(SM_SERVICE_STATE_SHUTDOWN),
sm_error_str( error ) );
return( error );
}
break;
default:
DPRINTFD( "Service (%s) ignoring event (%s).", service->name,
sm_service_event_str( event ) );
break;
}
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Service Enabling Throttle State - Initialize
// ===================================
SmErrorT sm_service_enabling_throttle_state_initialize( void )
{
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Service Enabling Throttle State - Finalize
// =================================
SmErrorT sm_service_enabling_throttle_state_finalize( void )
{
return( SM_OKAY );
}
// ****************************************************************************