http://git-wip-us.apache.org/repos/asf/trafodion/blob/87849fcf/core/sqf/src/trafconf/clusterconf.cpp ---------------------------------------------------------------------- diff --git a/core/sqf/src/trafconf/clusterconf.cpp b/core/sqf/src/trafconf/clusterconf.cpp new file mode 100644 index 0000000..5e3eaa0 --- /dev/null +++ b/core/sqf/src/trafconf/clusterconf.cpp @@ -0,0 +1,855 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ +// +/////////////////////////////////////////////////////////////////////////////// + +using namespace std; + +#include <errno.h> +#include <assert.h> +#include <sched.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <string.h> +#include <iostream> +#include <string> +#include <vector> +#include "tclog.h" +#include "tctrace.h" +#include "trafconf/trafconfig.h" +#include "clusterconf.h" + + +/////////////////////////////////////////////////////////////////////////////// +// Cluster Configuration +/////////////////////////////////////////////////////////////////////////////// + +CClusterConfig::CClusterConfig( void ) + : CPNodeConfigContainer(TC_NODES_MAX) + , CLNodeConfigContainer(TC_NODES_MAX) + , nodeReady_(false) + , persistReady_(false) + , newPNodeConfig_(true) + , trafConfigInitialized_(false) + , trafConfigStorageType_(TCDBSTOREUNDEFINED) + , prevPNodeConfig_(NULL) + , prevLNodeConfig_(NULL) + , prevPersistConfig_(NULL) +{ + const char method_name[] = "CClusterConfig::CClusterConfig"; + TRACE_ENTRY; + + TRACE_EXIT; +} + +CClusterConfig::~CClusterConfig ( void ) +{ + const char method_name[] = "CClusterConfig::~CClusterConfig"; + TRACE_ENTRY; + + TRACE_EXIT; +} + +void CClusterConfig::Clear( void ) +{ + const char method_name[] = "CClusterConfig::Clear"; + TRACE_ENTRY; + + // Delete the node configuration objects + CPNodeConfigContainer::Clear(); + CLNodeConfigContainer::Clear(); + CPersistConfigContainer::Clear(); + + nodeReady_ = false; + persistReady_ = false; + newPNodeConfig_ = true; + prevPNodeConfig_ = NULL; + + if ( trafConfigInitialized_ ) + { + int rc = tc_close(); + if ( rc ) + { + char la_buf[TC_LOG_BUF_SIZE]; + snprintf( la_buf, sizeof(la_buf) + , "[%s], Can't close configuration!\n" + , method_name ); + TcLogWrite( MON_CLUSTERCONF_CLEAR_1, TC_LOG_CRIT, la_buf ); + } + + trafConfigInitialized_ = false; + } + + TRACE_EXIT; +} + +void CClusterConfig::AddNodeConfiguration( pnodeConfigInfo_t &pnodeConfigInfo + , lnodeConfigInfo_t &lnodeConfigInfo ) +{ + const char method_name[] = "CClusterConfig::AddNodeConfiguration"; + TRACE_ENTRY; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf( "%s@%d nid=%d, pnid=%d, nodename=%s\n" + , method_name, __LINE__ + , lnodeConfigInfo.nid + , pnodeConfigInfo.pnid + , pnodeConfigInfo.nodename ); + } + + if ( newPNodeConfig_ ) + { + prevPNodeConfig_ = CPNodeConfigContainer::AddPNodeConfig( pnodeConfigInfo ); + newPNodeConfig_ = false; + } + prevLNodeConfig_ = CLNodeConfigContainer::AddLNodeConfig( prevPNodeConfig_ + , lnodeConfigInfo ); + + TRACE_EXIT; +} + +void CClusterConfig::AddSNodeConfiguration( pnodeConfigInfo_t &pnodeConfigInfo ) +{ + const char method_name[] = "CClusterConfig::AddSNodeConfiguration"; + TRACE_ENTRY; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf( "%s@%d pnid=%d, nodename=%s\n" + , method_name, __LINE__ + , pnodeConfigInfo.pnid + , pnodeConfigInfo.nodename ); + } + + if ( newPNodeConfig_ ) + { + prevPNodeConfig_ = CPNodeConfigContainer::AddPNodeConfig( pnodeConfigInfo ); + prevPNodeConfig_->SetSpareList( pnodeConfigInfo.sparePNid + , pnodeConfigInfo.spareCount ); + newPNodeConfig_ = false; + } + + TRACE_EXIT; +} + +void CClusterConfig::AddPersistConfiguration( persistConfigInfo_t &persistConfigInfo ) +{ + const char method_name[] = "CClusterConfig::AddPersistConfiguration"; + TRACE_ENTRY; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf( "%s@%d persistkey=%s\n" + , method_name, __LINE__ + , persistConfigInfo.persistPrefix ); + } + + prevPersistConfig_ = CPersistConfigContainer::AddPersistConfig( persistConfigInfo ); + + TRACE_EXIT; +} + +bool CClusterConfig::DeleteNodeConfig( int pnid ) +{ + const char method_name[] = "CClusterConfig::DeleteNodeConfig"; + TRACE_ENTRY; + + bool rs = true; + int rc; + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d deleting (pnid=%d), pnodesCount=%d, lnodesCount=%d\n" + , method_name, __LINE__ + , pnid + , GetPNodesCount() + , GetLNodesCount() ); + } + + // Delete logical and physical nodes from the configuration database + + rc = tc_delete_node( pnid, NULL ); + if ( rc == 0 ) + { + // Delete logical and physical nodes from configuration objects + CPNodeConfig *pnodeConfig = GetPNodeConfig( pnid ); + if (pnodeConfig) + { + + CLNodeConfig *lnodeConfig = pnodeConfig->GetFirstLNodeConfig(); + while ( lnodeConfig ) + { + // Delete logical nodes unique strings from the configuration database + rc = tc_delete_unique_strings( lnodeConfig->GetNid() ); + if ( rc ) + { + rs = false; + break; + } + DeleteLNodeConfig( lnodeConfig ); + lnodeConfig = pnodeConfig->GetFirstLNodeConfig(); + } + + if (rs) + { + DeletePNodeConfig( pnodeConfig ); + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d deleted (pnid=%d), pnodesCount=%d, lnodesCount=%d\n" + , method_name, __LINE__ + , pnid + , GetPNodesCount() + , GetLNodesCount() ); + } + } + } + } + else + { + char buf[TC_LOG_BUF_SIZE]; + snprintf( buf, sizeof(buf), "[%s] Node delete failed, pnid=%d\n", + method_name, pnid ); + TcLogWrite( MON_CLUSTERCONF_DELETENODE_1, TC_LOG_ERR, buf ); + rs = false; + } + + TRACE_EXIT; + return( rs ); +} + +// The following method maps the 'sqconfig' text file persist section's +// <persist-key>_PROCESS_TYPE string value to the internal +// TC_PROCESS_TYPE enum value +TC_PROCESS_TYPE CClusterConfig::GetProcessType( const char *processtype ) +{ + if (strcmp( "DTM", processtype) == 0) + { + return(ProcessType_DTM); + } + else if (strcmp( "GENERIC", processtype) == 0) + { + return(ProcessType_Generic); + } + else if (strcmp( "WDG", processtype) == 0) + { + return(ProcessType_Watchdog); + } + else if (strcmp( "MXOSRVR", processtype) == 0) + { + return(ProcessType_MXOSRVR); + } + else if (strcmp( "SPX", processtype) == 0) + { + return(ProcessType_SPX); + } + else if (strcmp( "SSMP", processtype) == 0) + { + return(ProcessType_SSMP); + } + else if (strcmp( "PSD", processtype) == 0) + { + return(ProcessType_PSD); + } + else if (strcmp( "SMS", processtype) == 0) + { + return(ProcessType_SMS); + } + else if (strcmp( "TMID", processtype) == 0) + { + return(ProcessType_TMID); + } + else if (strcmp( "PERSIST", processtype) == 0) + { + return(ProcessType_PERSIST); + } + + return(ProcessType_Undefined); +} + +bool CClusterConfig::Initialize( void ) +{ + return( Initialize( false, NULL ) ); +} + +bool CClusterConfig::Initialize( bool traceEnabled, const char *traceFile ) +{ + const char method_name[] = "CClusterConfig::Initialize"; + TRACE_ENTRY; + + if ( trafConfigInitialized_ ) + { + // Already initialized + return( true ); + } + + int rc = tc_initialize( traceEnabled, traceFile ); + if ( rc ) + { + char la_buf[TC_LOG_BUF_SIZE]; + snprintf( la_buf, sizeof(la_buf) + , "[%s], Can't initialize configuration!\n" + , method_name ); + TcLogWrite( MON_CLUSTERCONF_INIT_1, TC_LOG_CRIT, la_buf ); + return( false ); + } + + trafConfigInitialized_ = true; + trafConfigStorageType_ = tc_get_storage_type(); + + TRACE_EXIT; + return( true ); +} + +void CClusterConfig::InitCoreMask( cpu_set_t &coreMask ) +{ + CPU_ZERO( &coreMask ); +} + +bool CClusterConfig::LoadConfig( void ) +{ + const char method_name[] = "CClusterConfig::LoadConfig"; + TRACE_ENTRY; + + if ( LoadNodeConfig() ) + { + LoadPersistConfig(); + } + + TRACE_EXIT; + return( nodeReady_ && persistReady_ ); +} + +bool CClusterConfig::LoadNodeConfig( void ) +{ + const char method_name[] = "CClusterConfig::LoadNodeConfig"; + TRACE_ENTRY; + + int rc; + int nodeCount = 0; + int snodeCount = 0; + node_configuration_t nodeConfigData[TC_NODES_MAX]; + physical_node_configuration_t spareNodeConfigData[TC_SPARE_NODES_MAX]; + pnodeConfigInfo_t pnodeConfigInfo; + lnodeConfigInfo_t lnodeConfigInfo; + + rc = tc_get_nodes( &nodeCount + , TC_NODES_MAX + , nodeConfigData ); + if ( rc ) + { + char la_buf[TC_LOG_BUF_SIZE]; + snprintf( la_buf, sizeof(la_buf) + , "[%s] Node configuration access failed!\n" + , method_name ); + TcLogWrite(MON_CLUSTERCONF_LOADNODE_1, TC_LOG_CRIT, la_buf); + return( false ); + } + + // Process logical nodes + for (int i =0; i < nodeCount; i++ ) + { + ProcessLNode( nodeConfigData[i], pnodeConfigInfo, lnodeConfigInfo ); + AddNodeConfiguration( pnodeConfigInfo, lnodeConfigInfo ); + } + + rc = tc_get_snodes( &snodeCount + , TC_NODES_MAX + , spareNodeConfigData ); + if ( rc ) + { + char la_buf[TC_LOG_BUF_SIZE]; + snprintf( la_buf, sizeof(la_buf) + , "[%s] Node configuration access failed!\n" + , method_name ); + TcLogWrite(MON_CLUSTERCONF_LOADNODE_2, TC_LOG_CRIT, la_buf); + return( false ); + } + + // Process spare nodes + for (int i =0; i < snodeCount; i++ ) + { + ProcessSNode( spareNodeConfigData[i], pnodeConfigInfo ); + AddSNodeConfiguration( pnodeConfigInfo ); + } + + nodeReady_ = true; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + if ( nodeReady_ ) + trace_printf("%s@%d - Successfully loaded node configuration\n", method_name, __LINE__); + else + trace_printf("%s@%d - Failed to load node configuration\n", method_name, __LINE__); + } + + TRACE_EXIT; + return( nodeReady_ ); +} + +bool CClusterConfig::LoadPersistConfig( void ) +{ + const char method_name[] = "CClusterConfig::LoadPersistConfig"; + TRACE_ENTRY; + + int rc; + + // Get persistent process keys + char persistProcessKeys[TC_PERSIST_KEYS_VALUE_MAX]; + rc = tc_get_persist_keys( persistProcessKeys ); + if ( rc ) + { + char la_buf[TC_LOG_BUF_SIZE]; + snprintf( la_buf, sizeof(la_buf) + , "[%s] Persist keys configuration access failed!\n" + , method_name ); + TcLogWrite(MON_CLUSTERCONF_LOADPERSIST_1, TC_LOG_CRIT, la_buf); + return( false ); + } + + persist_configuration_t persistConfig; + persistConfigInfo_t persistConfigInfo; + pkeysVector_t pkeysVector; // vector of persist prefix strings + + // Initialize vector of persistent keys + CPersistConfigContainer::InitializePersistKeys( persistProcessKeys + , pkeysVector ); + if ( CPersistConfigContainer::GetPersistKeysCount() == 0 ) + { + char la_buf[TC_LOG_BUF_SIZE]; + snprintf( la_buf, sizeof(la_buf) + , "[%s] Invalid PERSIST_PROCESS_KEYS value, %s\n" + , method_name, persistProcessKeys ); + TcLogWrite(MON_CLUSTERCONF_LOADPERSIST_2, TC_LOG_CRIT, la_buf); + return( false ); + } + + pkeysVector_t::iterator pkit; + + // Process each prefix in the vector + for (pkit = pkeysVector.begin(); pkit < pkeysVector.end(); pkit++ ) + { + memset( &persistConfig, 0, sizeof(persist_configuration_t) ); + memset( &persistConfigInfo, 0, sizeof(persistConfigInfo_t) ); + strncpy( persistConfig.persist_prefix + , pkit->c_str() + , sizeof(persistConfig.persist_prefix)); + rc = tc_get_persist_process( pkit->c_str(), &persistConfig ); + if ( rc ) + { + char la_buf[TC_LOG_BUF_SIZE]; + snprintf( la_buf, sizeof(la_buf) + , "[%s] Persist process info for prefix key %s does not exist!\n" + , method_name, pkit->c_str() ); + TcLogWrite(MON_CLUSTERCONF_LOADPERSIST_3, TC_LOG_CRIT, la_buf); + return( false ); + } + + ProcessPersistInfo( persistConfig, persistConfigInfo ); + AddPersistConfiguration( persistConfigInfo ); + } + + persistReady_ = true; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + if ( persistReady_ ) + trace_printf("%s@%d - Successfully loaded persist configuration\n", method_name, __LINE__); + else + trace_printf("%s@%d - Failed to load persist configuration\n", method_name, __LINE__); + } + + TRACE_EXIT; + return( persistReady_ ); +} + +void CClusterConfig::ProcessLNode( node_configuration_t &nodeConfigData + , pnodeConfigInfo_t &pnodeConfigInfo + , lnodeConfigInfo_t &lnodeConfigInfo ) +{ + const char method_name[] = "CClusterConfig::ProcessLNode"; + TRACE_ENTRY; + + bool excludedCores = false; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf( "%s@%d nid=%d, pnid=%d, name=%s, excluded cores=(%d:%d)," + " cores=(%d:%d), processors=%d, roles=%d\n" + , method_name, __LINE__ + , nodeConfigData.nid + , nodeConfigData.pnid + , nodeConfigData.node_name + , nodeConfigData.excluded_first_core + , nodeConfigData.excluded_last_core + , nodeConfigData.first_core + , nodeConfigData.last_core + , nodeConfigData.processors + , nodeConfigData.roles ); + } + + newPNodeConfig_ = ((prevPNodeConfig_ == NULL) || + (nodeConfigData.pnid != prevPNodeConfig_->GetPNid())) + ? true : false; + if ( newPNodeConfig_ ) + { + memset( &pnodeConfigInfo, 0, sizeof(pnodeConfigInfo) ); + pnodeConfigInfo.pnid = nodeConfigData.pnid; + strncpy( pnodeConfigInfo.nodename + , nodeConfigData.node_name + , sizeof(pnodeConfigInfo.nodename) ); + pnodeConfigInfo.excludedFirstCore = nodeConfigData.excluded_first_core; + pnodeConfigInfo.excludedLastCore = nodeConfigData.excluded_last_core; + excludedCores = (nodeConfigData.excluded_first_core != -1 || + nodeConfigData.excluded_last_core != -1) + ? true : false; + if ( excludedCores ) + { + SetCoreMask( nodeConfigData.excluded_first_core + , nodeConfigData.excluded_last_core + , pnodeConfigInfo.excludedCoreMask ); + } + else + { + InitCoreMask( pnodeConfigInfo.excludedCoreMask ); + } + } + + lnodeConfigInfo.nid = nodeConfigData.nid; + lnodeConfigInfo.pnid = nodeConfigData.pnid; + strncpy( lnodeConfigInfo.nodename + , nodeConfigData.node_name + , sizeof(lnodeConfigInfo.nodename) ); + lnodeConfigInfo.firstCore = nodeConfigData.first_core; + lnodeConfigInfo.lastCore = nodeConfigData.last_core; + SetCoreMask( nodeConfigData.first_core + , nodeConfigData.last_core + , lnodeConfigInfo.coreMask ); + lnodeConfigInfo.processor = nodeConfigData.processors; + lnodeConfigInfo.zoneType = static_cast<TC_ZONE_TYPE>(nodeConfigData.roles); + + TRACE_EXIT; +} + +void CClusterConfig::ProcessSNode( physical_node_configuration_t &pnodeConfig + , pnodeConfigInfo_t &pnodeConfigInfo ) +{ + const char method_name[] = "CClusterConfig::ProcessSNode"; + TRACE_ENTRY; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf( "%s@%d pnid=%d, name=%s, excluded cores=(%d:%d), " + "spareCount=%d\n" + , method_name, __LINE__ + , pnodeConfig.pnid + , pnodeConfig.node_name + , pnodeConfig.excluded_first_core + , pnodeConfig.excluded_last_core + , pnodeConfig.spare_count + ); + } + + newPNodeConfig_ = (pnodeConfig.pnid != prevPNodeConfig_->GetPNid()) + ? true : false; + if ( newPNodeConfig_ ) + { + strncpy( pnodeConfigInfo.nodename + , pnodeConfig.node_name + , sizeof(pnodeConfigInfo.nodename) ); + + bool excludedCores = (pnodeConfig.excluded_first_core != -1 || + pnodeConfig.excluded_last_core != -1) + ? true : false; + if ( excludedCores ) + { + SetCoreMask( pnodeConfig.excluded_first_core + , pnodeConfig.excluded_last_core + , pnodeConfigInfo.excludedCoreMask ); + } + + memset( pnodeConfigInfo.sparePNid, 255, sizeof(pnodeConfigInfo.sparePNid) ); + + pnodeConfigInfo.spareCount = pnodeConfig.spare_count; + for (int i = 0; i < pnodeConfigInfo.spareCount ; i++ ) + { + pnodeConfigInfo.sparePNid[i] = pnodeConfig.spare_pnid[i]; + } + } + + TRACE_EXIT; +} + +void CClusterConfig::ProcessPersistInfo( persist_configuration_t &persistConfig + , persistConfigInfo_t &persistConfigInfo ) +{ + const char method_name[] = "CClusterConfig::ProcessPersistInfo"; + TRACE_ENTRY; + + char workValue[TC_PERSIST_VALUE_MAX]; + char *token1; + char *token2; + static const char *delimPercent = "%"; + static int chPercent = '%'; + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf( "%s@%d Processing persist info for persistKey=%s\n" + , method_name, __LINE__ + , persistConfig.persist_prefix ); + } + + strncpy( persistConfigInfo.persistPrefix + , persistConfig.persist_prefix + , sizeof(persistConfigInfo.persistPrefix) ); + + strncpy( workValue, persistConfig.process_name, sizeof(workValue) ); + if (strlen(workValue)) + { + // Extract name prefix + token1 = strtok( workValue, delimPercent ); + if (token1) + { + strncpy( persistConfigInfo.processNamePrefix + , token1 + , sizeof(persistConfigInfo.processNamePrefix) ); + } + // Extract nid format + strncpy( workValue, persistConfig.process_name, sizeof(workValue) ); + token2 = strchr( workValue, chPercent ); + if (token2) + { + strncpy( persistConfigInfo.processNameFormat + , token2 + , sizeof(persistConfigInfo.processNameFormat) ); + } + } + + persistConfigInfo.processType = GetProcessType( persistConfig.process_type ); + + strncpy( persistConfigInfo.programName + , persistConfig.program_name + , sizeof(persistConfigInfo.programName) ); + + strncpy( persistConfigInfo.programArgs + , persistConfig.program_args + , sizeof(persistConfigInfo.programArgs) ); + + persistConfigInfo.requiresDTM = persistConfig.requires_DTM; + + strncpy( workValue, persistConfig.std_out, sizeof(workValue) ); + if (strlen(workValue)) + { + // Extract name prefix + token1 = strtok( workValue, delimPercent ); + if (token1) + { + strncpy( persistConfigInfo.stdoutPrefix + , token1 + , sizeof(persistConfigInfo.stdoutPrefix) ); + } + // Extract nid format + strncpy( workValue, persistConfig.std_out, sizeof(workValue) ); + token2 = strchr( workValue, chPercent ); + if (token2) + { + strncpy( persistConfigInfo.stdoutFormat + , token2 + , sizeof(persistConfigInfo.stdoutFormat) ); + } + } + + persistConfigInfo.persistRetries = persistConfig.persist_retries; + + persistConfigInfo.persistWindow = persistConfig.persist_window; + + strncpy( persistConfigInfo.zoneFormat + , persistConfig.persist_zones + , sizeof(persistConfigInfo.zoneFormat) ); + + TRACE_EXIT; +} + +bool CClusterConfig::SaveNodeConfig( const char *name + , int nid + , int pnid + , int firstCore + , int lastCore + , int processors + , int excludedFirstCore + , int excludedLastCore + , int roles ) +{ + const char method_name[] = "CClusterConfig::SaveNodeConfig"; + TRACE_ENTRY; + + bool rs = true; + int rc; + node_configuration_t nodeConfig; + pnodeConfigInfo_t pnodeConfigInfo; + lnodeConfigInfo_t lnodeConfigInfo; + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d Saving node config (node_name=%s, processors=%d, " + "roles=%d, firstCore=%d, lastCore=%d " + "excludedFirstCore=%d, excludedLastCore=%d)\n" + , method_name, __LINE__ + , name + , processors + , roles + , firstCore + , lastCore + , excludedFirstCore + , excludedLastCore ); + } + + nodeConfig.nid = nid; + nodeConfig.pnid = pnid; + strncpy( nodeConfig.node_name, name, sizeof(nodeConfig.node_name) ); + nodeConfig.excluded_first_core = excludedFirstCore; + nodeConfig.excluded_last_core = excludedLastCore; + nodeConfig.first_core = firstCore; + nodeConfig.last_core = lastCore; + nodeConfig.processors = processors; + nodeConfig.roles = roles; + + // Insert data into pnode and lnode tables + rc = tc_put_node( &nodeConfig ); + if ( rc == 0 ) + { + ProcessLNode( nodeConfig, pnodeConfigInfo, lnodeConfigInfo ); + // Add new logical and physical nodes to configuration objects + AddNodeConfiguration( pnodeConfigInfo, lnodeConfigInfo ); + } + else + { + rs = false; + char buf[TC_LOG_BUF_SIZE]; + snprintf( buf, sizeof(buf), "[%s] Node add failed, pnid=%d\n", + method_name, pnid ); + TcLogWrite( MON_CLUSTERCONF_SAVENODE_1, TC_LOG_ERR, buf ); + } + + TRACE_EXIT; + return( rs ); +} + +void CClusterConfig::SetCoreMask( int firstCore + , int lastCore + , cpu_set_t &coreMask ) +{ + CPU_ZERO( &coreMask ); + for (int i = firstCore; i < (lastCore+1) ; i++ ) + { + CPU_SET( i, &coreMask ); + } +} + +bool CClusterConfig::UpdatePNodeConfig( int pnid + , const char *name + , int excludedFirstCore + , int excludedLastCore ) +{ + const char method_name[] = "CClusterConfig::UpdatePNodeConfig"; + TRACE_ENTRY; + + bool rs = true; + int rc; + physical_node_configuration_t pnodeConfig; + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d Updating pnode config " + "(pnid=%d, node_name=%s, " + "excludedFirstCore=%d, excludedLastCore=%d)\n" + , method_name, __LINE__ + , pnid + , name + , excludedFirstCore + , excludedLastCore ); + } + + memset( &pnodeConfig, 0, sizeof(physical_node_configuration_t) ); + pnodeConfig.pnid = pnid; + strncpy( pnodeConfig.node_name, name, sizeof(pnodeConfig.node_name) ); + pnodeConfig.excluded_first_core = excludedFirstCore; + pnodeConfig.excluded_last_core = excludedLastCore; + + // Update pnode table + rc = tc_put_pnode( &pnodeConfig ); + if ( rc == 0 ) + { + // Update physical node to configuration object + UpdatePNodeConfiguration( pnid + , name + , excludedFirstCore + , excludedLastCore ); + } + else + { + rs = false; + char buf[TC_LOG_BUF_SIZE]; + snprintf( buf, sizeof(buf) + , "[%s] PNode update failed, pnid=%d, node_name=%s\n" + , method_name, pnid, name ); + TcLogWrite( MON_CLUSTERCONF_UPDATEPNODECFG_1, TC_LOG_ERR, buf ); + } + + TRACE_EXIT; + return( rs ); +} + +void CClusterConfig::UpdatePNodeConfiguration( int pnid + , const char *name + , int excludedFirstCore + , int excludedLastCore ) +{ + const char method_name[] = "CClusterConfig::UpdatePNodeConfiguration"; + TRACE_ENTRY; + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d pnid=%d, name=%s, " + "excludedFirstCore=%d, excludedLastCore=%d\n" + , method_name, __LINE__ + , pnid + , name + , excludedFirstCore + , excludedLastCore ); + } + + CPNodeConfig *pnodeConfig = GetPNodeConfig( pnid ); + if ( pnodeConfig ) + { + pnodeConfig->SetName( name ); + pnodeConfig->SetExcludedFirstCore( excludedFirstCore ); + pnodeConfig->SetExcludedLastCore( excludedLastCore ); + } + + TRACE_EXIT; +} +
http://git-wip-us.apache.org/repos/asf/trafodion/blob/87849fcf/core/sqf/src/trafconf/clusterconf.h ---------------------------------------------------------------------- diff --git a/core/sqf/src/trafconf/clusterconf.h b/core/sqf/src/trafconf/clusterconf.h new file mode 100644 index 0000000..7061bbb --- /dev/null +++ b/core/sqf/src/trafconf/clusterconf.h @@ -0,0 +1,118 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CLUSTERCONF_H_ +#define CLUSTERCONF_H_ + +#include <stdlib.h> + +#include "lnodeconfig.h" +#include "pnodeconfig.h" +#include "persistconfig.h" + +class CClusterConfig : public CPNodeConfigContainer + , public CLNodeConfigContainer + , public CPersistConfigContainer +{ +public: + + CClusterConfig( void ); + ~CClusterConfig( void ); + + void Clear( void ); + bool DeleteNodeConfig( int pnid ); + bool Initialize( void ); + bool Initialize( bool traceEnabled, const char *traceFile ); + void InitCoreMask( cpu_set_t &coreMask ); + inline bool IsConfigReady( void ) { return( nodeReady_ && persistReady_ ); } + inline bool IsNodeReady( void ) { return( nodeReady_ ); } + inline bool IsPersistReady( void ) { return( persistReady_ ); } + inline TC_STORAGE_TYPE GetStorageType( void ) { return(trafConfigStorageType_); } + bool LoadConfig( void ); + bool LoadNodeConfig( void ); + bool LoadPersistConfig( void ); + bool SaveNodeConfig( const char *name + , int nid + , int pnid + , int firstCore + , int lastCore + , int processors + , int excludedFirstCore + , int excludedLastCore + , int roles ); + void SetCoreMask( int firstCore + , int lastCore + , cpu_set_t &coreMask ); + bool UpdatePNodeConfig( int pnid + , const char *name + , int excludedFirstCore + , int excludedLastCore ); + +protected: +private: + + bool nodeReady_; // true when node configuration loaded + bool persistReady_; // true when persist configuration loaded + bool newPNodeConfig_; + bool trafConfigInitialized_; + TC_STORAGE_TYPE trafConfigStorageType_; + CPNodeConfig *prevPNodeConfig_; + CLNodeConfig *prevLNodeConfig_; + CPersistConfig *prevPersistConfig_; + + void AddNodeConfiguration( pnodeConfigInfo_t &pnodeConfigInfo + , lnodeConfigInfo_t &lnodeConfigInfo ); + void AddSNodeConfiguration( pnodeConfigInfo_t &pnodeConfigInfo ); + void AddPersistConfiguration( persistConfigInfo_t &persistConfigInfo ); + bool DeleteDbNodeData( int pnid ); + TC_PROCESS_TYPE GetProcessType( const char *processtype ); + void ProcessLNode( node_configuration_t &nodeConfig + , pnodeConfigInfo_t &pnodeConfigInfo + , lnodeConfigInfo_t &lnodeConfigInfo ); + void ProcessSNode( physical_node_configuration_t &pnodeConfig + , pnodeConfigInfo_t &pnodeConfigInfo ); + void ProcessPersistInfo( persist_configuration_t &persistConfigData + , persistConfigInfo_t &persistConfigInfo ); + bool SaveDbLNodeData( int nid + , int pnid + , int firstCore + , int lastCore + , int processors + , int roles ); + bool SaveDbPNodeData( const char *name + , int pnid + , int excludedFirstCore + , int excludedLastCore ); + bool UpdateDbPNodeData( int pnid + , const char *name + , int excludedFirstCore + , int excludedLastCore ); + void UpdatePNodeConfiguration( int pnid + , const char *name + , int excludedFirstCore + , int excludedLastCore ); +}; + +#endif /* CLUSTERCONF_H_ */ http://git-wip-us.apache.org/repos/asf/trafodion/blob/87849fcf/core/sqf/src/trafconf/lnodeconfig.cpp ---------------------------------------------------------------------- diff --git a/core/sqf/src/trafconf/lnodeconfig.cpp b/core/sqf/src/trafconf/lnodeconfig.cpp new file mode 100644 index 0000000..70af102 --- /dev/null +++ b/core/sqf/src/trafconf/lnodeconfig.cpp @@ -0,0 +1,397 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ +// +/////////////////////////////////////////////////////////////////////////////// + +using namespace std; + +#include <errno.h> +#include <string.h> +#include <assert.h> +#include <sched.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <iostream> +#include "tclog.h" +#include "tctrace.h" +#include "pnodeconfig.h" +#include "lnodeconfig.h" + + +/////////////////////////////////////////////////////////////////////////////// +// Logical Node Configuration +/////////////////////////////////////////////////////////////////////////////// + +CLNodeConfig::CLNodeConfig( CPNodeConfig *pnodeConfig + , lnodeConfigInfo_t &lnodeConfigInfo + ) + : nid_(lnodeConfigInfo.nid) + , zid_(pnodeConfig->GetPNid()) + , coreMask_(lnodeConfigInfo.coreMask) + , firstCore_(lnodeConfigInfo.firstCore) + , lastCore_(lnodeConfigInfo.lastCore) + , processors_(lnodeConfigInfo.processor) + , zoneType_(lnodeConfigInfo.zoneType) + , pnodeConfig_(pnodeConfig) + , next_(NULL) + , prev_(NULL) + , nextP_(NULL) + , prevP_(NULL) +{ + const char method_name[] = "CLNodeConfig::CLNodeConfig"; + TRACE_ENTRY; + + pnodeConfig_->AddLNodeConfigP( this ); + + TRACE_EXIT; +} + +CLNodeConfig::~CLNodeConfig( void ) +{ + const char method_name[] = "CLNodeConfig::~CLNodeConfig"; + TRACE_ENTRY; + + pnodeConfig_->RemoveLNodeConfigP( this ); + + TRACE_EXIT; +} + +const char *CLNodeConfig::GetName( void ) +{ + return( pnodeConfig_->GetName() ); +} + +int CLNodeConfig::GetPNid( void ) +{ + return( pnodeConfig_->GetPNid() ); +} + +CLNodeConfigContainer::CLNodeConfigContainer( void ) + : lnodesCount_(0) + , nextNid_(-1) + , lnodesConfigMax_(0) + , lnodesConfig_(NULL) + , head_(NULL) + , tail_(NULL) +{ + const char method_name[] = "CLNodeConfigContainer::CLNodeConfigContainer"; + TRACE_ENTRY; + + TRACE_EXIT; +} + +CLNodeConfigContainer::CLNodeConfigContainer( int lnodesConfigMax ) + : lnodesCount_(0) + , nextNid_(0) + , lnodesConfigMax_(lnodesConfigMax) + , lnodesConfig_(NULL) + , head_(NULL) + , tail_(NULL) +{ + const char method_name[] = "CLNodeConfigContainer::CLNodeConfigContainer"; + TRACE_ENTRY; + + lnodesConfig_ = new CLNodeConfig *[lnodesConfigMax_]; + + if ( ! lnodesConfig_ ) + { + int err = errno; + char la_buf[TC_LOG_BUF_SIZE]; + sprintf(la_buf, "[%s], Error: Can't allocate logical node configuration array - errno=%d (%s)\n", method_name, err, strerror(errno)); + TcLogWrite(MON_LNODECONF_CONSTR_1, TC_LOG_CRIT, la_buf); + } + else + { + // Initialize array + for ( int i = 0; i < lnodesConfigMax_ ;i++ ) + { + lnodesConfig_[i] = NULL; + } + } + + TRACE_EXIT; +} + +CLNodeConfigContainer::~CLNodeConfigContainer(void) +{ + CLNodeConfig *lnodeConfig = head_; + + const char method_name[] = "CLNodeConfigContainer::~CLNodeConfigContainer"; + TRACE_ENTRY; + + // Only the main container builds the array of + // logical node configuration objects. + // The logical nodes container in a physical node configuration object + // only stores the configured logical nodes it hosts. + if ( lnodesConfig_ ) + { // This is the main container + // Delete entries + while ( head_ ) + { + DeleteLNodeConfig( lnodeConfig ); + lnodeConfig = head_; + } + + // Delete array + delete [] lnodesConfig_; + } + + TRACE_EXIT; +} + +void CLNodeConfigContainer::Clear( void ) +{ + const char method_name[] = "CLNodeConfigContainer::Clear"; + TRACE_ENTRY; + + CLNodeConfig *lnodeConfig = head_; + + // Only the main container builds the array of + // logical node configuration objects. + // The logical nodes container in a physical node configuration object + // only stores the configured logical nodes it hosts. + if ( lnodesConfig_ ) + { + while ( head_ ) + { + DeleteLNodeConfig( lnodeConfig ); + lnodeConfig = head_; + } + + // Initialize array + for ( int i = 0; i < lnodesConfigMax_; i++ ) + { + lnodesConfig_[i] = NULL; + } + } + + lnodesCount_ = 0; + nextNid_ = 0; + head_ = NULL; + tail_ = NULL; + + TRACE_EXIT; +} + +CLNodeConfig *CLNodeConfigContainer::AddLNodeConfigP( CLNodeConfig *lnodeConfig ) +{ + const char method_name[] = "CLNodeConfigContainer::AddLNodeConfig"; + TRACE_ENTRY; + + assert( lnodeConfig != NULL ); + + if ( lnodeConfig ) + { + lnodesCount_++; + // Add it to the container list + if ( head_ == NULL ) + { + head_ = tail_ = lnodeConfig; + } + else + { + //tail_ = tail_->LinkP( entry ); + tail_->nextP_ = lnodeConfig; + lnodeConfig->prevP_ = tail_; + tail_ = lnodeConfig; + } + } + + TRACE_EXIT; + return( lnodeConfig ); +} + +CLNodeConfig *CLNodeConfigContainer::AddLNodeConfig( CPNodeConfig *pnodeConfig + , lnodeConfigInfo_t &lnodeConfigInfo + ) +{ + const char method_name[] = "CLNodeConfigContainer::AddLNodeConfig"; + TRACE_ENTRY; + + // nid list is NOT sequential from zero + if ( ! (lnodeConfigInfo.nid >= 0 && lnodeConfigInfo.nid < lnodesConfigMax_) ) + { + char la_buf[TC_LOG_BUF_SIZE]; + sprintf( la_buf, "[%s], Error: Invalid nid=%d - should be >= 0 and < %d)\n" + , method_name, lnodeConfigInfo.nid, lnodesConfigMax_); + TcLogWrite(MON_LNODECONF_ADD_LNODE_1, TC_LOG_CRIT, la_buf); + return( NULL ); + } + + assert( lnodesConfig_[lnodeConfigInfo.nid] == NULL ); + + CLNodeConfig *lnodeConfig = new CLNodeConfig( pnodeConfig + , lnodeConfigInfo ); + if (lnodeConfig) + { + // Bump the logical node count + lnodesCount_++; + // Add it to the array + lnodesConfig_[lnodeConfigInfo.nid] = lnodeConfig; + // Add it to the container list + if ( head_ == NULL ) + { + head_ = tail_ = lnodeConfig; + } + else + { + tail_->next_ = lnodeConfig; + lnodeConfig->prev_ = tail_; + tail_ = lnodeConfig; + } + + // Set the next available nid + nextNid_ = (lnodeConfigInfo.nid == nextNid_) ? (lnodeConfigInfo.nid+1) : nextNid_ ; + if ( nextNid_ == lnodesConfigMax_ ) + { // We are at the limit, search for unused nid from begining + nextNid_ = -1; + for (int i = 0; i < lnodesConfigMax_; i++ ) + { + if ( lnodesConfig_[i] == NULL ) + { + nextNid_ = i; + break; + } + } + } + else if ( lnodesConfig_[nextNid_] != NULL ) + { // nid is in use + int next = ((nextNid_ + 1) < lnodesConfigMax_) ? nextNid_ + 1 : 0 ; + nextNid_ = -1; + for (int i = next; i < lnodesConfigMax_; i++ ) + { + if ( lnodesConfig_[i] == NULL ) + { + nextNid_ = i; + break; + } + } + } + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d - Added logical node configuration object\n" + " (nid=%d, pnid=%d, nextNid_=%d)\n" + " (lnodesCount_=%d,lnodesConfigMax=%d)\n" + , method_name, __LINE__ + , lnodeConfigInfo.nid, pnodeConfig->GetPNid(), nextNid_ + , lnodesCount_, lnodesConfigMax_); + } + } + else + { + int err = errno; + char la_buf[TC_LOG_BUF_SIZE]; + sprintf( la_buf, "[%s], Error: Can't allocate logical node configuration object - errno=%d (%s)\n" + , method_name, err, strerror(errno)); + TcLogWrite(MON_LNODECONF_ADD_LNODE_2, TC_LOG_ERR, la_buf); + } + + TRACE_EXIT; + return( lnodeConfig ); +} + +void CLNodeConfigContainer::DeleteLNodeConfig( CLNodeConfig *lnodeConfig ) +{ + const char method_name[] = "CLNodeConfigContainer::DeleteLNodeConfig"; + TRACE_ENTRY; + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d Deleting nid=%d, nextNid_=%d\n" + , method_name, __LINE__ + , lnodeConfig->GetNid() + , nextNid_ ); + } + + int nid = lnodeConfig->GetNid(); + lnodesConfig_[nid] = NULL; + + if ( head_ == lnodeConfig ) + head_ = lnodeConfig->next_; + if ( tail_ == lnodeConfig ) + tail_ = lnodeConfig->prev_; + if ( lnodeConfig->prev_ ) + lnodeConfig->prev_->next_ = lnodeConfig->next_; + if ( lnodeConfig->next_ ) + lnodeConfig->next_->prev_ = lnodeConfig->prev_; + delete lnodeConfig; + + // Decrement the logical node count + lnodesCount_--; + + if ( nextNid_ == -1 ) + { // We are at the limit, use the deleted nid as the next available + nextNid_ = nid; + } + else if ( nextNid_ > nid ) + { // Always use the lower nid value + nextNid_ = nid; + } + + if (TcTraceSettings & (TC_TRACE_INIT | TC_TRACE_REQUEST)) + { + trace_printf( "%s@%d - Deleted logical node configuration object\n" + " (nid=%d, nextNid_=%d)\n" + " (lnodesCount_=%d,lnodesConfigMax=%d)\n" + , method_name, __LINE__ + , nid, nextNid_ + , lnodesCount_, lnodesConfigMax_); + } + + TRACE_EXIT; +} + +CLNodeConfig *CLNodeConfigContainer::GetLNodeConfig( int nid ) +{ + const char method_name[] = "CLNodeConfigContainer::GetLNodeConfig"; + TRACE_ENTRY; + + CLNodeConfig *config = head_; + while (config) + { + if ( config->GetNid() == nid ) + { + break; + } + config = config->GetNext(); + } + + TRACE_EXIT; + return config; +} + +void CLNodeConfigContainer::RemoveLNodeConfigP( CLNodeConfig *lnodeConfig ) +{ + + if ( head_ == lnodeConfig ) + head_ = lnodeConfig->nextP_; + if ( tail_ == lnodeConfig ) + tail_ = lnodeConfig->prevP_; + if ( lnodeConfig->prevP_ ) + lnodeConfig->prevP_->nextP_ = lnodeConfig->nextP_; + if ( lnodeConfig->nextP_ ) + lnodeConfig->nextP_->prevP_ = lnodeConfig->prevP_; +} http://git-wip-us.apache.org/repos/asf/trafodion/blob/87849fcf/core/sqf/src/trafconf/lnodeconfig.h ---------------------------------------------------------------------- diff --git a/core/sqf/src/trafconf/lnodeconfig.h b/core/sqf/src/trafconf/lnodeconfig.h new file mode 100644 index 0000000..78e40cc --- /dev/null +++ b/core/sqf/src/trafconf/lnodeconfig.h @@ -0,0 +1,121 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef LNODECONFIG_H_ +#define LNODECONFIG_H_ + +#include "trafconf/trafconfig.h" + +typedef struct lnodeConfigInfo_s +{ + int nid; + int pnid; + char nodename[TC_PROCESSOR_NAME_MAX]; + int firstCore; + int lastCore; + cpu_set_t coreMask; + int processor; + TC_ZONE_TYPE zoneType; +} lnodeConfigInfo_t; + + +class CLNodeConfig; +class CPNodeConfig; + +class CLNodeConfigContainer +{ +public: + CLNodeConfigContainer( void ); + CLNodeConfigContainer( int lnodesConfigMax ); + ~CLNodeConfigContainer( void ); + CLNodeConfig *AddLNodeConfig( CPNodeConfig *pnodeConfig + , lnodeConfigInfo_t &lnodeConfigInfo ); + CLNodeConfig *AddLNodeConfigP( CLNodeConfig *lnodeConfig ); + void Clear( void ); + void DeleteLNodeConfig( CLNodeConfig *lnodeConfig ); + void RemoveLNodeConfigP( CLNodeConfig *lnodeConfig ); + inline CLNodeConfig *GetFirstLNodeConfig( void ) { return ( head_ ); } + inline int GetNextNid( void ) { return ( nextNid_ ); } + CLNodeConfig *GetLNodeConfig( int nid ); + inline int GetLNodesConfigMax( void ) { return ( lnodesConfigMax_ ); } + inline int GetLNodesCount( void ) { return ( lnodesCount_ ); } + +protected: + int lnodesCount_; // # of logical nodes + int nextNid_; // next logical node id available + +private: + int lnodesConfigMax_; // maximum number of logical nodes + CLNodeConfig **lnodesConfig_; // array of all logical nodes + + CLNodeConfig *head_; // head of logical nodes linked list + CLNodeConfig *tail_; // tail of logical nodes linked list +}; + +class CLNodeConfig +{ + friend CLNodeConfig *CLNodeConfigContainer::AddLNodeConfig( CPNodeConfig *pnodeConfig + , lnodeConfigInfo_t &lnodeConfigInfo ); + friend CLNodeConfig *CLNodeConfigContainer::AddLNodeConfigP( CLNodeConfig *lnodeConfig ); + friend void CLNodeConfigContainer::DeleteLNodeConfig( CLNodeConfig *lnodeConfig ); + friend void CLNodeConfigContainer::RemoveLNodeConfigP( CLNodeConfig *lnodeConfig ); +public: + CLNodeConfig( CPNodeConfig *pnodeConfig + , lnodeConfigInfo_t &lnodeConfigInfo + ); + ~CLNodeConfig( void ); + + inline cpu_set_t &GetCoreMask( void ) { return( coreMask_ ); } + inline int GetFirstCore( void ) { return( firstCore_ ); } + inline int GetLastCore( void ) { return( lastCore_ ); } + const char *GetName( void ); + inline CLNodeConfig *GetNext( void ) { return( next_); } + inline CLNodeConfig *GetNextP( void ) { return( nextP_); } + inline int GetNid( void ) { return( nid_ ); } + inline int GetZid( void ) { return( zid_ ); } + int GetPNid( void ); + CPNodeConfig *GetPNodeConfig( void ) { return(pnodeConfig_); } + + inline int GetProcessors( void ) { return( processors_ ); } + inline TC_ZONE_TYPE GetZoneType( void ) { return( zoneType_ ); } + +protected: +private: + int nid_; // Logical Node Identifier + int zid_; // Zone Identifier + cpu_set_t coreMask_; // mask of SMP processor cores used by logical node + int firstCore_; // First SMP processor core used by logical node + int lastCore_; // Last SMP processor core used by logical node + int processors_; // # of logical processors in logical node + TC_ZONE_TYPE zoneType_; // type of zone + CPNodeConfig *pnodeConfig_; // logical node's current physical node + + CLNodeConfig *next_; // next LNodeConfig in CLNodeConfigContainer list + CLNodeConfig *prev_; // previous LNodeConfig in CLNodeConfigContainer list + CLNodeConfig *nextP_; // next LNodeConfig in pnodeConfig_ linked list + CLNodeConfig *prevP_; // prev LNodeConfig in pnodeConfig_ linked list +}; + +#endif /* LNODECONFIG_H_ */ http://git-wip-us.apache.org/repos/asf/trafodion/blob/87849fcf/core/sqf/src/trafconf/macros.gmk ---------------------------------------------------------------------- diff --git a/core/sqf/src/trafconf/macros.gmk b/core/sqf/src/trafconf/macros.gmk new file mode 100644 index 0000000..1e8a0dc --- /dev/null +++ b/core/sqf/src/trafconf/macros.gmk @@ -0,0 +1,112 @@ +# @@@ START COPYRIGHT @@@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# @@@ END COPYRIGHT @@@ + +# his allows logging +USE_LOGGING = 1 + +ifndef SQ_MTYPE + SQ_MTYPE = 32 +endif + +# Trafodion Configuration +#TCROOT = . +#INCTCDIR = -I$(TCROOT) + +# Seabed +SRCSBDIR = ../seabed/src + +INCMISCDIR += -I$(SRCSBDIR) + +# export +EXPROOT = $(TRAF_HOME)/export + +# tools +CXX += $(PHVERIF) +ifeq ($(SQ_MTYPE),32) + CC += -mpi32 + CXX += -mpi32 + ifeq ($(SQ_USE_INTC),0) + CC += -m32 + CXX += -m32 + endif +endif + +# flags +CFLAGS = $(DEFINES) $(SCOPEFLAGS) $(CWARN) $(DFLAG) $(COVER_FLGS) +CXXFLAGS = $(DEFINES) $(SCOPEFLAGS) $(CXXWARN) $(DFLAG) $(COVER_FLGS) +SCOPEFLAGS = $(CLOSED_SOURCE_GPP_OPTS) +DFLAG = -g3 $(OPTIM_FLGS) +DFLAG = -g3 +CFLAGS += -fPIC +CXXFLAGS += -fPIC +ifeq ($(SQ_USE_INTC),1) + # 177=variable "<variable>" was declared but never referenced + # 981=operands are evaluated in unspecified order + # 1418=external function definition with no prior declaration + # 1684=conversion from "long long" to "long" may lose significant bits + IOPTS = -Wall -Werror -wd177 -wd981 -wd1418 -wd1684 -Wcheck -Wp64 + IOPTSTEMP = -wd383 + CWARN = $(HPCWARN) $(IOPTS) + CXXWARN = $(HPCXXWARN) $(IOPTS) + # + ifeq ($(SQ_BUILD_TYPE),release) + DFLAG = -g -debug full $(OPTIM_FLGS) + else + DFLAG = -g + endif +else + # Gnu + GOPTS = -Wall -Wunused -Wextra -pedantic -Werror -Wno-long-long -Wconversion + ifeq ($(SQ_MTYPE),32) + GOPTS += -march=i686 + endif + CWARN = $(HPCWARN) $(GOPTS) + CXXWARN = $(HPCXXWARN) $(GOPTS) +endif + +INCLUDES = -I$(INCEXPDIR) $(INCMISCDIR) + +# cover +COVFILES = $(OUTDIR)/*.gcda $(OUTDIR)/*.gcno $(OUTDIR)/*.gcov *.gcda *.gcno *.gcov + +# Trafodion Configuration Library +LIBTRAFCONFIG = $(LIBEXPDIR)/libtrafconfig.so +LIBTRAFCONFIGX = -L$(LIBEXPDIR) -ltrafconfig + +# Trafodion Configuration Utility +TRAFCONF = $(BINEXPDIR)/trafconf + +# common rules +.c.o: + $(CC) $(CDEPFLAGS) $(CFLAGS) $(INCLUDES) -c $< + +.cpp.o: + $(CXX) $(CDEPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $< + +# common pattern rules +$(OUTDIR)/%.o: %.c + $(CC) $(CDEPFLAGS) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(OUTDIR)/%.o: %.cpp + $(CXX) $(CDEPFLAGS) $(CXXFLAGS) $(INCLUDES) -c -o $@ $< + +$(OUTDIR)/%.o: $(SRCSBDIR)/%.cpp + $(CXX) $(CXXFLAGS) $(INCLUDES) -c -o $@ $< http://git-wip-us.apache.org/repos/asf/trafodion/blob/87849fcf/core/sqf/src/trafconf/persistconfig.cpp ---------------------------------------------------------------------- diff --git a/core/sqf/src/trafconf/persistconfig.cpp b/core/sqf/src/trafconf/persistconfig.cpp new file mode 100644 index 0000000..4d4a880 --- /dev/null +++ b/core/sqf/src/trafconf/persistconfig.cpp @@ -0,0 +1,637 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// @@@ START COPYRIGHT @@@ +// +// (C) Copyright 2015 Hewlett Packard Enterprise Development LP +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// @@@ END COPYRIGHT @@@ +// +/////////////////////////////////////////////////////////////////////////////// + +using namespace std; + +#include <errno.h> +#include <string.h> +#include "tclog.h" +#include "tctrace.h" +#include "persistconfig.h" + +const char *PersistProcessTypeString( TC_PROCESS_TYPE type ) +{ + const char *str; + + switch( type ) + { + case ProcessType_TSE: + str = "TSE"; + break; + case ProcessType_DTM: + str = "DTM"; + break; + case ProcessType_ASE: + str = "ASE"; + break; + case ProcessType_Generic: + str = "GENERIC"; + break; + case ProcessType_Watchdog: + str = "WDG"; + break; + case ProcessType_AMP: + str = "AMP"; + break; + case ProcessType_Backout: + str = "BO"; + break; + case ProcessType_VolumeRecovery: + str = "VR"; + break; + case ProcessType_MXOSRVR: + str = "MXOSRVR"; + break; + case ProcessType_SPX: + str = "SPX"; + break; + case ProcessType_SSMP: + str = "SSMP"; + break; + case ProcessType_PSD: + str = "PSD"; + break; + case ProcessType_SMS: + str = "SMS"; + break; + case ProcessType_TMID: + str = "TMID"; + break; + case ProcessType_PERSIST: + str = "PERSIST"; + break; + default: + str = "Undefined"; + break; + } + + return( str ); +} + +const char *ProcessTypeString( TC_PROCESS_TYPE type ) +{ + const char *str; + + switch( type ) + { + case ProcessType_Undefined: + str = "ProcessType_Undefined"; + break; + case ProcessType_TSE: + str = "ProcessType_TSE"; + break; + case ProcessType_DTM: + str = "ProcessType_DTM"; + break; + case ProcessType_ASE: + str = "ProcessType_ASE"; + break; + case ProcessType_Generic: + str = "ProcessType_Generic"; + break; + case ProcessType_Watchdog: + str = "ProcessType_Watchdog"; + break; + case ProcessType_AMP: + str = "ProcessType_AMP"; + break; + case ProcessType_Backout: + str = "ProcessType_Backout"; + break; + case ProcessType_VolumeRecovery: + str = "ProcessType_VolumeRecovery"; + break; + case ProcessType_MXOSRVR: + str = "ProcessType_MXOSRVR"; + break; + case ProcessType_SPX: + str = "ProcessType_SPX"; + break; + case ProcessType_SSMP: + str = "ProcessType_SSMP"; + break; + case ProcessType_PSD: + str = "ProcessType_PSD"; + break; + case ProcessType_SMS: + str = "ProcessType_SMS"; + break; + case ProcessType_TMID: + str = "ProcessType_TMID"; + break; + case ProcessType_PERSIST: + str = "ProcessType_PERSIST"; + break; + default: + str = "ProcessType_Invalid"; + } + + return( str ); +} + +const char *FormatNidString( FormatNid_t type ) +{ + const char *str; + + switch( type ) + { + case Nid_ALL: + str = "Nid_ALL"; + break; + case Nid_RELATIVE: + str = "Nid_RELATIVE"; + break; + default: + str = "Nid_Undefined"; + } + + return( str ); +} + +const char *FormatZidString( FormatZid_t type ) +{ + const char *str; + + switch( type ) + { + case Zid_ALL: + str = "Zid_ALL"; + break; + case Zid_RELATIVE: + str = "Zid_RELATIVE"; + break; + default: + str = "Zid_Undefined"; + } + + return( str ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Persistent Process Configuration +/////////////////////////////////////////////////////////////////////////////// + +CPersistConfig::CPersistConfig( persistConfigInfo_t &persistConfigInfo ) + : persistPrefix_(persistConfigInfo.persistPrefix) + , processName_("") + , processNamePrefix_(persistConfigInfo.processNamePrefix) + , processNameFormat_(persistConfigInfo.processNameFormat) + , stdoutFile_("") + , stdoutPrefix_(persistConfigInfo.stdoutPrefix) + , stdoutFormat_(persistConfigInfo.stdoutFormat) + , programName_(persistConfigInfo.programName) + , programArgs_(persistConfigInfo.programArgs) + , zoneFormat_(persistConfigInfo.zoneFormat) + , processType_(persistConfigInfo.processType) + , processNameNidFormat_(Nid_Undefined) + , stdoutNidFormat_(Nid_Undefined) + , zoneZidFormat_(Zid_Undefined) + , requiresDTM_(persistConfigInfo.requiresDTM) + , persistRetries_(persistConfigInfo.persistRetries) + , persistWindow_(persistConfigInfo.persistWindow) + , programArgc_(0) + , programArgv_(NULL) + , programArgvLen_(0) + , next_(NULL) + , prev_(NULL) +{ + const char method_name[] = "CPersistConfig::CPersistConfig"; + TRACE_ENTRY; + + if (processNameFormat_.compare(TOKEN_NID_PLUS) == 0) + { + processNameNidFormat_ = Nid_ALL; + } + else + { + if (processNameFormat_.compare(TOKEN_NID) == 0) + { + processNameNidFormat_ = Nid_RELATIVE; + } + } + if (stdoutFormat_.compare(TOKEN_NID_PLUS) == 0) + { + stdoutNidFormat_ = Nid_ALL; + } + else + { + if (stdoutFormat_.compare(TOKEN_NID) == 0) + { + stdoutNidFormat_ = Nid_RELATIVE; + } + } + if (zoneFormat_.compare(TOKEN_ZID_PLUS) == 0) + { + zoneZidFormat_ = Zid_ALL; + } + else + { + if (zoneFormat_.compare(TOKEN_ZID) == 0) + { + zoneZidFormat_ = Zid_RELATIVE; + } + } + + char *token, *programArgs = NULL; + static const char *delim = " "; + stringVector_t argvVector; + + if (programArgs_.size()) + { + programArgs = new char [programArgs_.size()+100]; + memset(programArgs, 0, programArgs_.size()+100); + memcpy(programArgs, programArgs_.c_str(), programArgs_.size()); + + token = strtok( programArgs, delim ); + while (token != NULL) + { + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf("%s@%d Setting argvVector=%s\n", + method_name, __LINE__, token); + } + argvVector.push_back( token ); + token = strtok( NULL, delim ); + } + + programArgc_ = static_cast<int>(argvVector.size()); + + // Compute amount of space need to store argument strings + stringVector_t::iterator avit; + for (avit = argvVector.begin(); avit < argvVector.end(); avit++ ) + { + programArgvLen_ += static_cast<int>(strlen(avit->c_str()) + 1); + } + + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf( "%s@%d - Copying arguments " + "programArgc_=%d, programArgvLen_=%d\n" + , method_name, __LINE__ + , programArgc_, programArgvLen_); + } + + if (programArgvLen_ != 0) + { + programArgv_ = new char[programArgvLen_]; + if (programArgv_) + { + memset(programArgv_, 0, programArgvLen_); + char *pProgramArgv = programArgv_; + for (avit = argvVector.begin(); avit < argvVector.end(); avit++ ) + { + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf("%s@%d - prefix=%s, Copying argvVector='%s'\n" + , method_name, __LINE__ + , persistPrefix_.c_str(), avit->c_str()); + } + strcpy (pProgramArgv, avit->c_str()); + pProgramArgv += strlen(avit->c_str()) + 1; + } + } + } + } + + if (programArgs) delete [] programArgs; + + TRACE_EXIT; +} + +CPersistConfig::~CPersistConfig( void ) +{ + const char method_name[] = "CPersistConfig::~CPersistConfig"; + TRACE_ENTRY; + + if (programArgv_) delete [] programArgv_; + + TRACE_EXIT; +} + + +const char *CPersistConfig::GetProcessName( int nid ) +{ + const char method_name[] = "CPersistConfig::GetProcessName"; + TRACE_ENTRY; + + char nidStr[TC_PROCESSOR_NAME_MAX]; + + switch (processNameNidFormat_) + { + case Nid_ALL: + case Nid_RELATIVE: + if (nid == -1) + { + processName_ = processNamePrefix_; + } + else + { + sprintf( nidStr, "%d", nid ); + processName_ = processNamePrefix_ + nidStr; + } + break; + case Nid_Undefined: + processName_ = processNamePrefix_; + } + + if ( TcTraceSettings & (TC_TRACE_REQUEST | TC_TRACE_PROCESS)) + { + trace_printf( "%s@%d Process prefix=%s, name=%s, format=%s\n" + , method_name, __LINE__ + , processNamePrefix_.c_str() + , processName_.c_str() + , FormatNidString(processNameNidFormat_)); + } + + TRACE_EXIT; + return( processName_.c_str() ); +} + +const char *CPersistConfig::GetStdoutFile( int nid ) +{ + const char method_name[] = "CPersistConfig::GetStdoutFile"; + TRACE_ENTRY; + + char nidStr[TC_PROCESSOR_NAME_MAX]; + + switch (stdoutNidFormat_) + { + case Nid_ALL: + case Nid_RELATIVE: + if (nid == -1) + { + stdoutFile_ = stdoutPrefix_; + } + else + { + sprintf( nidStr, "%d", nid ); + stdoutFile_ = stdoutPrefix_ + nidStr; + } + break; + case Nid_Undefined: + stdoutFile_ = stdoutPrefix_; + } + + if ( TcTraceSettings & (TC_TRACE_REQUEST | TC_TRACE_PROCESS)) + { + trace_printf( "%s@%d stdout prefix=%s, file=%s, format=%s\n" + , method_name, __LINE__ + , stdoutPrefix_.c_str() + , stdoutFile_.c_str() + , FormatNidString(stdoutNidFormat_)); + } + + TRACE_EXIT; + return( stdoutFile_.c_str() ); +} + +bool CPersistConfig::IsPersistConfig( const char *processName, int nid ) +{ + const char method_name[] = "CPersistConfig:IsPersistConfig"; + TRACE_ENTRY; + + bool match = false; + + string name = GetProcessName( nid ); + if ( name.compare( processName ) == 0 ) + { + match = true; + } + + TRACE_EXIT; + return( match ); +} + +bool CPersistConfig::IsZoneMatch( int zid ) +{ + const char method_name[] = "CPersistConfig:IsZoneMatch"; + TRACE_ENTRY; + + bool match = false; + + switch (stdoutNidFormat_) + { + case Zid_ALL: + if (zid == -1) + { + match = false; + } + else + { + match = true; + } + break; + case Zid_RELATIVE: + if (zid == -1) + { + match = false; + } + else + { + match = true; + } + break; + case Zid_Undefined: + match = true; + break; + } + + TRACE_EXIT; + return( match ); +} + +CPersistConfigContainer::CPersistConfigContainer( void ) + : persistsCount_(0) + , head_(NULL) + , tail_(NULL) +{ + const char method_name[] = "CPersistConfigContainer::CPersistConfigContainer"; + TRACE_ENTRY; + + TRACE_EXIT; +} + +CPersistConfigContainer::~CPersistConfigContainer(void) +{ + CPersistConfig *persistConfig = head_; + + const char method_name[] = "CPersistConfigContainer::~CPersistConfigContainer"; + TRACE_ENTRY; + + while ( head_ ) + { + DeletePersistConfig( persistConfig ); + persistConfig = head_; + } + + pkeysVector_.clear(); + + TRACE_EXIT; +} + +void CPersistConfigContainer::Clear( void ) +{ + CPersistConfig *persistConfig = head_; + + const char method_name[] = "CPersistConfigContainer::Clear"; + TRACE_ENTRY; + + while ( head_ ) + { + DeletePersistConfig( persistConfig ); + persistConfig = head_; + } + + pkeysVector_.clear(); + + persistsCount_ = 0; + head_ = NULL; + tail_ = NULL; + + TRACE_EXIT; +} + +CPersistConfig *CPersistConfigContainer::AddPersistConfig( persistConfigInfo_t &persistConfigInfo ) +{ + const char method_name[] = "CPersistConfigContainer::AddPersistConfig"; + TRACE_ENTRY; + + CPersistConfig *persistConfig = new CPersistConfig( persistConfigInfo ); + if (persistConfig) + { + persistsCount_++; + // Add it to the container list + if ( head_ == NULL ) + { + head_ = tail_ = persistConfig; + } + else + { + tail_->next_ = persistConfig; + persistConfig->prev_ = tail_; + tail_ = persistConfig; + } + } + else + { + int err = errno; + char la_buf[TC_LOG_BUF_SIZE]; + sprintf(la_buf, "[%s], Error: Can't allocate persistent configuration " + "object - errno=%d (%s)\n" + , method_name, err, strerror(errno)); + TcLogWrite(MON_PERSISTCONFIG_ADDCONFIG_1, TC_LOG_ERR, la_buf); + } + + TRACE_EXIT; + return persistConfig; +} + +void CPersistConfigContainer::DeletePersistConfig( CPersistConfig *persistConfig ) +{ + + if ( head_ == persistConfig ) + head_ = persistConfig->next_; + if ( tail_ == persistConfig ) + tail_ = persistConfig->prev_; + if ( persistConfig->prev_ ) + persistConfig->prev_->next_ = persistConfig->next_; + if ( persistConfig->next_ ) + persistConfig->next_->prev_ = persistConfig->prev_; + delete persistConfig; +} + +CPersistConfig *CPersistConfigContainer::GetPersistConfig( const char *persistPrefix ) +{ + CPersistConfig *config = head_; + + const char method_name[] = "CPersistConfigContainer::GetPersistConfig"; + TRACE_ENTRY; + + while ( config ) + { + if (strcasecmp( config->GetPersistPrefix(), persistPrefix) == 0) + { + break; + } + config = config->GetNext(); + } + + TRACE_EXIT; + return config; +} + +CPersistConfig *CPersistConfigContainer::GetPersistConfig( TC_PROCESS_TYPE processType + , const char *processName + , int nid ) +{ + CPersistConfig *config = head_; + + const char method_name[] = "CPersistConfigContainer::GetPersistConfig"; + TRACE_ENTRY; + + while ( config ) + { + if (config->GetProcessType() == processType) + { + if ( TcTraceSettings & (TC_TRACE_REQUEST | TC_TRACE_PROCESS)) + { + trace_printf( "%s@%d Process type=%s, name=%s\n" + , method_name, __LINE__ + , PersistProcessTypeString(processType) + , processName); + } + if (config->IsPersistConfig( processName, nid )) + { + break; + } + } + config = config->GetNext(); + } + + TRACE_EXIT; + return config; +} + +void CPersistConfigContainer::InitializePersistKeys( char *persistkeys + , pkeysVector_t &pkeysVector ) +{ + const char method_name[] = "CPersistConfigContainer::InitializePersistKeys"; + TRACE_ENTRY; + + char *token; + static const char *delim = ", "; + + token = strtok( persistkeys, delim ); + while (token != NULL) + { + if ( TcTraceSettings & TC_TRACE_INIT ) + { + trace_printf("%s@%d Setting pkeysVector=%s\n", + method_name, __LINE__, token); + } + pkeysVector.push_back( token ); + pkeysVector_.push_back( token ); + token = strtok( NULL, " ," ); + } + + TRACE_EXIT; +} http://git-wip-us.apache.org/repos/asf/trafodion/blob/87849fcf/core/sqf/src/trafconf/persistconfig.h ---------------------------------------------------------------------- diff --git a/core/sqf/src/trafconf/persistconfig.h b/core/sqf/src/trafconf/persistconfig.h new file mode 100644 index 0000000..add6aa6 --- /dev/null +++ b/core/sqf/src/trafconf/persistconfig.h @@ -0,0 +1,164 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// @@@ START COPYRIGHT @@@ +// +// (C) Copyright 2015 Hewlett Packard Enterprise Development LP +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// @@@ END COPYRIGHT @@@ +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PERSISTCONFIG_H_ +#define PERSISTCONFIG_H_ + +#include <string> +#include <vector> +#include "trafconf/trafconfig.h" + +using namespace std; + +#define TOKEN_NID "%nid" +#define TOKEN_NID_PLUS "%nid+" +#define TOKEN_ZID "%zid" +#define TOKEN_ZID_PLUS "%zid+" + +typedef enum +{ + Nid_Undefined=0 + , Nid_ALL // %nid+ + , Nid_RELATIVE // %nid + //, Nid_SET // %nid[n,...] future? +} FormatNid_t; + +typedef enum +{ + Zid_Undefined=0 + , Zid_ALL // %zid+ + , Zid_RELATIVE // %zid + //, Zid_SET // %zid[n,...] future? +} FormatZid_t; + +typedef vector<string> pkeysVector_t; +typedef vector<string> stringVector_t; + +typedef struct persistConfigInfo_s +{ + char persistPrefix[TC_PERSIST_KEY_MAX]; + char processNamePrefix[TC_PERSIST_VALUE_MAX]; + char processNameFormat[TC_PERSIST_VALUE_MAX]; + char stdoutPrefix[TC_PERSIST_VALUE_MAX]; + char stdoutFormat[TC_PERSIST_VALUE_MAX]; + char programName[TC_PERSIST_VALUE_MAX]; + char programArgs[TC_PERSIST_VALUE_MAX]; + char zoneFormat[TC_PERSIST_VALUE_MAX]; + TC_PROCESS_TYPE processType; + bool requiresDTM; + int persistRetries; + int persistWindow; +} persistConfigInfo_t; + +class CPersistConfig; + +class CPersistConfigContainer +{ +public: + CPersistConfigContainer( void ); + ~CPersistConfigContainer( void ); + + CPersistConfig *AddPersistConfig( persistConfigInfo_t &persistConfigInfo ); + void Clear( void ); + void DeletePersistConfig( CPersistConfig *persistConfig ); + inline CPersistConfig *GetFirstPersistConfig( void ) { return ( head_ ); } + CPersistConfig *GetPersistConfig( const char *persistPrefix ); + CPersistConfig *GetPersistConfig( TC_PROCESS_TYPE processType + , const char *processName + , int nid ); + inline int GetPersistConfigCount( void ) { return ( persistsCount_ ); } + +protected: + void InitializePersistKeys( char *persistkeys + , pkeysVector_t &pkeysVector ); + int GetPersistKeysCount( void ) { return ( static_cast<int>(pkeysVector_.size()) ); } + + int persistsCount_; // # of persistent configuration object + pkeysVector_t pkeysVector_; // vector of persist keys + +private: + CPersistConfig *head_; // head of persist configuration linked list + CPersistConfig *tail_; // tail of persist configuration linked list +}; + +class CPersistConfig +{ + friend CPersistConfig *CPersistConfigContainer::AddPersistConfig( persistConfigInfo_t &persistConfigInfo ); + friend void CPersistConfigContainer::DeletePersistConfig( CPersistConfig *persistConfig ); +public: + CPersistConfig( persistConfigInfo_t &persistConfigInfo ); + ~CPersistConfig( void ); + + inline CPersistConfig *GetNext( void ){ return( next_); } + + inline const char *GetPersistPrefix( void ) { return( persistPrefix_.c_str() ); } + const char *GetProcessName( int nid ); + inline const char *GetProcessNamePrefix( void ) { return( processNamePrefix_.c_str() ); } + inline const char *GetProcessNameFormat( void ) { return( processNameFormat_.c_str() ); } + inline FormatNid_t GetProcessNameNidFormat( void ) { return( processNameNidFormat_ ); } + const char *GetStdoutFile( int nid ); + inline const char *GetStdoutPrefix( void ) { return( stdoutPrefix_.c_str() ); } + inline const char *GetStdoutFormat( void ) { return( stdoutFormat_.c_str() ); } + inline FormatNid_t GetStdoutNidFormat( void ) { return( stdoutNidFormat_ ); } + inline const char *GetProgramName( void ) { return( programName_.c_str() ); } + inline const char *GetProgramArgs( void ) { return( programArgs_.c_str() ); } + inline int GetProgramArgc( void ) { return( programArgc_ ); } + inline const char *GetProgramArgv( void ) { return( programArgv_ ); } + inline int GetProgramArgvLen( void ) { return( programArgvLen_ ); } + inline const char *GetZoneFormat( void ) { return( zoneFormat_.c_str() ); } + inline FormatZid_t GetZoneZidFormat( void ) { return( zoneZidFormat_ ); } + inline TC_PROCESS_TYPE GetProcessType( void ) { return ( processType_ ); } + inline bool GetRequiresDTM( void ) { return ( requiresDTM_ ); } + inline int GetPersistRetries( void ) { return ( persistRetries_ ); } + inline int GetPersistWindow( void ) { return ( persistWindow_ ); } + bool IsPersistConfig( const char *processName, int nid ); + bool IsZoneMatch( int zid ); + +protected: +private: + string persistPrefix_; + string processName_; + string processNamePrefix_; + string processNameFormat_; + string stdoutFile_; + string stdoutPrefix_; + string stdoutFormat_; + string programName_; + string programArgs_; + string zoneFormat_; + TC_PROCESS_TYPE processType_; + FormatNid_t processNameNidFormat_; + FormatNid_t stdoutNidFormat_; + FormatZid_t zoneZidFormat_; + bool requiresDTM_; + int persistRetries_; + int persistWindow_; + + int programArgc_; + char *programArgv_; + int programArgvLen_; + + CPersistConfig *next_; // next PersistConfig in CPersistConfigContainer list + CPersistConfig *prev_; // previous PersistConfig in CPersistConfigContainer list +}; + +#endif /* PERSISTCONFIG_H_ */
