ha/service-mgmt/sm-common-1.0.0/src/sm_node_utils.c

546 lines
17 KiB
C

//
// Copyright (c) 2014-2018 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include "sm_node_utils.h"
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include "sm_limits.h"
#include "sm_types.h"
#include "sm_debug.h"
#define SM_NODE_GO_ENABLE_FILE "/var/run/goenabled"
#define SM_NODE_GO_ENABLE_FILE_SIMPLEX "/var/run/.goenabled"
#define SM_NODE_UNHEALTHY_FILE "/var/run/.sm_node_unhealthy"
#define SM_NODE_CONFIG_COMPLETE_FILE "/etc/platform/.initial_config_complete"
#define SM_NODE_PLATFORM_CONFIG_FILE "/etc/platform/platform.conf"
static bool _failover_disabled = false;
static SmErrorT _sm_node_utils_get_system_mode_str( char system_mode[] );
static SmErrorT _sm_node_utils_get_system_type_str( char system_type[] );
typedef enum
{
IsUnknown,
IsTrue,
IsFalse
}ThreeValuedT;
static ThreeValuedT _is_aio = IsUnknown;
static ThreeValuedT _is_aio_simplex = IsUnknown;
static ThreeValuedT _is_aio_duplex = IsUnknown;
// ****************************************************************************
// Node Utilities - Read Platform Config
// =====================================
static SmErrorT sm_node_utils_read_platform_config( const char key[],
char value[], int value_size )
{
FILE* fp;
char format[1024];
char line[1024];
char val[1024];
value[0] = '\0';
fp = fopen( SM_NODE_PLATFORM_CONFIG_FILE, "r" );
if( NULL == fp )
{
DPRINTFE( "Failed to open file (%s).", SM_NODE_PLATFORM_CONFIG_FILE );
return( SM_FAILED );
}
snprintf( format, sizeof(format), "%s=%%%ds", (char*) key,
(int) sizeof(val)-1 );
while( NULL != fgets( line, sizeof(line), fp ) )
{
if( 1 == sscanf( line, format, val ) )
{
val[sizeof(val)-1] = '\0';
snprintf( value, value_size, "%s", val );
break;
}
}
fclose( fp );
if( '\0' == value[0] )
{
return( SM_NOT_FOUND );
}
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get Node Type
// ==============================
static SmErrorT sm_node_utils_get_node_type( char node_type[] )
{
return( sm_node_utils_read_platform_config( "nodetype", node_type,
SM_NODE_TYPE_MAX_CHAR ) );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get Sub-Functions
// ==================================
static SmErrorT sm_node_utils_get_sub_functions( char sub_functions[] )
{
return( sm_node_utils_read_platform_config( "subfunction", sub_functions,
SM_NODE_SUB_FUNCTIONS_MAX_CHAR ) );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Node Type Is Controller
// ========================================
SmErrorT sm_node_utils_node_type_is_controller( bool* is_controller )
{
char node_type[SM_NODE_TYPE_MAX_CHAR+1] = "";
SmErrorT error;
*is_controller = false;
error = sm_node_utils_get_node_type( node_type );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to get node type, error=%s.",
sm_error_str(error) );
return( error );
}
if( 0 == strcmp( "controller", node_type ) )
{
*is_controller = true;
}
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - system Is AIO
// ========================================
SmErrorT sm_node_utils_is_aio( bool* is_aio )
{
if( IsUnknown == _is_aio )
{
char system_type[SM_SYSTEM_TYPE_MAX_CHAR];
SmErrorT error;
error = _sm_node_utils_get_system_type_str(system_type);
if( SM_OKAY != error)
{
return error;
}
if( strcmp("All-in-one", system_type) == 0 )
{
_is_aio = IsTrue;
}else
{
_is_aio = IsFalse;
}
*is_aio = ( IsTrue == _is_aio );
}
else
{
*is_aio = ( IsTrue == _is_aio );
}
return SM_OKAY;
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Sub-Functions Has Compute
// ==========================================
SmErrorT sm_node_utils_sub_function_has_compute( bool* has_compute )
{
char sub_functions[SM_NODE_SUB_FUNCTIONS_MAX_CHAR+1] = "";
SmErrorT error;
*has_compute = false;
error = sm_node_utils_get_sub_functions( sub_functions );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to get sub-functions, error=%s.",
sm_error_str(error) );
return( error );
}
if( NULL != strstr( sub_functions, "compute" ) )
{
*has_compute = true;
}
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get Management Interface
// =========================================
SmErrorT sm_node_utils_get_mgmt_interface( char interface_name[] )
{
return( sm_node_utils_read_platform_config( "management_interface",
interface_name,
SM_INTERFACE_NAME_MAX_CHAR ) );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get OAM Interface
// ==================================
SmErrorT sm_node_utils_get_oam_interface( char interface_name[] )
{
return( sm_node_utils_read_platform_config( "oam_interface",
interface_name,
SM_INTERFACE_NAME_MAX_CHAR ) );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get Infrastructure Interface
// =============================================
SmErrorT sm_node_utils_get_infra_interface( char interface_name[] )
{
return( sm_node_utils_read_platform_config( "infrastructure_interface",
interface_name,
SM_INTERFACE_NAME_MAX_CHAR ) );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get system mode string
// =============================================
static SmErrorT _sm_node_utils_get_system_mode_str( char system_mode[] )
{
SmErrorT error = sm_node_utils_read_platform_config( "system_mode",
system_mode,
SM_SYSTEM_MODE_MAX_CHAR);
if( SM_NOT_FOUND == error )
{
system_mode[0] = '\0';
error = SM_OKAY;
}
return error;
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get system type string
// =============================================
static SmErrorT _sm_node_utils_get_system_type_str( char system_type[] )
{
SmErrorT error = sm_node_utils_read_platform_config( "system_type",
system_type,
SM_SYSTEM_TYPE_MAX_CHAR);
if( SM_NOT_FOUND == error )
{
system_type[0] = '\0';
error = SM_OKAY;
}
return error;
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get system mode string
// =============================================
SmSystemModeT sm_node_utils_get_system_mode()
{
char system_mode[SM_SYSTEM_MODE_MAX_CHAR];
char system_type[SM_SYSTEM_TYPE_MAX_CHAR];
if ( SM_OKAY == _sm_node_utils_get_system_type_str(system_type) &&
SM_OKAY == _sm_node_utils_get_system_mode_str(system_mode) )
{
if ( 0 == strcmp("All-in-one", system_type) )
{
if ( 0 == strcmp(SM_CPE_MODE_SIMPLEX, system_mode) )
{
return SM_SYSTEM_MODE_CPE_SIMPLEX;
}
else if ( 0 == strcmp(SM_CPE_MODE_DUPLEX, system_mode) )
{
return SM_SYSTEM_MODE_CPE_DUPLEX;
}
else if ( 0 == strcmp(SM_CPE_MODE_DUPLEX_DIRECT, system_mode) )
{
return SM_SYSTEM_MODE_CPE_DUPLEX_DC;
}
} else if ( 0 == strcmp("Standard", system_type) ) {
return SM_SYSTEM_MODE_STANDARD;
}
}
return SM_SYSTEM_MODE_UNKNOWN;
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get Uptime
// ===========================
SmErrorT sm_node_utils_get_uptime( long* uptime )
{
struct sysinfo info;
int result;
result = sysinfo( &info );
if( 0 > result )
{
DPRINTFE( "Failed to get system uptime, error=%s.",
strerror( errno ) );
return( SM_FAILED );
}
*uptime = info.uptime;
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Get Host Name
// ==============================
SmErrorT sm_node_utils_get_hostname( char node_name[] )
{
char hostname[SM_NODE_NAME_MAX_CHAR];
if( 0 > gethostname( hostname, sizeof(hostname) ) )
{
DPRINTFE( "Failed to get node name, error=%s.", strerror( errno ) );
return( SM_FAILED );
}
snprintf( node_name, SM_NODE_NAME_MAX_CHAR, "%s", hostname );
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Configuration Complete
// =======================================
SmErrorT sm_node_utils_config_complete( bool* complete )
{
*complete = false;
if( 0 > access( SM_NODE_CONFIG_COMPLETE_FILE, F_OK ) )
{
if( ENOENT == errno )
{
DPRINTFD( "Config-Complete file (%s) not available, error=%s.",
SM_NODE_CONFIG_COMPLETE_FILE, strerror( errno ) );
return( SM_OKAY );
} else {
DPRINTFE( "Config-Complete file (%s) access failed, error=%s.",
SM_NODE_CONFIG_COMPLETE_FILE, strerror( errno ) );
return( SM_FAILED );
}
}
*complete = true;
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Enabled
// ========================
SmErrorT sm_node_utils_enabled( bool* enabled, char reason_text[] )
{
*enabled = false;
reason_text[0] = '\0';
bool is_aio_simplex = false;
SmErrorT error = sm_node_utils_is_aio_simplex(&is_aio_simplex);
if(SM_OKAY != error)
{
DPRINTFE("Failed to get system mode, error %s",
sm_error_str(error));
return error;
}
if( (!is_aio_simplex && (0 > access( SM_NODE_GO_ENABLE_FILE, F_OK ))) ||
(is_aio_simplex && (0 > access( SM_NODE_GO_ENABLE_FILE_SIMPLEX, F_OK ))) )
{
if( ENOENT == errno )
{
DPRINTFD( "Go-Enable file (%s) not available, error=%s.",
SM_NODE_GO_ENABLE_FILE, strerror( errno ) );
snprintf( reason_text, SM_LOG_REASON_TEXT_MAX_CHAR,
"node not ready, go-enable not set" );
return( SM_OKAY );
} else {
DPRINTFE( "Go-Enable file (%s) access failed, error=%s.",
SM_NODE_GO_ENABLE_FILE, strerror( errno ) );
return( SM_FAILED );
}
}
if( 0 > access( SM_NODE_CONFIG_COMPLETE_FILE, F_OK ) )
{
if( ENOENT == errno )
{
DPRINTFD( "Config-Complete file (%s) not available, error=%s.",
SM_NODE_CONFIG_COMPLETE_FILE, strerror( errno ) );
snprintf( reason_text, SM_LOG_REASON_TEXT_MAX_CHAR,
"node not ready, config-complete not set" );
return( SM_OKAY );
} else {
DPRINTFE( "Config-Complete file (%s) access failed, error=%s.",
SM_NODE_CONFIG_COMPLETE_FILE, strerror( errno ) );
return( SM_FAILED );
}
}
if( 0 == access( SM_NODE_UNHEALTHY_FILE, F_OK ) )
{
DPRINTFI( "Node unhealthy file (%s) set.", SM_NODE_UNHEALTHY_FILE );
snprintf( reason_text, SM_LOG_REASON_TEXT_MAX_CHAR,
"node not ready, node unhealthy set" );
return( SM_OKAY );
} else {
if( ENOENT != errno )
{
DPRINTFE( "Node unhealthy file (%s) access failed, error=%s.",
SM_NODE_UNHEALTHY_FILE, strerror( errno ) );
return( SM_FAILED );
}
}
if(_failover_disabled)
{
DPRINTFI( "Failover disabled" );
snprintf( reason_text, SM_LOG_REASON_TEXT_MAX_CHAR,
"Failover action to disable node" );
return( SM_OKAY );
}
*enabled = true;
snprintf( reason_text, SM_LOG_REASON_TEXT_MAX_CHAR, "node ready" );
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Set Failover
// ==============================
bool sm_node_utils_set_failover( bool to_disable )
{
bool old_value = _failover_disabled;
if(to_disable)
{
DPRINTFI("disable system for failover");
}
_failover_disabled = to_disable;
return old_value;
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - Set Unhealthy
// ==============================
SmErrorT sm_node_utils_set_unhealthy( void )
{
int fd = open( SM_NODE_UNHEALTHY_FILE,
O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH);
if( 0 > fd )
{
DPRINTFE( "Failed to create file (%s), error=%s.",
SM_NODE_UNHEALTHY_FILE, strerror(errno) );
return( SM_FAILED );
}
close(fd);
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - System Is AIO Simplex
// ======================================
SmErrorT sm_node_utils_is_aio_simplex( bool* is_aio_simplex )
{
if( IsUnknown == _is_aio_simplex )
{
SmSystemModeT system_mode = sm_node_utils_get_system_mode();
if( SM_SYSTEM_MODE_CPE_SIMPLEX == system_mode )
{
_is_aio_simplex = IsTrue;
}else
{
_is_aio_simplex = IsFalse;
}
}
*is_aio_simplex = ( IsTrue == _is_aio_simplex );
return SM_OKAY;
}
// ****************************************************************************
// ****************************************************************************
// Node Utilities - System is AIO Duplex
// =====================================
SmErrorT sm_node_utils_is_aio_duplex( bool* is_aio_duplex )
{
if( IsUnknown == _is_aio_duplex )
{
SmErrorT error;
bool is_aio = false;
error = sm_node_utils_is_aio( &is_aio );
if( SM_OKAY != error)
{
return error;
}
if ( !is_aio )
{
*is_aio_duplex = false;
return SM_OKAY;
}else
{
SmSystemModeT system_mode = sm_node_utils_get_system_mode();
if(( SM_SYSTEM_MODE_CPE_DUPLEX == system_mode ) ||
( SM_SYSTEM_MODE_CPE_DUPLEX_DC == system_mode ))
{
_is_aio_duplex = IsTrue;
}else
{
_is_aio_duplex = IsFalse;
}
}
}
*is_aio_duplex = ( IsTrue == _is_aio_duplex );
return SM_OKAY;
}