369 lines
12 KiB
C++
369 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2018 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* @file Maintenance Heartbeat Utilities Module
|
|
*
|
|
*************************************************************************
|
|
*
|
|
* This module provides heartbeat utilities that are common to both
|
|
* hbsAgent and hbsClient.
|
|
*
|
|
*************************************************************************/
|
|
|
|
using namespace std;
|
|
|
|
#include "daemon_common.h" /* common daemon constructs and definitions */
|
|
#include "hbsBase.h" /* mtce heartbeat constructs and definitions */
|
|
|
|
/* hbs_cluster_log utility support. log control array. */
|
|
bool first_log[MTCE_HBS_MAX_HISTORY_ELEMENTS]; /* has first history log out */
|
|
bool was_diff [MTCE_HBS_MAX_HISTORY_ELEMENTS]; /* was there a history diff */
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Name : hbs_utils_init
|
|
*
|
|
* Description : Module Init function
|
|
*
|
|
***************************************************************************/
|
|
|
|
void hbs_utils_init ( void )
|
|
{
|
|
MEMSET_ZERO ( first_log );
|
|
MEMSET_ZERO ( was_diff );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Name : hbs_cluster_history_init
|
|
*
|
|
* Description : Initialize a cluster history element.
|
|
*
|
|
* Parameters : Reference to a mtce_hbs_cluster_history_type (history element)
|
|
*
|
|
* Returns : Nothing
|
|
*
|
|
***************************************************************************/
|
|
|
|
void hbs_cluster_history_init ( mtce_hbs_cluster_history_type & history )
|
|
{
|
|
MEMSET_ZERO(history);
|
|
history.entries_max = MTCE_HBS_HISTORY_ENTRIES ;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Name : hbs_cluster_history_clear
|
|
*
|
|
* Description : Clear all history in the cluster vault.
|
|
*
|
|
* Parameters : mtce_hbs_cluster_type instance : the vault.
|
|
*
|
|
* Returns : Nothing
|
|
*
|
|
***************************************************************************/
|
|
|
|
void hbs_cluster_history_clear ( mtce_hbs_cluster_type & cluster )
|
|
{
|
|
if ( cluster.histories )
|
|
{
|
|
for ( int h = 0 ; h < cluster.histories ; h++ )
|
|
hbs_cluster_history_init ( cluster.history[h] ) ;
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Name : cluster_network_name
|
|
*
|
|
* Description : converts what is a heartbeat cluster network id to
|
|
* network name.
|
|
*
|
|
* Parameters : network id
|
|
*
|
|
* Returns : network name as a string
|
|
*
|
|
***************************************************************************/
|
|
|
|
string hbs_cluster_network_name ( mtce_hbs_network_enum network )
|
|
{
|
|
switch ( network )
|
|
{
|
|
case MTCE_HBS_NETWORK_MGMT:
|
|
return ("Mgmnt");
|
|
case MTCE_HBS_NETWORK_INFRA:
|
|
return ("Infra");
|
|
|
|
#ifdef MONITORED_OAM_NETWORK
|
|
case MTCE_HBS_NETWORK_OAM:
|
|
return ("Oam");
|
|
#endif
|
|
|
|
default:
|
|
slog ("invalid network enum (%d)", network );
|
|
return ("unknown");
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Name : hbs_cluster_copy
|
|
*
|
|
* Descrition : Copies cluster from src to dst.
|
|
*
|
|
* Returns : Nothing.
|
|
*
|
|
***************************************************************************/
|
|
|
|
void hbs_cluster_copy ( mtce_hbs_cluster_type & src, mtce_hbs_cluster_type & dst )
|
|
{
|
|
dst.version = src.version ;
|
|
dst.revision = src.revision ;
|
|
dst.magic_number = src.magic_number ;
|
|
dst.period_msec = src.period_msec ;
|
|
dst.histories = src.histories ;
|
|
dst.storage0_enabled = src.storage0_enabled ;
|
|
for ( int h = 0 ; h < dst.histories ; h++ )
|
|
{
|
|
memcpy( &dst.history[h],
|
|
&src.history[h],
|
|
sizeof(mtce_hbs_cluster_history_type));
|
|
}
|
|
dst.bytes = BYTES_IN_CLUSTER_VAULT(dst.histories);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Name : hbs_cluster_log
|
|
*
|
|
* Description : logs changes to the heartbeat cluster
|
|
*
|
|
* Parameters : The heartbeat cluster structure
|
|
*
|
|
* Returns : Nothing
|
|
*
|
|
***************************************************************************/
|
|
|
|
void hbs_cluster_log ( string & hostname,
|
|
mtce_hbs_cluster_type & cluster,
|
|
string log_prefix,
|
|
bool force )
|
|
{
|
|
for ( int h = 0 ; h < cluster.histories ; h++ )
|
|
{
|
|
if ( cluster.history[h].entries == MTCE_HBS_HISTORY_ENTRIES )
|
|
{
|
|
#define MAX_CLUSTER_LINE_LEN 100
|
|
#define MAX_ENTRY_STR_LEN 10 /* "9999:9999 " */
|
|
mtce_hbs_cluster_entry_type e = { 0, 0 } ;
|
|
char str[MAX_CLUSTER_LINE_LEN] ;
|
|
string line = "";
|
|
bool newline = false ;
|
|
bool logit = false ;
|
|
bool first = false ;
|
|
string controller = "" ;
|
|
|
|
mtce_hbs_cluster_history_type * history_ptr = &cluster.history[h] ;
|
|
|
|
/* Manage local this_index for log display.
|
|
* Display oldest to newest ; left to right
|
|
*
|
|
* */
|
|
int this_index = history_ptr->oldest_entry_index ;
|
|
int debug = daemon_get_cfg_ptr()->debug_state ;
|
|
|
|
for ( int count = 0 ; count < history_ptr->entries ; count++ )
|
|
{
|
|
if (( line.length() + MAX_ENTRY_STR_LEN ) >=
|
|
MAX_CLUSTER_LINE_LEN )
|
|
{
|
|
newline = true ;
|
|
}
|
|
|
|
#ifdef WANT_MINIMAL_LOGS
|
|
/* TODO: enable in final update */
|
|
if (( first_log[h] == true ) && ( newline == false ) &&
|
|
( history_ptr->entry[this_index].hosts_enabled ==
|
|
history_ptr->entry[this_index].hosts_responding ))
|
|
{
|
|
line.append(". ");
|
|
continue ;
|
|
}
|
|
#endif
|
|
|
|
if ( count == 0 )
|
|
{
|
|
snprintf (&str[0], MAX_ENTRY_STR_LEN , "%d:%d ", // -%d",
|
|
history_ptr->entry[this_index].hosts_enabled,
|
|
history_ptr->entry[this_index].hosts_responding );
|
|
line.append (str);
|
|
str[0] = '\0' ;
|
|
}
|
|
//#ifdef WANT_DOTS
|
|
else if (( history_ptr->entry[this_index].hosts_enabled ==
|
|
e.hosts_enabled ) &&
|
|
( history_ptr->entry[this_index].hosts_responding ==
|
|
e.hosts_responding ))
|
|
{
|
|
line.append(". ");
|
|
}
|
|
//#endif
|
|
else
|
|
{
|
|
snprintf (&str[0], MAX_ENTRY_STR_LEN , "%d:%d ", // -%d",
|
|
history_ptr->entry[this_index].hosts_enabled,
|
|
history_ptr->entry[this_index].hosts_responding );
|
|
line.append (str);
|
|
str[0] = '\0' ;
|
|
logit = true ;
|
|
was_diff[h] = true ;
|
|
}
|
|
if (( logit == false ) && ( first_log[h] == false ))
|
|
{
|
|
first_log[h] = true ;
|
|
logit = true ;
|
|
}
|
|
if ( newline == true )
|
|
{
|
|
if ( logit )
|
|
{
|
|
SET_CONTROLLER_HOSTNAME(history_ptr->controller);
|
|
if (( force ) || ( debug&2 ))
|
|
{
|
|
syslog ( LOG_INFO, "%s view from %s %s %s: %s",
|
|
controller.c_str(),
|
|
hostname.c_str(),
|
|
log_prefix.c_str(),
|
|
hbs_cluster_network_name((mtce_hbs_network_enum)history_ptr->network).c_str(),
|
|
line.c_str());
|
|
}
|
|
}
|
|
line.clear();
|
|
first = true ;
|
|
newline = false ;
|
|
}
|
|
e = history_ptr->entry[this_index] ;
|
|
|
|
/* manage index tracking */
|
|
if ( this_index == (MTCE_HBS_HISTORY_ENTRIES-1))
|
|
this_index = 0 ;
|
|
else
|
|
this_index++ ;
|
|
}
|
|
if (( newline == false ) && ( line.length() ))
|
|
{
|
|
if (( logit == false ) && ( was_diff[h] == true ))
|
|
{
|
|
logit = true ;
|
|
was_diff[h] = false ;
|
|
}
|
|
|
|
if ( logit )
|
|
{
|
|
if ( first )
|
|
{
|
|
if (( force ) || ( debug&2 ))
|
|
{
|
|
syslog ( LOG_INFO, "............ %s %s: %s",
|
|
log_prefix.c_str(),
|
|
hbs_cluster_network_name((mtce_hbs_network_enum)history_ptr->network).c_str(),
|
|
line.c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SET_CONTROLLER_HOSTNAME(history_ptr->controller);
|
|
if (( force ) || ( debug&2 ))
|
|
{
|
|
syslog ( LOG_INFO, "%s view from %s %s %s: %s",
|
|
controller.c_str(),
|
|
hostname.c_str(),
|
|
log_prefix.c_str(), /* Infra <- */
|
|
hbs_cluster_network_name((mtce_hbs_network_enum)history_ptr->network).c_str(),
|
|
line.c_str());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
was_diff[h] = false ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
*
|
|
* name : hbs_cluster_dump
|
|
*
|
|
* Description: Formatted dump of the vault contents to the log file.
|
|
*
|
|
***************************************************************************/
|
|
void hbs_cluster_dump ( mtce_hbs_cluster_type & vault, string log_prefix, bool force )
|
|
{
|
|
if ( vault.version == 0 )
|
|
return ;
|
|
|
|
int debug = daemon_get_cfg_ptr()->debug_state ;
|
|
|
|
if (( debug & 2 ) || ( force == true ))
|
|
{
|
|
ilog ("%s", log_prefix.c_str());
|
|
syslog ( LOG_INFO, "Cluster Vault : v%d.%d %d msec heartbeat period %s;%d network heartbeat response histories (%d bytes)",
|
|
vault.version,
|
|
vault.revision,
|
|
vault.period_msec,
|
|
vault.storage0_enabled ? " with storage-0: enabled " : "",
|
|
vault.histories,
|
|
vault.bytes );
|
|
}
|
|
|
|
if (( debug & 4 ) || ( force == true ))
|
|
{
|
|
for ( int h = 0 ; h < vault.histories ; h++ )
|
|
{
|
|
#define MAX_LINE_LEN (500)
|
|
char str[MAX_LINE_LEN] ;
|
|
int i = 0 ;
|
|
for ( int e = 0 ; e < vault.history[h].entries_max ; e++ )
|
|
{
|
|
snprintf ( &str[i], MAX_LINE_LEN, "%c[%d:%d]" ,
|
|
vault.history[h].oldest_entry_index==e ? '>' : ' ',
|
|
vault.history[h].entry[e].hosts_enabled,
|
|
vault.history[h].entry[e].hosts_responding);
|
|
i = strlen(str) ;
|
|
}
|
|
if ( vault.storage0_enabled )
|
|
{
|
|
syslog ( LOG_INFO, "Cluster Vault : C%d %s S:%s %s",
|
|
vault.history[h].controller,
|
|
hbs_cluster_network_name((mtce_hbs_network_enum)vault.history[h].network).c_str(),
|
|
vault.history[h].storage0_responding ? "y" : "n",
|
|
str);
|
|
}
|
|
else
|
|
{
|
|
syslog ( LOG_INFO, "Cluster Vault : C%d %s %s",
|
|
vault.history[h].controller,
|
|
hbs_cluster_network_name((mtce_hbs_network_enum)vault.history[h].network).c_str(),
|
|
str);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( debug & 8 )
|
|
{
|
|
dump_memory ( &vault, 16, vault.bytes );
|
|
}
|
|
}
|
|
|
|
|