You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by db...@apache.org on 2018/02/06 19:23:23 UTC

[04/11] trafodion git commit: [TRAFODION-2650] Restructured Trafodion Configuration code into separate directory structure.

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_ */