class='cKeyword'>#include <procdefs.h>
class='cKeyword'>#include <stdio.h>
class='cKeyword'>#include <stdlib.h>
class='cKeyword'>#include <string.h>
class='cKeyword'>#include <nwthread.h>
class='cKeyword'>#include <signal.h>
class='cKeyword'>#include <ncssdk.h>
class='cKeyword'>#include <mpkapis.h>
class='cKeyword'>#include <clstrlib.h>
class='cKeyword'>#include "hmo.h"
UINT32 ShutDownFlag, DeadFlag;
UINT8 savedCommandLine[512];
int ThdGrpID;
typedef struct{
UINT32 (*curLooksAlive)( int ParamCount, UINT8 *ParamList[]);
UINT32 (*curIsAlive)( int ParamCount, UINT8 *ParamList[]);
UINT32 IsWait, LooksWait;
UINT8 WhichResource[ 64];
UINT8 params[ MAX_PARAMS][ 80];
UINT8 keywords[ MAX_PARAMS][ 20];
UINT32 NumParams;
int thisHmo;
NCS_RESOURCE aRes, *pRes;
UINT32 GroupEpoch;
UINT32 NodeBitmap;
UINT8 loadBuff[1200];
UINT8 unloadBuff[1200];
UINT32 ThisNodeNum;
NCS_HANDLE sdkHandle;
UINT32 RecoveryFlag;
UINT32 FailFlag;
}HMO_CONTEXT;
HMO_CONTEXT anHmo, *pHmo;
UINT8 *parseStrs[ MAX_PARAMS +5] = { MSG("KEY", 1), MSG("LOOK", 2), MSG("IS", 3), MSG("RECOVERY", 4), MSG("FAILED", 5),
NULL };
UINT8 *recoverStrs[ 5]={MSG("MIGRATE", 6), MSG("OFFLINE", 7), MSG("RESTART", 8), MSG("ABEND", 9), NULL};
typedef enum {
RECOVER_UNKNOWN, RECOVER_MIGRATE, RECOVER_OFFLINE, RECOVER_RESTART,
RECOVER_ABEND
}RECOVER_TYPES;
void ParseCommandHmo( HMO_CONTEXT *pHmo, UINT8 *ptrCommandLine);
UINT32 MoveThis( HMO_CONTEXT *pHmo);
void HmoGaurdian( THREAD thr, void *arg);
class='cKeyword'>class='cKeyword'>#ifdef MsgTagNLM
BYTE **NLMMessageTable;
class='cKeyword'>#endif
struct ScreenStruct *CScreen = NULL;
LONG
HmoStart(
struct LoadDefinitionStructure *loadHandle,
struct ScreenStruct *initErrorScreen,
STR *commandLine)
{
UINT retVal;
class='cKeyword'>class='cKeyword'>#ifdef MsgTagNLM
LONG messageCount;
LONG languageId;
BYTE *helpFile;
ReturnMessageInformation((LONG)loadHandle, &NLMMessageTable,
&messageCount, &languageId, &helpFile);
class='cKeyword'>#endif
CScreen = initErrorScreen;
CStrCpy( savedCommandLine, commandLine);
ShutDownFlag = FALSE;
DeadFlag = 0;
retVal = StartHmoApp();
return retVal;
}
LONG
HmoExit(void)
{
OutputToScreen( CScreen, MSG("HmoExit called\r\n", 10));
ShutDownFlag = 1;
if( pHmo != NULL && pHmo->thisHmo != 0){
while( DeadFlag == 0){
kYieldThread();
}
}
return 0;
}
void HmoDeregister( HMO_HANDLE hmoHandle)
{
HMO_CONTEXT *pHmo;
OutputToScreen( CScreen, MSG("Deregister called %x\r\n", 11), hmoHandle);
pHmo = ( HMO_CONTEXT *)hmoHandle;
if( pHmo != NULL){
if( pHmo->sdkHandle != NULL){
NCS_Deregister( pHmo->sdkHandle);
pHmo->sdkHandle = NULL;
}
}
}
void myEpochCback( IN NCS_HANDLE Handle, IN UINT32 GroupEpoch,
IN UINT32 Members ){
}
UINT32 myCrmCback(NCS_MAPI crmMapi, NCS_RESOURCE *pRes, void * cxt)
{
OutputToScreen( CScreen, MSG("myCrmCback called\r\n", 12));
return 0;
}
UINT32 HmoRegister( HMO_HANDLE *newHandle, UINT32 (*looksAlive)( int ParamCount,
class='cKeyword'>char *ParamList[]),
UINT32 (*isAlive)( int ParamCount, class='cKeyword'>char *ParamList[]),
int ParamCount, class='cKeyword'>char *ParamList[])
{
UINT32 retVal;
UINT32 pCount;
int i, j, done;
UINT8 tBuff[ 64], *pList[MAX_PARAMS], *aPtr;
retVal = HMO_UNKNOWN;
if( looksAlive == NULL || isAlive == NULL || newHandle == NULL){
return HMO_BAD_PARAMETER;
}
memset( pList, 0, sizeof( pList));
for( i=0; i < ParamCount; i++){
pList[i] = ParamList[i];
}
pCount = ParamCount;
pHmo = &anHmo;
memset( pHmo, 0, sizeof( HMO_CONTEXT));
*newHandle = ( HMO_HANDLE) pHmo;
pHmo->curLooksAlive = looksAlive;
pHmo->curIsAlive = isAlive;
pHmo->RecoveryFlag = RECOVER_MIGRATE;
pHmo->FailFlag = RECOVER_OFFLINE;
for( i =0; i < MAX_PARAMS; i++){
if( pList[i] != NULL){
aPtr = pList[i];
if( *aPtr != 0){
j = strlen( aPtr);
if( j >=20 ){
memcpy( pHmo->keywords[ pHmo->NumParams], aPtr, 19);
}else{
strcpy( pHmo->keywords[ pHmo->NumParams], aPtr);
}
pHmo->NumParams++;
}
}
}
ParseCommandHmo( pHmo, savedCommandLine);
OutputToScreen( CScreen, MSG("params is=%d look=%d which=%s p1=%s p2=%s p3=%s p4=%s\r\n", 13),
pHmo->IsWait, pHmo->LooksWait, pHmo->WhichResource, pHmo->params[0],
pHmo->params[1], pHmo->params[2], pHmo->params[3]);
if( pHmo->WhichResource[0] != 0){
sprintf( tBuff, MSG("Thd%s", 14), pHmo->WhichResource);
pHmo->thisHmo = kStartThread( tBuff, HmoGaurdian, 0, 16000, pHmo);
i = 0;
done = FALSE;
while( i < 40 && !done){
if( pHmo->aRes.name[ 0] != 0){
done = TRUE;
continue;
}else{
delay( 500);
i++;
}
}
if( !done){
OutputToScreen( CScreen, MSG("Cannot find resource %s.\n", 15), pHmo->WhichResource);
retVal = HMO_NORESOURCE;
}else{
retVal = HMO_OK;
}
}else{
retVal = HMO_NORESOURCE;
}
return retVal;
}
void HmoGaurdian( THREAD thr, void *arg){
HMO_CONTEXT *pHmo;
UINT32 retVal, done, looksCount, isCount;
UINT8 *ppList[ MAX_PARAMS];
UINT32 LookFailure;
int i;
pHmo = (HMO_CONTEXT *)arg;
retVal = NCS_Register( myCrmCback, pHmo->WhichResource, myEpochCback,
NULL, NULL, &pHmo->sdkHandle);
if( retVal == NCS_SUCCESS)
{
retVal = NCS_NodeNumber( pHmo->sdkHandle, &pHmo->ThisNodeNum);
pHmo->pRes = &pHmo->aRes;
retVal = NCS_FindResource( pHmo->sdkHandle, pHmo->WhichResource, 1,
pHmo->pRes);
OutputToScreen( CScreen, MSG("Resource is %s Node=%d\r\n", 16),
pHmo->pRes->name, pHmo->ThisNodeNum);
if( retVal != NCS_RESOURCE_FOUND){
NCS_Deregister( pHmo->sdkHandle);
pHmo->sdkHandle = 0;
retVal = HMO_NORESOURCE;
}else{
delay( 1);
pHmo->pRes->loadScript = pHmo->loadBuff;
pHmo->pRes->unloadScript = pHmo->unloadBuff;
retVal = NCS_ReadResource( pHmo->sdkHandle, pHmo->pRes, sizeof( pHmo->loadBuff));
if( retVal != 0){
NCS_Deregister( pHmo->sdkHandle);
pHmo->sdkHandle = 0;
retVal = HMO_NORESOURCE;
}
}
retVal = 0;
}else{
retVal = HMO_UNKNOWN;
}
if( retVal != 0){
StopHmoApp( );
DeadFlag = 1;
return;
}
done = FALSE;
isCount = 0;
looksCount = 0;
LookFailure = 0;
memset( ppList, 0, sizeof( ppList));
for( i = 0; i< pHmo->NumParams; i++){
ppList[i] = pHmo->params[i];
}
while( !done){
if( ShutDownFlag){
done = TRUE;
}
if( isCount >= pHmo->IsWait){
isCount = 0;
looksCount = 0;
LookFailure = 0;
retVal = pHmo->curIsAlive( pHmo->NumParams, ppList);
if( retVal){
retVal = MoveThis( pHmo);
done = TRUE;
continue;
}
}
if( looksCount >= pHmo->LooksWait){
looksCount = 0;
retVal = pHmo->curLooksAlive( pHmo->NumParams, ppList);
if( retVal){
LookFailure++;
if( LookFailure > 1){
isCount = 0;
looksCount = 0;
LookFailure = 0;
retVal = pHmo->curIsAlive( pHmo->NumParams, ppList);
if( retVal){
retVal = MoveThis( pHmo);
done = TRUE;
continue;
}
}
}
}
isCount++;
looksCount++;
delay( 1000);
}
StopHmoApp();
while( !ShutDownFlag){
delay(100);
}
DeadFlag = 1;
}
void ExpandNodeList( UINT32 Bitmap, UINT8 Expanded[32]){
UINT32 i, j, onee;
onee = 1;
j = 0;
memset( Expanded, -1, 32);
for( i = 0; i < 32; i++){
if( onee & Bitmap){
Expanded[ j++] = i;
}
onee *= 2;
}
}
UINT32 MoveThis( HMO_CONTEXT *pHmo){
UINT32 retVal, tempUI, tempUI2;
UINT8 nodeList[32];
int i, j, k, m;
OutputToScreen( CScreen, MSG("Move %s recover=%d fail=%d \r\n", 17), pHmo->pRes->name, pHmo->RecoveryFlag,
pHmo->FailFlag);
if( pHmo->RecoveryFlag == RECOVER_OFFLINE ){
pHmo->pRes->fromTo = -1;
retVal = NCS_ResourceControl( pHmo->sdkHandle, NCS_MAPI_OFFLINE, pHmo->pRes,
NULL);
if( retVal != 0){
goto DO_FAILED_OPTION;
}
return retVal;
}
if( pHmo->RecoveryFlag == RECOVER_MIGRATE){
retVal = NCS_Query_Epoch( pHmo->sdkHandle, &pHmo->GroupEpoch, &pHmo->NodeBitmap);
tempUI = pHmo->NodeBitmap;
tempUI2 = 1<< pHmo->ThisNodeNum;
tempUI &= ~tempUI2;
ExpandNodeList( tempUI, nodeList);
if( tempUI != 0){
j = -1;
for( i = pHmo->ThisNodeNum+1; i < 32; i++){
for( k = 0; k < 32; k++){
if( nodeList[k] == i ){
for( m = 0; m < 32; m++){
if( pHmo->pRes->fail_order[m] == i){
j = i;
goto FOUND_NEXT;
}
}
}
}
}
for( i = 0; i < pHmo->ThisNodeNum; i++){
for( k = 0; k < 32; k++){
if( nodeList[k] == i ){
for( m = 0; m < 32; m++){
if( pHmo->pRes->fail_order[m] == i){
j = i;
goto FOUND_NEXT;
}
}
}
}
}
goto DO_FAILED_OPTION;
}
goto DO_FAILED_OPTION;
FOUND_NEXT:;
pHmo->pRes->fromTo = j;
OutputToScreen( CScreen, MSG("Migrate to %d\r\n", 18), j);
retVal = NCS_ResourceControl( pHmo->sdkHandle, NCS_MAPI_MIGRATE, pHmo->pRes,
NULL);
OutputToScreen( CScreen, MSG("ret=%d ", 19), retVal);
if( retVal){
goto DO_FAILED_OPTION;
}
return( retVal);
}
if( pHmo->RecoveryFlag == RECOVER_ABEND){
NWCLSTR_Abend( MSG("NWCS: HMO Abend on recover.\n", 20));
}
if( pHmo->RecoveryFlag == RECOVER_RESTART){
RestartServer( NULL);
return 0;
}
DO_FAILED_OPTION:;
OutputToScreen( CScreen, MSG("Doing failed option\r\n", 21));
if( pHmo->FailFlag == RECOVER_OFFLINE || pHmo->FailFlag == 0 ||
pHmo->FailFlag == RECOVER_MIGRATE){
pHmo->pRes->fromTo = -1;
retVal = NCS_ResourceControl( pHmo->sdkHandle, NCS_MAPI_OFFLINE, pHmo->pRes,
NULL);
return retVal;
}
if( pHmo->FailFlag == RECOVER_ABEND){
NWCLSTR_Abend( MSG("NWCS: HMO Abend on failure to recover.\n", 22));
}
if( pHmo->FailFlag == RECOVER_RESTART){
RestartServer( NULL);
return 0;
}
return retVal;
}
void ParseCommandHmo( HMO_CONTEXT *pHmo, UINT8 *ptrCommandLine){
int len, wordLen, done;
UINT8 *aPtr, *bPtr, copyOverByte;
int i, ii, j, newCount, j2, ii2, i2 ;
newCount = 5 + pHmo->NumParams;
for( i= 0; i < pHmo->NumParams; i++){
parseStrs[ i+5] = pHmo->keywords[ i];
}
len = strlen( ptrCommandLine);
aPtr = ptrCommandLine;
OutputToScreen( CScreen, MSG("in Parse len=%d s=%s\r\n", 23), len, aPtr);
while( len > 0 && *aPtr == ' '){
aPtr++;
len--;
}
bPtr = aPtr;
wordLen = 0;
while( len > 0 ){
while( len > 0 && *aPtr != '/'){
aPtr++;
len--;
}
if( len >0){
wordLen = 0;
aPtr++;
len--;
bPtr = aPtr;
done = FALSE;
while( !done){
if( len <= 0 || *bPtr == 0 || *bPtr == ' ' || *bPtr == '='){
copyOverByte = *bPtr;
*bPtr = 0;
done = TRUE;
}else{
len--;
bPtr++;
wordLen++;
}
}
if( wordLen > 0){
i = 0;
while( i < newCount && parseStrs[ i] != NULL){
ii = strlen( parseStrs[ i]);
j = memicmp( aPtr, parseStrs[ i], ii);
if( j == 0 && ii == wordLen ){
*bPtr = copyOverByte;
if( (i == 0 || i >4) && i < (MAX_PARAMS +5)){
if( len > 0){
bPtr++;
aPtr = bPtr;
len--;
wordLen = 0;
while( len >0 && *aPtr != ' '){
aPtr++;
len--;
wordLen++;
}
if( wordLen > 0){
*aPtr = 0;
if( i == 0 ){
if( wordLen >= 63){
memcpy( pHmo->WhichResource, bPtr, 63);
}else{
strcpy( pHmo->WhichResource, bPtr);
}
}else{
if( wordLen >= 79){
memcpy( pHmo->params[ i-5], bPtr, 79);
}else{
strcpy( pHmo->params[ i-5], bPtr);
}
}
}
bPtr = aPtr;
}
goto NEXT_PHRASE;
}else{
if( i >= 1 && i <= 4){
if( len > 0){
bPtr++;
aPtr = bPtr;
len--;
wordLen = 0;
while( len >0 && *aPtr != ' '){
aPtr++;
len--;
wordLen++;
}
if( wordLen > 0){
*aPtr = 0;
switch( i){
class='cKeyword'>case 1:
pHmo->LooksWait = atoi( bPtr);
class='cKeyword'>break;
class='cKeyword'>case 2:
pHmo->IsWait = atoi( bPtr);
class='cKeyword'>break;
class='cKeyword'>case 3:
class='cKeyword'>case 4:
i2 = 0;
while( i2 < 4 && recoverStrs[ i2] != NULL){
ii2 = strlen( recoverStrs[ i2]);
j2 = memicmp( bPtr, recoverStrs[ i2], ii2);
if( j2 == 0 && ii2 == wordLen ){
i2++;
if( i == 3){
pHmo->RecoveryFlag = i2;
}else{
pHmo->FailFlag = i2;
}
class='cKeyword'>break;
}
i2++;
}
class='cKeyword'>break;
default:
class='cKeyword'>break;
}
}
bPtr = aPtr;
}
}
goto NEXT_PHRASE;
}
}
i++;
}
}
}
NEXT_PHRASE:;
wordLen = 0;
}
}