Hi,

I don't understand what you are trying to solve, apparently not #517...

To solve #517 and for other reasons (#395), one possible solution is to use a 
helper IMM reader thread. Such thread can 
block and wait in TRYAGAIN loops longer than the main thread can. Another 
possible solution is that amfd sends the 
complete IMM configuration to amfnd which then can skip reading from IMM. That 
is going back to the 3.x behaviour. Not 
sure that is what we want.

But the first step is to correct the error handling in the amfnd init phase so 
that it just fails if reading from IMM 
fails. That is all failed IMM reads before nid_notify(...) should fail the 
amfnd/opensaf start. No core dump generated.

The second step could be to handle the IMM read error without generating a 
pointless core dump. This by adding an 
immutils error handler that calls exit() instead of abort().

The third step would be to add a reader thread. This is a rather major work and 
I am not sure it can be done as a defect.

An amfnd applier thread is my proposed solution for dealing with configuration 
changes that we currently do not support. 
See https://sourceforge.net/p/opensaf/tickets/539/

Thanks,
Hans


On 09/02/2013 03:27 PM, [email protected] wrote:
>   osaf/services/saf/avsv/avd/avd_su.c             |    4 +-
>   osaf/services/saf/avsv/avnd/Makefile.am         |    1 +
>   osaf/services/saf/avsv/avnd/avnd.c              |    4 +
>   osaf/services/saf/avsv/avnd/avnd_compdb.c       |    2 +-
>   osaf/services/saf/avsv/avnd/avnd_imm.c          |  608 
> ++++++++++++++++++++++++
>   osaf/services/saf/avsv/avnd/avnd_proc.c         |   14 +-
>   osaf/services/saf/avsv/avnd/avnd_sudb.c         |   12 +-
>   osaf/services/saf/avsv/avnd/include/avnd.h      |    1 +
>   osaf/services/saf/avsv/avnd/include/avnd_cb.h   |    2 +
>   osaf/services/saf/avsv/avnd/include/avnd_comp.h |    2 +
>   osaf/services/saf/immsv/immnd/immnd_evt.c       |    2 +
>   11 files changed, 645 insertions(+), 7 deletions(-)
>
>
> diff --git a/osaf/services/saf/avsv/avd/avd_su.c 
> b/osaf/services/saf/avsv/avd/avd_su.c
> --- a/osaf/services/saf/avsv/avd/avd_su.c
> +++ b/osaf/services/saf/avsv/avd/avd_su.c
> @@ -639,13 +639,13 @@ static void su_add_to_model(AVD_SU *su)
>                   (node->node_state == AVD_AVND_STATE_NO_CONFIG) ||
>                   (node->node_state == AVD_AVND_STATE_NCS_INIT)) {
>
> -                     if (avd_snd_su_msg(avd_cb, su) != NCSCC_RC_SUCCESS) {
> +                     /*if (avd_snd_su_msg(avd_cb, su) != NCSCC_RC_SUCCESS) {
>                               avd_node_remove_su(su);
>                               avd_sg_remove_su(su);
>
>                               LOG_ER("%s: avd_snd_su_msg failed %s", 
> __FUNCTION__, su->name.value);
>                               goto done;
> -                     }
> +                     }*/
>
>                       avd_su_oper_state_set(su, SA_AMF_OPERATIONAL_ENABLED);
>               } else
> diff --git a/osaf/services/saf/avsv/avnd/Makefile.am 
> b/osaf/services/saf/avsv/avnd/Makefile.am
> --- a/osaf/services/saf/avsv/avnd/Makefile.am
> +++ b/osaf/services/saf/avsv/avnd/Makefile.am
> @@ -66,6 +66,7 @@ osafamfnd_SOURCES = \
>       avnd_verify.c \
>       avnd_avnd.c \
>       avnd_proxy.c \
> +     avnd_imm.c \
>       avnd_proxydb.c
>
>   osafamfnd_LDADD = \
> diff --git a/osaf/services/saf/avsv/avnd/avnd.c 
> b/osaf/services/saf/avsv/avnd/avnd.c
> --- a/osaf/services/saf/avsv/avnd/avnd.c
> +++ b/osaf/services/saf/avsv/avnd/avnd.c
> @@ -150,6 +150,10 @@ uint32_t avnd_create(void)
>               goto done;
>       }
>
> +        if (avnd_imm_init(cb) != SA_AIS_OK) {
> +                LOG_ER("avnd_imm_init FAILED");
> +                goto done;
> +        }
>   done:
>       /* if failed, perform the cleanup */
>       if (NCSCC_RC_SUCCESS != rc)
> diff --git a/osaf/services/saf/avsv/avnd/avnd_compdb.c 
> b/osaf/services/saf/avsv/avnd/avnd_compdb.c
> --- a/osaf/services/saf/avsv/avnd/avnd_compdb.c
> +++ b/osaf/services/saf/avsv/avnd/avnd_compdb.c
> @@ -1583,7 +1583,7 @@ void avnd_comp_delete(AVND_COMP *comp)
>    *
>    * @return AVND_COMP*
>    */
> -static AVND_COMP *avnd_comp_create(const SaNameT *comp_name, const 
> SaImmAttrValuesT_2 **attributes, AVND_SU *su)
> +AVND_COMP *avnd_comp_create(const SaNameT *comp_name, const 
> SaImmAttrValuesT_2 **attributes, AVND_SU *su)
>   {
>       int rc = -1;
>       AVND_COMP *comp;
> diff --git a/osaf/services/saf/avsv/avnd/avnd_imm.c 
> b/osaf/services/saf/avsv/avnd/avnd_imm.c
> new file mode 100644
> --- /dev/null
> +++ b/osaf/services/saf/avsv/avnd/avnd_imm.c
> @@ -0,0 +1,608 @@
> +/*      -*- OpenSAF  -*-
> + *
> + * (C) Copyright 2008 The OpenSAF Foundation
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> + * under the GNU Lesser General Public License Version 2.1, February 1999.
> + * The complete license can be accessed from the following location:
> + * http://opensource.org/licenses/lgpl-license.php
> + * See the Copying file included with the OpenSAF distribution for full
> + * licensing terms.
> + *
> + * Author(s): Emerson Network Power
> + *
> + */
> +
> +/*****************************************************************************
> +  FUNCTIONS INCLUDED in this module:
> +
> +******************************************************************************
> +*/
> +
> +/*
> + * Module Inclusion Control...
> + */
> +
> +#include <logtrace.h>
> +#include <immutil.h>
> +
> +#include "avnd.h"
> +
> +/* ========================================================================
> + *   DATA DECLARATIONS
> + * ========================================================================
> + */
> +extern void comp_ccb_apply_cb(CcbUtilOperationData_t *opdata);
> +typedef enum {
> +     AVND_SA_AMF_CLASS_INVALID = 0,
> +     AVND_SA_AMF_COMP = 1,
> +     AVND_SA_AMF_CLASS_MAX
> +} AVND_AMF_SUBS_CLASS_ID;
> +
> +typedef void (*AvndImmOiCcbApplyCallbackT) (CcbUtilOperationData_t *opdata);
> +typedef SaAisErrorT (*AvndImmOiCcbCompletedCallbackT) 
> (CcbUtilOperationData_t *opdata);
> +
> +typedef struct avnd_ccb_apply_ordered_list {
> +        AvndImmOiCcbApplyCallbackT ccb_apply_cb;
> +        CcbUtilOperationData_t *opdata;
> +        AVND_AMF_SUBS_CLASS_ID class_type;
> +        struct avnd_ccb_apply_ordered_list *next_ccb_to_apply;
> +} AvndCcbApplyOrderedListT;
> +
> +static const SaImmOiImplementerNameT implementerName =
> +        (SaImmOiImplementerNameT)"safAmfService";
> +static SaVersionT immVersion = { 'A', 2, 11 };
> +
> +/* This string array must match the AVND_AMF_SUBS_CLASS_ID enum */
> +static char *avnd_class_names[] = {
> +     "Invalid",
> +     "SaAmfComp"
> +};
> +
> +static void ccb_abort_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id);
> +static void ccb_apply_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id);
> +static SaAisErrorT ccb_completed_cb(SaImmOiHandleT immoi_handle, 
> SaImmOiCcbIdT ccb_id);
> +static SaAisErrorT comp_ccb_completed_cb(CcbUtilOperationData_t *opdata);
> +
> +static SaAisErrorT ccb_object_create_cb(SaImmOiHandleT immoi_handle,
> +        SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
> +        const SaNameT *parent_name, const SaImmAttrValuesT_2 **attr);
> +static SaAisErrorT ccb_object_modify_cb(SaImmOiHandleT immoi_handle,
> +        SaImmOiCcbIdT ccb_id, const SaNameT *object_name,
> +        const SaImmAttrModificationT_2 **attr_mods);
> +static SaAisErrorT ccb_object_delete_cb(SaImmOiHandleT immoi_handle,
> +        SaImmOiCcbIdT ccb_id, const SaNameT *object_name);
> +
> +static const SaImmOiCallbacksT_2 avnd_callbacks = {
> +        .saImmOiAdminOperationCallback = NULL,
> +        .saImmOiCcbAbortCallback = ccb_abort_cb,
> +        .saImmOiCcbApplyCallback = ccb_apply_cb,
> +        .saImmOiCcbCompletedCallback = ccb_completed_cb,
> +        .saImmOiCcbObjectCreateCallback = ccb_object_create_cb,
> +        .saImmOiCcbObjectDeleteCallback = ccb_object_delete_cb,
> +        .saImmOiCcbObjectModifyCallback = ccb_object_modify_cb,
> +        .saImmOiRtAttrUpdateCallback = NULL
> +};
> +
> +static AvndImmOiCcbCompletedCallbackT 
> ccb_completed_callback[AVND_SA_AMF_CLASS_MAX];
> +static AvndImmOiCcbApplyCallbackT ccb_apply_callback[AVND_SA_AMF_CLASS_MAX];
> +
> +static AvndCcbApplyOrderedListT *ccb_apply_list;
> +
> +
> +static AVND_AMF_SUBS_CLASS_ID class_name_to_class_type(const SaImmClassNameT 
> className)
> +{
> +        int i;
> +
> +        for (i = 0; i < AVND_SA_AMF_CLASS_MAX; i++) {
> +                if (strcmp(className, avnd_class_names[i]) == 0)
> +                        return i;
> +        }
> +
> +        osafassert(0);
> +        return AVND_SA_AMF_CLASS_MAX;
> +}
> +
> +void avnd_class_impl_set(const SaImmClassNameT className,
> +        SaImmOiRtAttrUpdateCallbackT rtattr_cb, 
> SaImmOiAdminOperationCallbackT_2 adminop_cb,
> +        AvndImmOiCcbCompletedCallbackT ccb_compl_cb, 
> AvndImmOiCcbApplyCallbackT ccb_apply_cb)
> +{
> +        AVND_AMF_SUBS_CLASS_ID type = class_name_to_class_type(className);
> +
> +        ccb_completed_callback[type] = ccb_compl_cb;
> +        ccb_apply_callback[type] = ccb_apply_cb;
> +}
> +
> +/*****************************************************************************
> + * @brief               This function becomes applier and sets the applier 
> name
> + *                      for all AMF objects
> + *
> + * @param[in]           Nothing
> + *
> + * @return              SA_AIS_OK or error
> + *
> + **************************************************************************/
> +SaAisErrorT avnd_imm_applier_set(void)
> +{
> +        SaAisErrorT rc = SA_AIS_OK;
> +        uint32_t i;
> +        char applier_name[SA_MAX_NAME_LENGTH] = {0};
> +
> +        TRACE_ENTER();
> +        snprintf(applier_name, SA_MAX_NAME_LENGTH, "@safAmfService%x", 
> ncs_get_node_id());
> +
> +        if ((rc = immutil_saImmOiImplementerSet(avnd_cb->immOiHandle, 
> applier_name)) != SA_AIS_OK) {
> +                LOG_ER("saImmOiImplementerSet failed %u", rc);
> +                return rc;
> +        }
> +
> +        for (i = 0; i < AVND_SA_AMF_CLASS_MAX - 1; i++) {
> +                rc = 
> immutil_saImmOiClassImplementerSet(avnd_cb->immOiHandle, 
> avnd_class_names[i+1]);
> +             LOG_ER("Impl Set Failed for %s, returned %d",   
> avnd_class_names[i+1], rc);
> +                if(rc != SA_AIS_OK) {
> +                        LOG_ER("Impl Set Failed for %s, returned %d",   
> avnd_class_names[i+1], rc);
> +                        break;
> +                }
> +        }
> +
> +        TRACE_LEAVE2("%u", rc);
> +        return rc;
> +}
> +
> +/*****************************************************************************
> + * Function: avnd_imm_init
> + *
> + * Purpose: This function Initialize the OI interface and get a selection
> + *          object.
> + *
> + * Input: cb  - AVND control block
> + *
> + * Returns: Void pointer.
> + *
> + * NOTES: None.
> + *
> + **************************************************************************/
> +
> +SaAisErrorT avnd_imm_init(AVND_CB *cb)
> +{
> +        SaAisErrorT error = SA_AIS_OK;
> +        TRACE_ENTER();
> +
> +        if ((error = immutil_saImmOiInitialize_2(&cb->immOiHandle, 
> &avnd_callbacks, &immVersion)) != SA_AIS_OK) {
> +                LOG_ER("saImmOiInitialize failed %u", error);
> +                goto done;
> +        }
> +
> +        if ((error = immutil_saImmOiSelectionObjectGet(cb->immOiHandle, 
> &cb->imm_sel_obj)) != SA_AIS_OK) {
> +                LOG_ER("saImmOiSelectionObjectGet failed %u", error);
> +                goto done;
> +        }
> +     avnd_class_impl_set("SaAmfComp", NULL, NULL,
> +                     comp_ccb_completed_cb, comp_ccb_apply_cb);
> +     avnd_imm_applier_set();
> +        TRACE("Successfully initialized IMM");
> +
> +done:
> +        TRACE_LEAVE();
> +        return error;
> +}
> +
> +/*****************************************************************************
> + * Function: avnd_class_type_find
> + *
> + * Purpose: This function returns class enum corresponding to Object name.
> + *
> + * Input: cb  - Object Name, Class type.
> + *
> + * Returns: OK/Error.
> + *
> + * NOTES: None.
> + *
> + **************************************************************************/
> +static AVND_AMF_SUBS_CLASS_ID object_name_to_class_type(const SaNameT 
> *obj_name)
> +{
> +     AVND_AMF_SUBS_CLASS_ID class_type = AVND_SA_AMF_CLASS_MAX;
> +
> +     if (strncmp((char *)&obj_name->value, "safComp=", 8) == 0) {
> +             class_type = AVND_SA_AMF_COMP;
> +     }
> +
> +     return class_type;
> +}
> +
> +/*****************************************************************************
> + * Function: ccb_completed_cb
> + *
> + * Purpose: This function handles completed callback for the corresponding
> + *          CCB operation.
> + *
> + * Input: cb  - Oi Handle and Ccb Id.
> + *
> + * Returns: Ok/Error.
> + *
> + * NOTES: None.
> + *
> + **************************************************************************/
> +static SaAisErrorT ccb_completed_cb(SaImmOiHandleT immoi_handle,
> +        SaImmOiCcbIdT ccb_id)
> +{
> +        SaAisErrorT rc = SA_AIS_OK;
> +        CcbUtilOperationData_t *opdata = NULL;
> +        AVND_AMF_SUBS_CLASS_ID type;
> +
> +        TRACE_ENTER2("CCB ID %llu", ccb_id);
> +
> +        /* "check that the sequence of change requests contained in the CCB 
> is
> +           valid and that no errors will be generated when these changes
> +           are applied." */
> +
> +     while ((opdata = ccbutil_getNextCcbOp(ccb_id, opdata)) != NULL) {
> +             type = object_name_to_class_type(&opdata->objectName);
> +             rc = ccb_completed_callback[type](opdata);
> +
> +             /* Get out at first error */
> +                if (rc != SA_AIS_OK)
> +                        break;
> +        }
> +
> +        TRACE_LEAVE2("%u", rc);
> +        return rc;
> +}
> +
> +/*****************************************************************************
> + * Function: ccb_object_create_cb
> + *
> + * Purpose: This function handles object create callback for all config 
> classes.
> + *          Its purpose is to memorize the request until the completed 
> callback.
> + *
> + * Input: cb  - Oi Handle, Ccb Id, Class Name, Parent Name, Attributes.
> + *
> + * Returns: Ok/Error.
> + *
> + * NOTES: None.
> + *
> + **************************************************************************/
> +static SaAisErrorT ccb_object_create_cb(SaImmOiHandleT immoi_handle,
> +        SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
> +        const SaNameT *parent_name, const SaImmAttrValuesT_2 **attr)
> +{
> +        SaAisErrorT rc = SA_AIS_OK;
> +        CcbUtilCcbData_t *ccb_util_ccb_data;
> +        CcbUtilOperationData_t *operation;
> +        int i = 0;
> +        const SaImmAttrValuesT_2 *attrValue;
> +        AVND_AMF_SUBS_CLASS_ID id_from_class_name, id_from_dn;
> +
> +        TRACE_ENTER2("CCB ID %llu, class %s, parent '%s'", ccb_id, 
> class_name, parent_name->value);
> +
> +        if ((ccb_util_ccb_data = ccbutil_getCcbData(ccb_id)) == NULL) {
> +                LOG_ER("Failed to get CCB object for %llu", ccb_id);
> +                rc = SA_AIS_ERR_NO_MEMORY;
> +                goto done;
> +        }
> +
> +        operation = ccbutil_ccbAddCreateOperation(ccb_util_ccb_data, 
> class_name, parent_name, attr);
> +
> +        if (operation == NULL) {
> +                LOG_ER("Failed to get CCB operation object for %llu", 
> ccb_id);
> +                rc = SA_AIS_ERR_NO_MEMORY;
> +                goto done;
> +        }
> +
> +        /* Find the RDN attribute and store the object DN */
> +        while ((attrValue = attr[i++]) != NULL) {
> +                if (!strncmp(attrValue->attrName, "saf", 3)) {
> +                        if (attrValue->attrValueType == 
> SA_IMM_ATTR_SASTRINGT) {
> +                                SaStringT rdnVal = *((SaStringT 
> *)attrValue->attrValues[0]);
> +                                if ((parent_name != NULL) && 
> (parent_name->length > 0)) {
> +                                        operation->objectName.length = 
> sprintf((char *)operation->objectName.value,
> +                                                "%s,%s", rdnVal, 
> parent_name->value);
> +                                } else {
> +                                        operation->objectName.length = 
> sprintf((char *)operation->objectName.value,
> +                                                "%s", rdnVal);
> +                                }
> +                        } else {
> +                                SaNameT *rdnVal = ((SaNameT 
> *)attrValue->attrValues[0]);
> +                                operation->objectName.length = sprintf((char 
> *)operation->objectName.value,
> +                                        "%s,%s", rdnVal->value, 
> parent_name->value);
> +                        }
> +
> +                        TRACE("%s(%u)", operation->objectName.value, 
> operation->objectName.length);
> +                }
> +        }
> +
> +        if (operation->objectName.length == 0) {
> +                LOG_ER("Malformed DN %llu", ccb_id);
> +                rc = SA_AIS_ERR_INVALID_PARAM;
> +        }
> +
> +        /* Verify that DN is valid for class */
> +        id_from_class_name = class_name_to_class_type(class_name);
> +        id_from_dn = object_name_to_class_type(&operation->objectName);
> +        if (id_from_class_name != id_from_dn) {
> +                LOG_ER("Illegal DN '%s' for class '%s'", 
> operation->objectName.value, class_name);
> +                rc = SA_AIS_ERR_INVALID_PARAM;
> +        }
> +
> +done:
> +        return rc;
> +}
> +
> +/*****************************************************************************
> + * Function: ccb_abort_cb
> + *
> + * Purpose: This function handles abort callback for the corresponding
> + *          CCB operation.
> + *
> + * Input: cb  - Oi Handle and Ccb Id.
> + *
> + * Returns: None.
> + *
> + * NOTES: None.
> + *
> + **************************************************************************/
> +static void ccb_abort_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id)
> +{
> +        CcbUtilCcbData_t *ccb_util_ccb_data;
> +
> +        TRACE_ENTER2("CCB ID %llu", ccb_id);
> +
> +        /* Return CCB container memory */
> +        ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
> +        osafassert(ccb_util_ccb_data);
> +        ccbutil_deleteCcbData(ccb_util_ccb_data);
> +
> +        TRACE_LEAVE();
> +}
> +
> +/*****************************************************************************
> + * Function: ccb_insert_ordered_list
> + *
> + * Purpose: This function sorts the Ccb apply callbacks for the correponding
> + *          CCB operation in order of dependency/heirarchy
> + *
> + * Input: ccb_apply_cb - apply callback for specific object
> + *        opdata - Ccb Operation data
> + *
> + * Returns: None.
> + *
> + * NOTES: None.
> + *
> + **************************************************************************/
> +static void ccb_insert_ordered_list(AvndImmOiCcbApplyCallbackT ccb_apply_cb,
> +             CcbUtilOperationData_t *opdata, AVND_AMF_SUBS_CLASS_ID type)
> +{
> +        AvndCcbApplyOrderedListT *temp = NULL;
> +        AvndCcbApplyOrderedListT *prev = NULL;
> +        AvndCcbApplyOrderedListT *next = NULL;
> +
> +        /* allocate memory */
> +
> +        temp = malloc(sizeof(AvndCcbApplyOrderedListT));
> +
> +        temp->ccb_apply_cb = ccb_apply_cb;
> +        temp->opdata = opdata;
> +        temp->class_type = type;
> +        temp->next_ccb_to_apply = NULL;
> +
> +        /* ccbs are sorted in top-down order in create/modify operations and
> +         * sorted in bottom-up order for delete operation. All the ccbs are
> +         * appended to a single list in the order of create operations first
> +         * then modify operations and lastly delete operations
> +         */
> +
> +        switch (opdata->operationType) {
> +        case CCBUTIL_CREATE:
> +                next = ccb_apply_list;
> +                while (next != NULL) {
> +                        if((next->opdata->operationType != CCBUTIL_CREATE) ||
> +                                        (next->class_type > 
> temp->class_type))
> +                                break;
> +                        prev = next;
> +                        next = next->next_ccb_to_apply;
> +                }
> +                /* insert the ccb */
> +                if (prev != NULL)
> +                        prev->next_ccb_to_apply = temp;
> +                else
> +                        ccb_apply_list = temp;
> +
> +                temp->next_ccb_to_apply = next;
> +                break;
> +
> +        case CCBUTIL_MODIFY:
> +                next = ccb_apply_list;
> +
> +                /* traverse to the end of all the create CCBs */
> +                while (next && next->opdata->operationType == 
> CCBUTIL_CREATE) {
> +                        prev = next;
> +                        next = next->next_ccb_to_apply;
> +                }
> +
> +                while (next != NULL) {
> +                        if((next->opdata->operationType != CCBUTIL_MODIFY) ||
> +                                        (next->class_type > 
> temp->class_type))
> +                                break;
> +                        prev = next;
> +                        next = next->next_ccb_to_apply;
> +                }
> +                /* insert the ccb */
> +                if (prev != NULL)
> +                        prev->next_ccb_to_apply = temp;
> +                else
> +                        ccb_apply_list = temp;
> +
> +                temp->next_ccb_to_apply = next;
> +                break;
> +
> +        case CCBUTIL_DELETE:
> +                next = ccb_apply_list;
> +
> +                /* traverse to the end of all the create CCBs */
> +                while (next && next->opdata->operationType == 
> CCBUTIL_CREATE) {
> +                        prev = next;
> +                        next = next->next_ccb_to_apply;
> +                }
> +
> +                /* traverse to the end of all the modify CCBs */
> +                while (next && next->opdata->operationType == 
> CCBUTIL_MODIFY) {
> +                        prev = next;
> +                        next = next->next_ccb_to_apply;
> +                }
> +                /* insert the ccb */
> +                if (prev != NULL)
> +                        prev->next_ccb_to_apply = temp;
> +                else
> +                        ccb_apply_list = temp;
> +
> +                temp->next_ccb_to_apply = next;
> +                break;
> +
> +        default:
> +                osafassert(0);
> +                        break;
> +        }
> +}
> +
> +/*****************************************************************************
> + * Function: ccb_apply_cb
> + *
> + * Purpose: This function handles apply callback for the correponding
> + *          CCB operation.
> + *
> + * Input: cb  - Oi Handle and Ccb Id.
> + *
> + * Returns: None.
> + *
> + * NOTES: None.
> + *
> + **************************************************************************/
> +static void ccb_apply_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id)
> +{
> +        CcbUtilCcbData_t *ccb_util_ccb_data;
> +        CcbUtilOperationData_t *opdata = NULL;
> +        AVND_AMF_SUBS_CLASS_ID type;
> +        AvndCcbApplyOrderedListT *next = NULL;
> +        AvndCcbApplyOrderedListT *temp = NULL;
> +
> +        TRACE_ENTER2("CCB ID %llu", ccb_id);
> +
> +        while ((opdata = ccbutil_getNextCcbOp(ccb_id, opdata)) != NULL) {
> +                type = object_name_to_class_type(&opdata->objectName);
> +                /* Base types will not have an apply callback, skip empty 
> ones */
> +                if (ccb_apply_callback[type] != NULL) {
> +                        /* insert the apply callback into the sorted list
> +                         * to be applied later, after all the ccb apply
> +                         * callback are sorted as required by the internal
> +                         * AMFD's information model
> +                         */
> +                     ccb_insert_ordered_list(ccb_apply_callback[type], 
> opdata, type);
> +
> +                     switch (opdata->operationType) {
> +                             case CCBUTIL_CREATE:
> +                                     LOG_NO("CCB %llu Created %s", ccb_id, 
> opdata->objectName.value);
> +                                     break;
> +                             case CCBUTIL_MODIFY:
> +                                     LOG_NO("CCB %llu Modified %s", ccb_id, 
> opdata->objectName.value);
> +                                     break;
> +                             case CCBUTIL_DELETE:
> +                                     LOG_NO("CCB %llu Deleted %s", ccb_id, 
> opdata->objectName.value);
> +                                     break;
> +                             default:
> +                                     osafassert(0);
> +                     }
> +             }
> +     }
> +
> +        /* First pass: apply all the CCBs in the sorted order */
> +        next = ccb_apply_list;
> +        while (next != NULL) {
> +                next->ccb_apply_cb(next->opdata);
> +                temp = next;
> +                next = next->next_ccb_to_apply;
> +        }
> +
> +        /* Second pass: free allocated memory */
> +        next = ccb_apply_list;
> +        while (next != NULL) {
> +                temp = next;
> +                next = next->next_ccb_to_apply;
> +                free(temp);
> +        }
> +
> +        ccb_apply_list = NULL;
> +
> +        /* Return CCB container memory */
> +        ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
> +        osafassert(ccb_util_ccb_data);
> +        ccbutil_deleteCcbData(ccb_util_ccb_data);
> +        TRACE_LEAVE();
> +}
> +
> +void comp_create_dyn(const SaNameT *comp_name, const SaImmAttrValuesT_2 
> **attributes)
> +{
> +        AVSV_SU_INFO_MSG info;
> +        AVND_SU *su;
> +        uint32_t rc = NCSCC_RC_SUCCESS;
> +        TRACE_ENTER();
> +
> +        memset(&info, 0, sizeof(AVSV_SU_INFO_MSG));
> +        avsv_sanamet_init(comp_name, &info.name, "safSu");
> +
> +        /* get the su */
> +        su = m_AVND_SUDB_REC_GET(avnd_cb->sudb, info.name);
> +        if (!su) {
> +                TRACE("SU'%s', not found in DB",info.name.value);
> +                su = avnd_sudb_rec_add(avnd_cb, &info, &rc);
> +        }
> +
> +        avnd_comp_create(comp_name, attributes, su);
> +}
> +
> +void comp_ccb_apply_cb(CcbUtilOperationData_t *opdata)
> +{
> +
> +        TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId, 
> opdata->objectName.value);
> +
> +        switch (opdata->operationType) {
> +        case CCBUTIL_CREATE:
> +                comp_create_dyn(&opdata->objectName, 
> opdata->param.create.attrValues);
> +                break;
> +        default:
> +                osafassert(0);
> +                break;
> +        }
> +
> +        TRACE_LEAVE();
> +}
> +
> +static SaAisErrorT comp_ccb_completed_cb(CcbUtilOperationData_t *opdata)
> +{
> +        SaAisErrorT rc = SA_AIS_OK;
> +     TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId, 
> opdata->objectName.value);
> +        TRACE_LEAVE2("%u", rc);
> +        return rc;
> +}
> +
> +static SaAisErrorT ccb_object_delete_cb(SaImmOiHandleT immoi_handle,
> +        SaImmOiCcbIdT ccb_id, const SaNameT *object_name)
> +{
> +     TRACE_ENTER2("CCB ID %llu, %s, %llu", ccb_id, object_name->value, 
> immoi_handle);
> +
> +
> +        return SA_AIS_OK;
> +}
> +
> +
> +static SaAisErrorT ccb_object_modify_cb(SaImmOiHandleT immoi_handle,
> +        SaImmOiCcbIdT ccb_id, const SaNameT *object_name,
> +        const SaImmAttrModificationT_2 **attr_mods)
> +{
> +
> +        TRACE_ENTER2("CCB ID %llu, %s", ccb_id, object_name->value);
> +
> +        return SA_AIS_OK;
> +}
> +
> diff --git a/osaf/services/saf/avsv/avnd/avnd_proc.c 
> b/osaf/services/saf/avsv/avnd/avnd_proc.c
> --- a/osaf/services/saf/avsv/avnd/avnd_proc.c
> +++ b/osaf/services/saf/avsv/avnd/avnd_proc.c
> @@ -51,6 +51,7 @@
>   #define FD_TERM  1
>   #define FD_CLM   2
>   #define FD_MBCSV 3
> +#define FD_IMM 4
>
>   static NCS_SEL_OBJ term_sel_obj; /* Selection object for TERM signal events 
> */
>
> @@ -158,8 +159,8 @@ static void sigterm_handler(int sig)
>   void avnd_main_process(void)
>   {
>       NCS_SEL_OBJ mbx_fd;
> -     struct pollfd fds[4];
> -     nfds_t nfds = 3;
> +     struct pollfd fds[5];
> +     nfds_t nfds = 5;
>       AVND_EVT *evt;
>
>       TRACE_ENTER();
> @@ -187,8 +188,12 @@ void avnd_main_process(void)
>
>       fds[FD_CLM].fd = avnd_cb->clm_sel_obj;
>       fds[FD_CLM].events = POLLIN;
> +
> +     fds[FD_IMM].fd = avnd_cb->imm_sel_obj;
> +     fds[FD_IMM].events = POLLIN;
>
>   #if FIXME
> +     TRACE_ENTER2("Hello");
>       if (avnd_cb->type == AVSV_AVND_CARD_SYS_CON) {
>               fds[FD_MBCSV].fd = avnd_cb->avnd_mbcsv_sel_obj;
>               fds[FD_MBCSV].events = POLLIN;
> @@ -224,6 +229,11 @@ void avnd_main_process(void)
>                       avnd_sigterm_handler();
>               }
>
> +             if (fds[FD_IMM].revents & POLLIN) {
> +                     TRACE("IMM event");
> +                     saImmOiDispatch(avnd_cb->immOiHandle, SA_DISPATCH_ALL);
> +             }
> +
>   #if FIXME
>               if ((avnd_cb->type == AVSV_AVND_CARD_SYS_CON) &&
>                   (fds[FD_MBCSV].revents & POLLIN)) {
> diff --git a/osaf/services/saf/avsv/avnd/avnd_sudb.c 
> b/osaf/services/saf/avsv/avnd/avnd_sudb.c
> --- a/osaf/services/saf/avsv/avnd/avnd_sudb.c
> +++ b/osaf/services/saf/avsv/avnd/avnd_sudb.c
> @@ -119,9 +119,17 @@ AVND_SU *avnd_sudb_rec_add(AVND_CB *cb,
>       AVND_SU *su = 0;
>       TRACE_ENTER2("SU'%s'", info->name.value);
>       /* verify if this su is already present in the db */
> -     if (0 != m_AVND_SUDB_REC_GET(cb->sudb, info->name)) {
> +     if (su != m_AVND_SUDB_REC_GET(cb->sudb, info->name)) {
>               *rc = AVND_ERR_DUP_SU;
> -             goto err;
> +             /* update error recovery escalation parameters */
> +             su->comp_restart_prob = info->comp_restart_prob;
> +             su->comp_restart_max = info->comp_restart_max;
> +             su->su_restart_prob = info->su_restart_prob;
> +             su->su_restart_max = info->su_restart_max;
> +             /* update the NCS flag */
> +             su->is_ncs = info->is_ncs;
> +             su->su_is_external = info->su_is_external;
> +             return su;
>       }
>
>       /* a fresh su... */
> diff --git a/osaf/services/saf/avsv/avnd/include/avnd.h 
> b/osaf/services/saf/avsv/avnd/include/avnd.h
> --- a/osaf/services/saf/avsv/avnd/include/avnd.h
> +++ b/osaf/services/saf/avsv/avnd/include/avnd.h
> @@ -34,6 +34,7 @@
>   #define AVND_H
>
>   #include <saImmOm.h>
> +#include <saImmOi.h>
>
>   #include "avsv.h"
>   #include "ncs_main_papi.h"
> diff --git a/osaf/services/saf/avsv/avnd/include/avnd_cb.h 
> b/osaf/services/saf/avsv/avnd/include/avnd_cb.h
> --- a/osaf/services/saf/avsv/avnd/include/avnd_cb.h
> +++ b/osaf/services/saf/avsv/avnd/include/avnd_cb.h
> @@ -130,6 +130,8 @@ typedef struct avnd_cb_tag {
>       SaBoolT first_time_up;
>       bool reboot_in_progress;
>       AVND_SU *failed_su;
> +     SaImmOiHandleT immOiHandle;
> +     SaSelectionObjectT imm_sel_obj; /*Selection object to wait for IMM 
> events */
>   } AVND_CB;
>
>   #define AVND_CB_NULL ((AVND_CB *)0)
> diff --git a/osaf/services/saf/avsv/avnd/include/avnd_comp.h 
> b/osaf/services/saf/avsv/avnd/include/avnd_comp.h
> --- a/osaf/services/saf/avsv/avnd/include/avnd_comp.h
> +++ b/osaf/services/saf/avsv/avnd/include/avnd_comp.h
> @@ -879,6 +879,8 @@ extern unsigned int avnd_comp_config_get
>   extern int avnd_comp_config_reinit(AVND_COMP *comp);
>   extern void avnd_comp_delete(AVND_COMP *comp);
>   extern void avnd_comp_pres_state_set(AVND_COMP *comp, SaAmfPresenceStateT 
> newstate);
> +extern SaAisErrorT avnd_imm_init(struct avnd_cb_tag *cb);
> +struct avnd_comp_tag *avnd_comp_create(const SaNameT *comp_name, const 
> SaImmAttrValuesT_2 **attributes, struct avnd_su_tag *su);
>
>   /**
>    * Initiate restart of a component.
> diff --git a/osaf/services/saf/immsv/immnd/immnd_evt.c 
> b/osaf/services/saf/immsv/immnd/immnd_evt.c
> --- a/osaf/services/saf/immsv/immnd/immnd_evt.c
> +++ b/osaf/services/saf/immsv/immnd/immnd_evt.c
> @@ -4664,6 +4664,8 @@ static void immnd_evt_proc_object_create
>                                                  oi_cl_node->agent_mds_dest,
>                                                  &send_evt) != 
> NCSCC_RC_SUCCESS) {
>                                       LOG_WA("Create upcall for applier 
> failed");
> +                             }else{
> +                                     LOG_WA("Sending call to applier:");
>                               }
>                       }
>
>
>

------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to