static void clCompAppAMFCSISet(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* * ---BEGIN_APPLICATION_CODE--- */ clprintf (CL_LOG_SEV_INFO, "Component [%s] : PID [%d]. CSISet called\n", compName->value, mypid); clPyGlueCsiSet(compName, haState,&csiDescriptor); clprintf (CL_LOG_SEV_INFO, "Component [%s] : PID [%d]. PyGlueCsiSet() returned OK\n", compName->value, mypid); /* if (haState != SA_AMF_HA_QUIESCING) */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); /* GAS TODO: put in a separate python-visible callback */ if (haState == SA_AMF_HA_QUIESCING) saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); /* * ---END_APPLICATION_CODE--- */ /* * Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%s] : PID [%d]. CSI Set Received\n", compName->value, mypid); clCompAppAMFPrintCSI(csiDescriptor, haState); }
/**************************************************************************** * Name : amf_quiescing_state_handler * * Description : This function is called upon receving an Quiescing state * assignment from AMF. * * Arguments : invocation - Designates a particular invocation. * cb - A pointer to the SMFD control block. * * Return Values : None * * Notes : None *****************************************************************************/ static SaAisErrorT amf_quiescing_state_handler(smfd_cb_t * cb, SaInvocationT invocation) { TRACE_ENTER2("HA QUIESCING request"); return saAmfCSIQuiescingComplete(cb->amf_hdl, invocation, SA_AIS_OK); }
static void csi_set_callback(SaInvocationT invocation, const SaNameT *comp_name, SaAmfHAStateT ha_state, SaAmfCSIDescriptorT csi_desc) { SaAisErrorT rc, status = SA_AIS_OK; SaAmfCSIAttributeT *attr; int i; if (csi_desc.csiFlags == SA_AMF_CSI_ADD_ONE) { syslog(LOG_DEBUG, "CSI Set - add '%s' HAState %s", csi_desc.csiName.value, ha_state_name[ha_state]); for (i = 0; i < csi_desc.csiAttr.number; i++) { attr = &csi_desc.csiAttr.attr[i]; syslog(LOG_DEBUG, " name: %s, value: %s", attr->attrName, attr->attrValue); setenv((char*)attr->attrName, (char*)attr->attrValue, 1); } } else { assert(csi_desc.csiFlags == SA_AMF_CSI_TARGET_ALL); syslog(LOG_DEBUG, "CSI Set - HAState %s", ha_state_name[ha_state]); } switch (ha_state) { case SA_AMF_HA_ACTIVE: status = service_start(); break; case SA_AMF_HA_STANDBY: break; case SA_AMF_HA_QUIESCED: status = service_stop(); break; case SA_AMF_HA_QUIESCING: break; default: syslog(LOG_ERR, "CSI Set: unknown HA state (%u)", ha_state); exit(1); break; } my_ha_state = ha_state; rc = saAmfResponse(my_amf_hdl, invocation, status); if (rc != SA_AIS_OK) { syslog(LOG_ERR, "CSI Set: saAmfResponse FAILED (%u)", rc); exit(1); } if (ha_state == SA_AMF_HA_QUIESCING) { status = service_stop(); rc = saAmfCSIQuiescingComplete(my_amf_hdl, invocation, status); if (rc != SA_AIS_OK) { syslog(LOG_ERR, "CSI Set: saAmfCSIQuiescingComplete FAILED (%u)", rc); exit(1); } } }
SaUint32T plms_quiescing_state_handler(SaInvocationT invocation) { SaAisErrorT error = SA_AIS_OK; PLMS_CB * cb = plms_cb; TRACE_ENTER(); error = saAmfCSIQuiescingComplete(cb->amf_hdl, invocation, error); saAmfResponse(cb->amf_hdl, invocation, error); LOG_IN("I AM IN HA AMF QUIESCING STATE\n"); TRACE_LEAVE(); return NCSCC_RC_SUCCESS; }
/**************************************************************************** * Name : amf_quiescing_state_handler * * Description : This function is called upon receving an Quiescing state * assignment from AMF. * * Arguments : invocation - Designates a particular invocation. * cb - A pointer to the LGS control block. * * Return Values : None * * Notes : None *****************************************************************************/ static SaAisErrorT amf_quiescing_state_handler(lgs_cb_t *cb, SaInvocationT invocation) { TRACE_ENTER2("HA QUIESCING request"); close_all_files(); /* Give up our IMM OI implementer role */ immutilWrapperProfile.errorsAreFatal = 0; (void)immutil_saImmOiImplementerClear(cb->immOiHandle); immutilWrapperProfile.errorsAreFatal = 1; return saAmfCSIQuiescingComplete(cb->amf_hdl, invocation, SA_AIS_OK); }
void clCompAppAMFCSISet( SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* * Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); clCompAppAMFPrintCSI(csiDescriptor, haState); /* * Take appropriate action based on state */ switch ( haState ) { case CL_AMS_HA_STATE_ACTIVE: { /* * AMF has requested application to take the active HA state * for the CSI. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case CL_AMS_HA_STATE_STANDBY: { /* * AMF has requested application to take the standby HA state * for this CSI. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case CL_AMS_HA_STATE_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case CL_AMS_HA_STATE_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); break; } default: { assert(0); break; } } return; }
/**************************************************************************** * Name : amf_quiescing_state_handler * * Description : This function is called upon receving an Quiescing state * assignment from AMF. * * Arguments : invocation - Designates a particular invocation. * cb - A pointer to the IMMD control block. * *****************************************************************************/ static SaAisErrorT amf_quiescing_state_handler(IMMD_CB *cb, SaInvocationT invocation) { LOG_IN("AMF HA QUIESCING request"); /*anything to close down ? */ return saAmfCSIQuiescingComplete(cb->amf_hdl, invocation, SA_AIS_OK); }
void clCompAppAMFCSISet(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* * Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); clCompAppAMFPrintCSI(csiDescriptor, haState); SaAisErrorT rc = SA_AIS_OK; /* create a checkpoint based on the csi descriptor name to ensure uniqueness Both processes will attempt to open/create the checkpoint. The first one will create it. */ if (alarmClockCkptHdl == 0) { strcpy(alarmClockCkptName, (char *)csiDescriptor.csiName.value); rc = alarmClockCkptCreate(alarmClockCkptName, 1, sizeof(acClockT), &alarmClockCkptHdl); if (rc != SA_AIS_OK) { alarmClockLogWrite(CL_LOG_SEV_ERROR, "alarmClockCkptCreate failed code [%d]", rc); assert(0); alarmClockCkptHdl = 0; } } /* * Take appropriate action based on state */ switch ( haState ) { case SA_AMF_HA_ACTIVE: { /* * AMF has requested application to take the active HA state * for the CSI. */ rc = alarmClockCkptActivate(alarmClockCkptHdl, 1); if (rc != SA_AIS_OK) { alarmClockLogWrite(CL_LOG_SEV_ERROR, "alarmClockCkptCreate(pid=%d): Failed to activate ckpt :0x%x\n", getpid(), rc); } if (rc == SA_AIS_OK) /* try to read the checkpoint regardless of prior state if I become active prevHaState == SA_AMF_HA_STANDBY) */ { /* this way the ckpt will be read on process restart */ acClockT alarmClock = {{0}}; alarmClockLogWrite(CL_LOG_SEV_INFO, "Reading checkpoint to recover the time"); rc = alarmClockCkptRead ( alarmClockCkptHdl, 1, &alarmClock, sizeof(acClockT)); if (rc == SA_AIS_OK) { alarmClockCopyAndStart( &alarmClock); } else { alarmClockStart(); } } else { alarmClockStart(); } prevHaState = haState; saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_STANDBY: { /* * AMF has requested application to take the standby HA state * for this CSI. */ alarmClockLogWrite(CL_LOG_SEV_INFO, "I am standby"); prevHaState = haState; saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ alarmClockStop(); prevHaState = haState; saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); break; } default: { assert(0); break; } } return; }
void safAssignWork(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); printCSI(csiDescriptor, haState); /* * Take appropriate action based on state */ switch ( haState ) { /* AMF asks this process to take the standby HA state for the work described in the csiDescriptor variable */ case SA_AMF_HA_ACTIVE: { /* Typically you would spawn a thread here to initiate active processing of the work. */ /* The AMF times the interval between the assignment and acceptance of the work (the time interval is configurable). So it is important to call this saAmfResponse function ASAP. */ clprintf(CL_LOG_SEV_INFO, "csa112: ACTIVE state requested; activating service"); running = 1; ha_state = haState; saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } /* AMF asks this process to take the standby HA state for the work described in the csiDescriptor variable */ case SA_AMF_HA_STANDBY: { /* If your standby has ongoing maintenance, you would spawn a thread here to do it. */ /* The AMF times the interval between the assignment and acceptance of the work (the time interval is configurable). So it is important to call this saAmfResponse function ASAP. */ clprintf(CL_LOG_SEV_INFO, "csa112: State is standby"); running = 0; ha_state = haState; saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ clprintf(CL_LOG_SEV_INFO, "csa112: Stop being active or standby"); running = 0; ha_state = haState; saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ /* There are two typical cases for quiescing. Chooose one! CASE 1: Its possible to quiesce rapidly within this thread context */ if (1) { /* App code here: Now finish your work and cleanly stop the work*/ clprintf(CL_LOG_SEV_INFO, "csa112: Stopping active or standby handling"); running = 0; ha_state = haState; /* Call saAmfCSIQuiescingComplete when stopping the work is done */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); } else { /* CASE 2: You can't quiesce within this thread context or quiesce rapidly. */ /* Respond immediately to the quiescing request */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); /* App code here: Signal or spawn a thread to cleanly stop the work*/ /* When that thread is done, it should call: saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); */ } break; } default: { assert(0); break; } } return; }
void clCompAppAMFCSISet(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { ClRcT rc = CL_OK; /* * Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); clCompAppAMFPrintCSI(csiDescriptor, haState); /* * Take appropriate action based on state */ switch ( haState ) { case SA_AMF_HA_ACTIVE: { /* * AMF has requested application to take the active HA state * for the CSI. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); rc = clAlarmEventSubscribe(&alarm_event_subscribe_callback); if (CL_OK != rc) { clprintf(CL_LOG_SEV_ERROR,"%s: Failed while subscribing for the alarm events. rc[0x%x]", appname, rc); return; } break; } case SA_AMF_HA_STANDBY: { /* * AMF has requested application to take the standby HA state * for this CSI. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); rc = clAlarmEventUnsubscribe(); if (CL_OK != rc) { clprintf(CL_LOG_SEV_ERROR,"%s: Failed while un-subscribing for the alarm evnets. rc[0x%x] ", appname, rc); return; } break; } case SA_AMF_HA_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); break; } default: { assert(0); break; } } return; }
/************************************************************************** * FUNCTION: Java_org_opensaf_ais_amf_CsiManagerImpl_completedCsiQuiescing * TYPE: native method * Class: ais_amf_CsiManager * Method: completedCsiQuiescing * Signature: (JLorg/saforum/ais/AisStatus;)V *************************************************************************/ JNIEXPORT void JNICALL Java_org_opensaf_ais_amf_CsiManagerImpl_completedCsiQuiescing(JNIEnv *jniEnv, jobject thisCsiManager, jlong invocation, jint error) { // VARIABLES SaAmfHandleT _saAmfHandle; SaAisErrorT _saStatus; SaAisErrorT _error; // JNI jobject _amfLibraryHandle; // BODY assert(thisCsiManager != NULL); _TRACE2 ("NATIVE: Executing Java_org_opensaf_ais_amf_CsiManagerImpl_completedCsiQuiescing()\n"); // get Java library handle _amfLibraryHandle = (*jniEnv)->GetObjectField(jniEnv, thisCsiManager, FID_amfLibraryHandle); assert(_amfLibraryHandle != NULL); // get native library handle _saAmfHandle = (SaAmfHandleT)(*jniEnv)->GetLongField(jniEnv, _amfLibraryHandle, FID_saAmfHandle); // convert AisStatus -> int // MODIFICATION: screwed up _error = (SaAisErrorT)error; // call saAmfCSIQuiescingComplete _saStatus = saAmfCSIQuiescingComplete(_saAmfHandle, (SaInvocationT)invocation, (SaAisErrorT)_error); _TRACE2 ("NATIVE: saAmfCSIQuiescingComplete(...) has returned with %d...\n", _saStatus); // error handling if (_saStatus != SA_AIS_OK) { switch (_saStatus) { case SA_AIS_ERR_LIBRARY: JNU_throwNewByName(jniEnv, "org/saforum/ais/AisLibraryException", AIS_ERR_LIBRARY_MSG); break; case SA_AIS_ERR_TIMEOUT: JNU_throwNewByName(jniEnv, "org/saforum/ais/AisTimeoutException", AIS_ERR_TIMEOUT_MSG); break; case SA_AIS_ERR_TRY_AGAIN: JNU_throwNewByName(jniEnv, "org/saforum/ais/AisTryAgainException", AIS_ERR_TRY_AGAIN_MSG); break; case SA_AIS_ERR_BAD_HANDLE: // TODO library handle invalid (e.g finalized): this check could be done at Java level! JNU_throwNewByName(jniEnv, "org/saforum/ais/AisBadHandleException", AIS_ERR_BAD_HANDLE_MSG); break; case SA_AIS_ERR_INVALID_PARAM: JNU_throwNewByName(jniEnv, "org/saforum/ais/AisInvalidParamException", AIS_ERR_INVALID_PARAM_MSG); break; case SA_AIS_ERR_NO_MEMORY: JNU_throwNewByName(jniEnv, "org/saforum/ais/AisNoMemoryException", AIS_ERR_NO_MEMORY_MSG); break; case SA_AIS_ERR_NO_RESOURCES: JNU_throwNewByName(jniEnv, "org/saforum/ais/AisNoResourcesException", AIS_ERR_NO_RESOURCES_MSG); break; default: // this should not happen here! assert(JNI_FALSE); JNU_throwNewByName(jniEnv, "org/saforum/ais/AisLibraryException", AIS_ERR_LIBRARY_MSG); break; } return; // EXIT POINT!!! } // normal exit _TRACE2 ("NATIVE: Java_org_opensaf_ais_amf_CsiManagerImpl_completedCsiQuiescing() returning normally\n"); }
void safAssignWork(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); printCSI(csiDescriptor, haState); /* * Take appropriate action based on state */ switch ( haState ) { /* AMF asks this process to take the standby HA state for the work described in the csiDescriptor variable */ case SA_AMF_HA_ACTIVE: { /* Typically you would spawn a thread here to initiate active processing of the work. */ if (csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL) { ClRcT rc; ClCpmCompCSIRefT csiRef = { 0 }; ClInt32T i; rc = clCpmCompCSIList((SaNameT *)compName, &csiRef); if(rc != CL_OK) { clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc); } else { for(i = 0; i < csiRef.numCSIs; ++i) { VirtualIpAddress temp; ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i]; clprintf(CL_LOG_SEV_INFO,"Comp [%s], CSI [%s], HA state [%s]", (const char*)compName->value, (const char*)pCSI->csiDescriptor.csiName.value, STRING_HA_STATE((ClUint32T)pCSI->haState)); GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp); AddRemVirtualAddress("up",&temp); } if(csiRef.pCSIList) clHeapFree(csiRef.pCSIList); } } else /* SA_AMF_CSI_ADD_ONE */ { GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); AddRemVirtualAddress("up",&gVirtualIp); } /* The AMF times the interval between the assignment and acceptance of the work (the time interval is configurable). So it is important to call this saAmfResponse function ASAP. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } /* AMF asks this process to take the standby HA state for the work described in the csiDescriptor variable */ case SA_AMF_HA_STANDBY: { /* If your standby has ongoing maintenance, you would spawn a thread here to do it. */ /* The AMF times the interval between the assignment and acceptance of the work (the time interval is configurable). So it is important to call this saAmfResponse function ASAP. */ GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); AddRemVirtualAddress("down",&gVirtualIp); /* Bring it down just in case it is up from a prior run */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ if (csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ONE) { AddRemVirtualAddress("down",&gVirtualIp); } else if (csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL) { ClRcT rc; ClCpmCompCSIRefT csiRef = { 0 }; ClInt32T i; rc = clCpmCompCSIList((SaNameT *)compName, &csiRef); if(rc != CL_OK) { clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc); } else { for(i = 0; i < csiRef.numCSIs; ++i) { VirtualIpAddress temp; ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i]; clprintf(CL_LOG_SEV_INFO,"Comp [%s ], CSI [%s], HA state [%s]", compName->value, pCSI->csiDescriptor.csiName.value, STRING_HA_STATE((ClUint32T)pCSI->haState)); GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp); AddRemVirtualAddress("down",&temp); } if(csiRef.pCSIList) clHeapFree(csiRef.pCSIList); } } else /* SA_AMF_CSI_ADD_ONE */ { VirtualIpAddress temp; GetVirtualAddressInfo(&csiDescriptor, &temp); AddRemVirtualAddress("down",&temp); } saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ /* There are two typical cases for quiescing. Chooose one! CASE 1: Its possible to quiesce rapidly within this thread context */ if (1) { /* App code here: Now finish your work and cleanly stop the work*/ /* Call saAmfCSIQuiescingComplete when stopping the work is done */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); } else { /* CASE 2: You can't quiesce within this thread context or quiesce rapidly. */ /* Respond immediately to the quiescing request */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); /* App code here: Signal or spawn a thread to cleanly stop the work*/ /* When that thread is done, it should call: saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); */ } break; } default: { assert(0); break; } } return; }
void clCompAppAMFCSISet(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* * Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); clCompAppAMFPrintCSI(csiDescriptor, haState); /* * Take appropriate action based on state */ switch ( haState ) { case SA_AMF_HA_ACTIVE: { /* * AMF has requested application to take the active HA state * for the CSI. */ if ((csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL)||(csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ONE)) { /* Do not reload the virtual address info for the "TARGET" flag -- the CSI is not filled in. We will use the values that were cached when the "standby" assignment occurred. */ } else /* CL_AMS_CSI_FLAG_ADD_ONE */ { GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); } AddRemVirtualAddress("up",&gVirtualIp); saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_STANDBY: { /* * AMF has requested application to take the standby HA state * for this CSI. */ GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); AddRemVirtualAddress("down",&gVirtualIp); /* Bring it down just in case it is up from a prior run */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ if ((csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL)||(csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ONE)) { AddRemVirtualAddress("down",&gVirtualIp); } else /* CL_AMS_CSI_FLAG_ADD_ONE */ { VirtualIpAddress temp; GetVirtualAddressInfo(&csiDescriptor, &temp); AddRemVirtualAddress("down",&temp); } saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); break; } default: { assert(0); break; } } return; }
void safAssignWork(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); printCSI(csiDescriptor, haState); /* * Take appropriate action based on state */ switch ( haState ) { /* AMF asks this process to take the standby HA state for the work described in the csiDescriptor variable */ case SA_AMF_HA_ACTIVE: { /* Typically you would spawn a thread here to initiate active processing of the work. */ if ((csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL )||(csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ONE)) { /* Do not reload the virtual address info for the "TARGET" flag -- the CSI is not filled in. We will use the values that were cached when the "standby" assignment occurred. */ } else /* SA_AMF_CSI_ADD_ONE */ { GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); } AddRemVirtualAddress("up",&gVirtualIp); /* The AMF times the interval between the assignment and acceptance of the work (the time interval is configurable). So it is important to call this saAmfResponse function ASAP. */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } /* AMF asks this process to take the standby HA state for the work described in the csiDescriptor variable */ case SA_AMF_HA_STANDBY: { /* If your standby has ongoing maintenance, you would spawn a thread here to do it. */ /* The AMF times the interval between the assignment and acceptance of the work (the time interval is configurable). So it is important to call this saAmfResponse function ASAP. */ GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); AddRemVirtualAddress("down",&gVirtualIp); saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ if ((csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL)||(csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ONE)) { AddRemVirtualAddress("down",&gVirtualIp); } else /* SA_AMF_CSI_ADD_ONE */ { VirtualIpAddress temp; GetVirtualAddressInfo(&csiDescriptor, &temp); AddRemVirtualAddress("down",&temp); } saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ /* There are two typical cases for quiescing. Chooose one! CASE 1: Its possible to quiesce rapidly within this thread context */ if (1) { /* App code here: Now finish your work and cleanly stop the work*/ /* Call saAmfCSIQuiescingComplete when stopping the work is done */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); } else { /* CASE 2: You can't quiesce within this thread context or quiesce rapidly. */ /* Respond immediately to the quiescing request */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); /* App code here: Signal or spawn a thread to cleanly stop the work*/ /* When that thread is done, it should call: saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); */ } break; } default: { assert(0); break; } } return; }
void clCompAppAMFCSISet(SaInvocationT invocation, const SaNameT *compName, SaAmfHAStateT haState, SaAmfCSIDescriptorT csiDescriptor) { /* * Print information about the CSI Set */ clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", compName->length, compName->value, mypid); clCompAppAMFPrintCSI(csiDescriptor, haState); /* * Take appropriate action based on state */ switch ( haState ) { case SA_AMF_HA_ACTIVE: { /* * AMF has requested application to take the active HA state * for the CSI. */ if (csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL) { ClRcT rc; ClCpmCompCSIRefT csiRef = { 0 }; ClInt32T i; rc = clCpmCompCSIList((SaNameT*)compName, &csiRef); if(rc != CL_OK) { clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc); } else { for(i = 0; i < csiRef.numCSIs; ++i) { VirtualIpAddress temp; ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i]; clprintf(CL_LOG_SEV_INFO,"Comp [%.*s], CSI [%.*s], HA state [%s]", compName->length, compName->value, pCSI->csiDescriptor.csiName.length, pCSI->csiDescriptor.csiName.value, STRING_HA_STATE((ClUint32T)pCSI->haState)); GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp); AddRemVirtualAddress("up",&temp); } if(csiRef.pCSIList) clHeapFree(csiRef.pCSIList); } } else /* CL_AMS_CSI_FLAG_ADD_ONE */ { GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); AddRemVirtualAddress("up",&gVirtualIp); } saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_STANDBY: { /* * AMF has requested application to take the standby HA state * for this CSI. */ GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp); AddRemVirtualAddress("down",&gVirtualIp); /* Bring it down just in case it is up from a prior run */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCED: { /* * AMF has requested application to quiesce the CSI currently * assigned the active or quiescing HA state. The application * must stop work associated with the CSI immediately. */ if (csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ONE) { AddRemVirtualAddress("down",&gVirtualIp); } else if (csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL) { ClRcT rc; ClCpmCompCSIRefT csiRef = { 0 }; ClInt32T i; rc = clCpmCompCSIList((SaNameT*)compName, &csiRef); if(rc != CL_OK) { clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc); } else { for(i = 0; i < csiRef.numCSIs; ++i) { VirtualIpAddress temp; ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i]; clprintf(CL_LOG_SEV_INFO,"Comp [%.*s], CSI [%.*s], HA state [%s]", compName->length, compName->value, pCSI->csiDescriptor.csiName.length, pCSI->csiDescriptor.csiName.value, STRING_HA_STATE((ClUint32T)pCSI->haState)); GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp); AddRemVirtualAddress("down",&temp); } if(csiRef.pCSIList) clHeapFree(csiRef.pCSIList); } } else /* CL_AMS_CSI_FLAG_ADD_ONE */ { VirtualIpAddress temp; GetVirtualAddressInfo(&csiDescriptor, &temp); AddRemVirtualAddress("down",&temp); } saAmfResponse(amfHandle, invocation, SA_AIS_OK); break; } case SA_AMF_HA_QUIESCING: { /* * AMF has requested application to quiesce the CSI currently * assigned the active HA state. The application must stop work * associated with the CSI gracefully and not accept any new * workloads while the work is being terminated. */ saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK); break; } default: { assert(0); break; } } return; }
/** * AMF invokes this callback to assign a new workload (ADD_ONE) or * to change state of an already assigned workload (TARGET_ALL). * The callback is used for the initial assignment, as a consequence * of admin operations and fail/switch-over * * See example sequence diagrams in chapter 10. * * @param invocation * @param comp_name * @param ha_state * @param csi_desc */ static void amf_csi_set_callback(SaInvocationT invocation, const SaNameT *comp_name, SaAmfHAStateT ha_state, SaAmfCSIDescriptorT csi_desc) { SaAisErrorT rc, error; SaAmfCSIAttributeT *attr; int i, status; if (csi_desc.csiFlags == SA_AMF_CSI_ADD_ONE) { syslog(LOG_INFO, "CSI Set - add '%s' HAState %s", csi_desc.csiName.value, ha_state_name[ha_state]); /* For debug log the CSI attributes, they could ** define the workload characteristics */ for (i = 0; i < csi_desc.csiAttr.number; i++) { attr = &csi_desc.csiAttr.attr[i]; syslog(LOG_DEBUG, "\tname: %s, value: %s", attr->attrName, attr->attrValue); } } else if (csi_desc.csiFlags == SA_AMF_CSI_TARGET_ALL) { syslog(LOG_INFO, "CSI Set - HAState %s for all assigned CSIs", ha_state_name[ha_state]); } else { syslog(LOG_INFO, "CSI Set - HAState %s for '%s'", ha_state_name[ha_state], csi_desc.csiName.value); } switch (ha_state) { case SA_AMF_HA_ACTIVE: status = foo_activate(); break; case SA_AMF_HA_STANDBY: /* * Not much to do in this simple example code * For real one could open a checkpoint for reads * Open a communication channel for listening * etc. */ status = 0; break; case SA_AMF_HA_QUIESCED: /* the effect of admin op lock on SU or node or ... */ status = foo_deactivate(); break; case SA_AMF_HA_QUIESCING: /* the effect of admin op lock on SU or node or ... */ status = 0; break; default: syslog(LOG_ERR, "unmanaged HA state %u", ha_state); status = -1; break; } if (status == 0) error = SA_AIS_OK; else error = SA_AIS_ERR_FAILED_OPERATION; rc = saAmfResponse(my_amf_hdl, invocation, error); if (rc != SA_AIS_OK) { syslog(LOG_ERR, "saAmfResponse FAILED - %u", rc); exit(1); } if (ha_state == SA_AMF_HA_QUIESCING) { /* "gracefully quiescing CSI work assignment" */ sleep(1); rc = saAmfCSIQuiescingComplete(my_amf_hdl, invocation, SA_AIS_OK); if (rc != SA_AIS_OK) { syslog(LOG_ERR, "saAmfCSIQuiescingComplete FAILED - %u", rc); exit(1); } rc = saAmfHAStateGet(my_amf_hdl, comp_name, &csi_desc.csiName, &my_ha_state); if (rc != SA_AIS_OK) { syslog(LOG_ERR, "saAmfHAStateGet FAILED - %u", rc); exit(1); } syslog(LOG_INFO, "My HA state is %s", ha_state_name[my_ha_state]); } }