6a5e10492c
This decouples the build and packaging of guest-server, guest-agent from mtce, by splitting guest component into stx-nfv repo. This leaves existing C++ code, scripts, and resource files untouched, so there is no functional change. Code refactoring is beyond the scope of this update. Makefiles were modified to include devel headers directories /usr/include/mtce-common and /usr/include/mtce-daemon. This ensures there is no contamination with other system headers. The cgts-mtce-common package is renamed and split into: - repo stx-metal: mtce-common, mtce-common-dev - repo stx-metal: mtce - repo stx-nfv: mtce-guest - repo stx-ha: updates package dependencies to mtce-pmon for service-mgmt, sm, and sm-api mtce-common: - contains common and daemon shared source utility code mtce-common-dev: - based on mtce-common, contains devel package required to build mtce-guest and mtce - contains common library archives and headers mtce: - contains components: alarm, fsmon, fsync, heartbeat, hostw, hwmon, maintenance, mtclog, pmon, public, rmon mtce-guest: - contains guest component guest-server, guest-agent Story: 2002829 Task: 22748 Change-Id: I9c7a9b846fd69fd566b31aa3f12a043c08f19f1f Signed-off-by: Jim Gauld <james.gauld@windriver.com>
559 lines
15 KiB
C++
559 lines
15 KiB
C++
/*
|
|
* Copyright (c) 2015 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
*/
|
|
|
|
/* This module implements a linked list for unsigned long key:value pairs.
|
|
*
|
|
* Was first introduced to provide to associate a libEvent address with a
|
|
* eventLib base pointer so that the event handler could lookup the event
|
|
* from the base, Key is base and value is the libEvent address.
|
|
*
|
|
*/
|
|
|
|
#ifdef __AREA__
|
|
#undef __AREA__
|
|
#define __AREA__ "kvp"
|
|
#endif
|
|
|
|
#include "nodeBase.h"
|
|
#include "keyClass.h"
|
|
//#include "nodeUtil.h"
|
|
|
|
|
|
/* keyClass Constructor */
|
|
keyClass::keyClass()
|
|
{
|
|
head = tail = NULL;
|
|
memory_allocs = 0 ;
|
|
memory_used = 0 ;
|
|
keys = 0 ;
|
|
|
|
for ( int i = 0 ; i < MAX_KEYS ; i++ )
|
|
{
|
|
key_ptrs[i] = NULL ;
|
|
}
|
|
}
|
|
|
|
/* keyClass Destructor */
|
|
keyClass::~keyClass()
|
|
{
|
|
for ( int i = 0 ; i < MAX_KEYS ; i++ )
|
|
{
|
|
if ( key_ptrs[i] )
|
|
{
|
|
delete key_ptrs[i] ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************************
|
|
********** C O M M O N P R I V A T E I N T E R F A C E S ***************
|
|
*****************************************************************************************/
|
|
|
|
/******************************************************************
|
|
*
|
|
* Name : newKey (private)
|
|
*
|
|
* Description: Allocates memory for a new key value pair and
|
|
* stores its the address in key_ptrs
|
|
*
|
|
* @param void
|
|
* @return pointer to the newly allocted Key memory
|
|
*
|
|
*******************************************************************/
|
|
struct keyClass::keyValue * keyClass::newKey ( void )
|
|
{
|
|
struct keyClass::keyValue * key_ptr = NULL ;
|
|
|
|
// find an empty spot
|
|
for ( int i = 0 ; i < MAX_KEYS ; i++ )
|
|
{
|
|
if ( key_ptrs[i] == NULL )
|
|
{
|
|
key_ptrs[i] = key_ptr = new keyValue ;
|
|
memory_allocs++ ;
|
|
memory_used += sizeof (struct keyClass::keyValue);
|
|
keys++ ;
|
|
return key_ptr ;
|
|
}
|
|
}
|
|
elog ( "Failed to save new key pointer address\n" );
|
|
return key_ptr ;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Name : delKey (private)
|
|
*
|
|
* Description: Frees the memory of a pre-allocated key and removes
|
|
* it from the key_ptrs list.
|
|
*
|
|
* @param key * pointer to the key memory address to be freed
|
|
* @return int return code { PASS or -EINVAL }
|
|
*
|
|
**************************************************************************/
|
|
int keyClass::delKey ( struct keyClass::keyValue * key_ptr )
|
|
{
|
|
if ( memory_allocs > 0 )
|
|
{
|
|
for ( int i = 0 ; i < MAX_KEYS ; i++ )
|
|
{
|
|
if ( key_ptrs[i] == key_ptr )
|
|
{
|
|
delete key_ptr ;
|
|
key_ptrs[i] = NULL ;
|
|
memory_used -= sizeof (struct keyClass::keyValue);
|
|
if ( memory_allocs ) memory_allocs-- ;
|
|
if ( keys ) keys-- ;
|
|
return PASS ;
|
|
}
|
|
}
|
|
elog ( "Unable to validate memory address being freed\n" );
|
|
}
|
|
else
|
|
elog ( "Free memory called when there is no memory to free\n" );
|
|
|
|
return -EINVAL ;
|
|
}
|
|
|
|
/*****************************************************************
|
|
*
|
|
* Name : remKey
|
|
*
|
|
* Description: Remove a specified key from the linked list
|
|
*
|
|
*@param unsigned long key signature
|
|
*@return PASS or failure codes ENODEV, ENXIO, EFAULT
|
|
*
|
|
*****************************************************************/
|
|
int keyClass::remKey( struct keyValue * ptr )
|
|
{
|
|
if ( head == NULL )
|
|
return -ENXIO ;
|
|
|
|
if ( ptr == NULL )
|
|
return -EFAULT ;
|
|
|
|
/* If the key is the head key */
|
|
if ( ptr == head )
|
|
{
|
|
/* only one key in the list case */
|
|
if ( head == tail )
|
|
{
|
|
dlog3 ("Single Key -> Head Case\n");
|
|
head = NULL ;
|
|
tail = NULL ;
|
|
}
|
|
else
|
|
{
|
|
dlog3 ("Multiple Keys -> Head Case\n");
|
|
head = head->next ;
|
|
head->prev = NULL ;
|
|
}
|
|
}
|
|
/* if not head but tail then there must be more than one
|
|
* key in the list so go ahead and chop the tail.
|
|
*/
|
|
else if ( ptr == tail )
|
|
{
|
|
dlog3 ("Multiple Key -> Tail Case\n");
|
|
tail = tail->prev ;
|
|
tail->next = NULL ;
|
|
}
|
|
else
|
|
{
|
|
dlog3 ("Multiple Key -> Full Splice Out\n");
|
|
ptr->prev->next = ptr->next ;
|
|
ptr->next->prev = ptr->prev ;
|
|
}
|
|
delKey ( ptr );
|
|
|
|
return (PASS) ;
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************************
|
|
********** K E Y T Y P E P R I V A T E I N T E R F A C E S *************
|
|
*****************************************************************************************/
|
|
|
|
/******************************************************************
|
|
*
|
|
* Name : addKey (private)
|
|
*
|
|
* Description: Reprovisions the key:value if it already exists
|
|
* Calls newkey to allocates memory for a new key
|
|
* and then tacks the new key value onto the end
|
|
* of the linked list.
|
|
*
|
|
* @param unsigned long key and value
|
|
* @return pointer to the newly allocted Key memory
|
|
*
|
|
*******************************************************************/
|
|
struct keyClass::keyValue* keyClass::addKey( unsigned long key__int, unsigned long val__int )
|
|
{
|
|
/* verify key is not already provisioned */
|
|
struct keyValue * ptr = getKey ( key__int );
|
|
if ( ptr )
|
|
{
|
|
if ( delKey ( ptr ) )
|
|
{
|
|
/* Should never get here but if we do then */
|
|
/* something is seriously wrong */
|
|
elog ("Unable to remove key during reprovision\n");
|
|
return static_cast<struct keyValue *>(NULL);
|
|
}
|
|
}
|
|
|
|
/* allocate memory for new key */
|
|
ptr = newKey ();
|
|
if( ptr == NULL )
|
|
{
|
|
elog ( "Failed to allocate memory for new key\n" );
|
|
return static_cast<struct keyValue *>(NULL);
|
|
}
|
|
|
|
/* push the calling data into new key */
|
|
ptr->key__int = key__int ;
|
|
ptr->val__int = val__int ;
|
|
|
|
dlog3 ("add key:%lx val:%lx\n", ptr->key__int, ptr->val__int );
|
|
|
|
/* If the key list is empty add it to the head */
|
|
if( head == NULL )
|
|
{
|
|
head = ptr ;
|
|
tail = ptr ;
|
|
ptr->prev = NULL ;
|
|
ptr->next = NULL ;
|
|
}
|
|
else
|
|
{
|
|
/* link the new_key to the tail of the key_list
|
|
* then mark the next field as the end of the key_list
|
|
* adjust tail to point to the last key
|
|
*/
|
|
tail->next = ptr ;
|
|
ptr->prev = tail ;
|
|
ptr->next = NULL ;
|
|
tail = ptr ;
|
|
}
|
|
return ptr ;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
* Name : getKey (private)
|
|
*
|
|
* Description: Looks for a key in the linked list.
|
|
*
|
|
* @param unsigned long key
|
|
* @return pointer to the matching key in the linked list
|
|
*
|
|
*******************************************************************/
|
|
struct keyClass::keyValue * keyClass::getKey ( unsigned long key__int )
|
|
{
|
|
/* check for empty list condition */
|
|
if ( head == NULL )
|
|
return NULL ;
|
|
|
|
for ( struct keyValue * ptr = head ; ; ptr = ptr->next )
|
|
{
|
|
if ( ptr->key__int == key__int )
|
|
{
|
|
dlog3 ("get key:%lx val:%lx\n", ptr->key__int, ptr->val__int );
|
|
return ptr ;
|
|
}
|
|
if (( ptr->next == NULL ) || ( ptr == tail ))
|
|
break ;
|
|
}
|
|
return static_cast<struct keyValue *>(NULL);
|
|
}
|
|
|
|
/*****************************************************************/
|
|
/* String key version */
|
|
/******************************************************************
|
|
*
|
|
* Name : addKey (private)
|
|
*
|
|
* Description: Reprovisions the key:value if it already exists
|
|
* Calls newkey to allocates memory for a new key
|
|
* and then tacks the new key value onto the end
|
|
* of the linked list.
|
|
*
|
|
* @param unsigned long key and value
|
|
* @return pointer to the newly allocted Key memory
|
|
*
|
|
*******************************************************************/
|
|
struct keyClass::keyValue* keyClass::addKey( string key__str, unsigned long * val__ptr )
|
|
{
|
|
/* verify key is not already provisioned */
|
|
struct keyValue * ptr = getKey ( key__str );
|
|
if ( ptr )
|
|
{
|
|
if ( delKey ( ptr ) )
|
|
{
|
|
/* Should never get here but if we do then */
|
|
/* something is seriously wrong */
|
|
elog ("Unable to remove key during reprovision\n");
|
|
return static_cast<struct keyValue *>(NULL);
|
|
}
|
|
}
|
|
|
|
/* allocate memory for new key */
|
|
ptr = newKey ();
|
|
if( ptr == NULL )
|
|
{
|
|
elog ( "Failed to allocate memory for new key\n" );
|
|
return static_cast<struct keyValue *>(NULL);
|
|
}
|
|
|
|
/* push the calling data into new key */
|
|
ptr->key__str = key__str ;
|
|
ptr->val__ptr = val__ptr ;
|
|
|
|
dlog3 ("add key:%s val:%p\n", ptr->key__str.c_str(), ptr->val__ptr );
|
|
|
|
/* If the key list is empty add it to the head */
|
|
if( head == NULL )
|
|
{
|
|
head = ptr ;
|
|
tail = ptr ;
|
|
ptr->prev = NULL ;
|
|
ptr->next = NULL ;
|
|
}
|
|
else
|
|
{
|
|
/* link the new_key to the tail of the key_list
|
|
* then mark the next field as the end of the key_list
|
|
* adjust tail to point to the last key
|
|
*/
|
|
tail->next = ptr ;
|
|
ptr->prev = tail ;
|
|
ptr->next = NULL ;
|
|
tail = ptr ;
|
|
}
|
|
return ptr ;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
*
|
|
* Name : getKey (private)
|
|
*
|
|
* Description: Looks for a key in the linked list.
|
|
*
|
|
* @param unsigned long key
|
|
* @return pointer to the matching key in the linked list
|
|
*
|
|
*******************************************************************/
|
|
struct keyClass::keyValue * keyClass::getKey ( string key__str )
|
|
{
|
|
/* check for empty list condition */
|
|
if ( head == NULL )
|
|
return NULL ;
|
|
|
|
for ( struct keyValue * ptr = head ; ; ptr = ptr->next )
|
|
{
|
|
if ( ptr->key__str == key__str )
|
|
{
|
|
dlog3 ("get key:%s val:%p\n", ptr->key__str.c_str(), ptr->val__ptr );
|
|
return ptr ;
|
|
}
|
|
if (( ptr->next == NULL ) || ( ptr == tail ))
|
|
break ;
|
|
}
|
|
return static_cast<struct keyValue *>(NULL);
|
|
}
|
|
|
|
/******************************************************************************************
|
|
**************** P U B L I C I N T E R F A C E S ****************************
|
|
*****************************************************************************************/
|
|
|
|
/******************************************************************************************
|
|
*
|
|
* Name : get_key
|
|
*
|
|
* Purpose : look up the alue based on a key
|
|
*
|
|
******************************************************************************************/
|
|
|
|
/*
|
|
* Unsigned Long K E Y
|
|
* Unsigned Long V A L u e
|
|
*/
|
|
int keyClass::get_key ( unsigned long key__int, unsigned long & val__int )
|
|
{
|
|
/* verify key is not already provisioned */
|
|
struct keyValue * keyValue_ptr = getKey ( key__int );
|
|
if ( keyValue_ptr )
|
|
{
|
|
val__int = keyValue_ptr->val__int ;
|
|
return (PASS);
|
|
}
|
|
return(FAIL_NOT_FOUND);
|
|
}
|
|
|
|
/*
|
|
* String K E Y
|
|
* Unsigned Long Pointer V A L u e
|
|
*/
|
|
int keyClass::get_key ( string key__str, unsigned long *& val__ptr )
|
|
{
|
|
/* verify key is not already provisioned */
|
|
struct keyValue * keyValue_ptr = getKey ( key__str );
|
|
if ( keyValue_ptr )
|
|
{
|
|
val__ptr = keyValue_ptr->val__ptr ;
|
|
return (PASS);
|
|
}
|
|
return(FAIL_NOT_FOUND);
|
|
}
|
|
|
|
|
|
/******************************************************************************************
|
|
*
|
|
* Name : add_key
|
|
*
|
|
* Purpose : add a key value to the object
|
|
*
|
|
******************************************************************************************/
|
|
|
|
/*
|
|
* Unsigned Long K E Y
|
|
* Unsigned Long V A L u e
|
|
*/
|
|
|
|
int keyClass::add_key ( unsigned long key__int, unsigned long val__int )
|
|
{
|
|
int rc = FAIL ;
|
|
struct keyClass::keyValue * keyValue_ptr = static_cast<struct keyValue *>(NULL);
|
|
|
|
keyValue_ptr = keyClass::getKey(key__int);
|
|
if ( keyValue_ptr )
|
|
{
|
|
wlog ("add key:%lx failed - in use (value:%lx)\n", keyValue_ptr->key__int, keyValue_ptr->val__int );
|
|
|
|
/* Send back a retry in case the add needs to be converted to a modify */
|
|
return (RETRY);
|
|
}
|
|
/* Otherwise add it as a new key */
|
|
else
|
|
{
|
|
keyValue_ptr = keyClass::addKey( key__int , val__int);
|
|
if ( keyValue_ptr )
|
|
{
|
|
dlog3 ("add key:%lx\n", key__int );
|
|
rc = PASS ;
|
|
}
|
|
else
|
|
{
|
|
rc = FAIL_NULL_POINTER ;
|
|
}
|
|
}
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* String K E Y
|
|
* Unsigned Long Pointer V A L u e
|
|
*/
|
|
int keyClass::add_key ( string key__str, unsigned long * val__ptr )
|
|
{
|
|
int rc = FAIL ;
|
|
struct keyClass::keyValue * keyValue_ptr = static_cast<struct keyValue *>(NULL);
|
|
|
|
keyValue_ptr = keyClass::getKey(key__str);
|
|
if ( keyValue_ptr )
|
|
{
|
|
wlog ("add key:%s failed - in use (value:%p)\n", keyValue_ptr->key__str.c_str(), keyValue_ptr->val__ptr );
|
|
|
|
return (RETRY);
|
|
}
|
|
/* Otherwise add it as a new key */
|
|
else
|
|
{
|
|
keyValue_ptr = keyClass::addKey( key__str, val__ptr);
|
|
if ( keyValue_ptr )
|
|
{
|
|
dlog3 ("add key:%s\n", key__str.c_str());
|
|
|
|
rc = PASS ;
|
|
}
|
|
else
|
|
{
|
|
rc = FAIL_NULL_POINTER ;
|
|
}
|
|
}
|
|
return (rc);
|
|
}
|
|
|
|
|
|
/******************************************************************************************
|
|
*
|
|
* Name : del_key
|
|
*
|
|
* Purpose : del a key value from the object
|
|
*
|
|
******************************************************************************************/
|
|
|
|
/*
|
|
* Unsigned Long K E Y
|
|
* Unsigned Long V A L u e
|
|
*/
|
|
|
|
|
|
int keyClass::del_key ( unsigned long key__int )
|
|
{
|
|
int rc = FAIL_DEL_UNKNOWN ;
|
|
keyClass::keyValue * keyValue_ptr = keyClass::getKey( key__int );
|
|
if ( keyValue_ptr )
|
|
{
|
|
rc = remKey ( keyValue_ptr );
|
|
if ( rc != PASS )
|
|
{
|
|
elog ("del key:%lx failed - rc:%d\n", key__int , rc );
|
|
}
|
|
else
|
|
{
|
|
dlog3 ("del key:%lx\n", key__int );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wlog ("del key:%lx failed - not found\n", key__int );
|
|
}
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* String K E Y
|
|
* Unsigned Long Pointer V A L u e
|
|
*/
|
|
int keyClass::del_key ( string key__str )
|
|
{
|
|
int rc = FAIL_DEL_UNKNOWN ;
|
|
keyClass::keyValue * keyValue_ptr = keyClass::getKey( key__str );
|
|
if ( keyValue_ptr )
|
|
{
|
|
rc = remKey ( keyValue_ptr );
|
|
if ( rc != PASS )
|
|
{
|
|
elog ("del key:%s failed - rc:%d\n", key__str.c_str(), rc );
|
|
}
|
|
else
|
|
{
|
|
dlog3 ("del key:%s\n", key__str.c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wlog ("del key:%s failed - not found\n", key__str.c_str());
|
|
}
|
|
return (rc);
|
|
}
|