Beispiel #1
0
/****************************************************************************
 * Name          : gld_add_glnd_node
 * Description   : Adds node_details info to the gld_cb and initilizes
                   node_details->rsc_info_tree
 *
 * Arguments     :GLSV_GLD_CB, glnd_mds_dest
 *
 * Return Values :
 *
 * Notes         : None.
 *****************************************************************************/
GLSV_GLD_GLND_DETAILS *gld_add_glnd_node(GLSV_GLD_CB *gld_cb, MDS_DEST glnd_mds_dest)
{
    GLSV_GLD_GLND_DETAILS *node_details;
    NCS_PATRICIA_PARAMS params = { sizeof(uns32) };

    /* Need to add the node details */
    node_details = m_MMGR_ALLOC_GLSV_GLD_GLND_DETAILS;
    if (node_details == NULL) {
        m_LOG_GLD_MEMFAIL(GLD_NODE_DETAILS_ALLOC_FAILED, __FILE__, __LINE__);
        return NULL;
    }
    memset(node_details, 0, sizeof(GLSV_GLD_GLND_DETAILS));

    memcpy(&node_details->dest_id, &glnd_mds_dest, sizeof(MDS_DEST));
    node_details->node_id = m_NCS_NODE_ID_FROM_MDS_DEST(glnd_mds_dest);
    node_details->status = GLND_OPERATIONAL_STATE;

    m_LOG_GLD_EVT(GLD_EVT_MDS_GLND_UP, NCSFL_SEV_NOTICE, __FILE__, __LINE__, 0, node_details->node_id);

    /* Initialize the pat tree for resource info */
    if ((ncs_patricia_tree_init(&node_details->rsc_info_tree, &params))
            != NCSCC_RC_SUCCESS) {
        m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_INIT_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__, 0);
        m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
        return NULL;
    }
    node_details->pat_node.key_info = (uns8 *)&node_details->node_id;
    if (ncs_patricia_tree_add(&gld_cb->glnd_details, &node_details->pat_node)
            != NCSCC_RC_SUCCESS) {
        m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_ADD_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__, 0);
        m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
        return NULL;
    }
    return node_details;
}
Beispiel #2
0
/*****************************************************************************
  PROCEDURE NAME : gld_process_tmr_node_restart_wait_timeout

  DESCRIPTION    :

  ARGUMENTS      :gld_cb      - ptr to the GLD control block
                  evt          - ptr to the event.

  RETURNS        :NCSCC_RC_FAILURE/NCSCC_RC_SUCCESS

  NOTES         : None
*****************************************************************************/
static uns32 gld_process_tmr_node_restart_wait_timeout(GLSV_GLD_EVT *evt)
{
    GLSV_GLD_CB *gld_cb = evt->gld_cb;
    GLSV_GLD_GLND_DETAILS *node_details;
    GLSV_GLD_GLND_RSC_REF *glnd_rsc;
    SaLckResourceIdT rsc_id;
    uns32 node_id;

    node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.tmr.mdest_id);
    m_LOG_GLD_HEADLINE(GLD_ND_RESTART_WAIT_TMR_EXP, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id);

    if ((node_details =
                (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uns8 *)&node_id)) == NULL) {
        m_LOG_GLD_HEADLINE(GLD_UNKNOWN_GLND_EVT, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id);
        return NCSCC_RC_FAILURE;
    }

    if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) {

        /* checkpoint node_details */
        glsv_gld_a2s_ckpt_node_details(gld_cb, node_details->dest_id, GLSV_GLD_EVT_GLND_DOWN);

        /* If this node is non master for any resource, then send node status to the master */
        gld_process_send_non_master_status(gld_cb, node_details, GLND_DOWN_STATE);

        /* Remove the reference to each of the resource referred by this node */
        glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree, (uns8 *)0);
        if (glnd_rsc) {
            rsc_id = glnd_rsc->rsc_id;
            while (glnd_rsc) {
                gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details,
                                     glnd_rsc->rsc_info->can_orphan);
                glnd_rsc =
                    (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree,
                            (uns8 *)&rsc_id);
                if (glnd_rsc)
                    rsc_id = glnd_rsc->rsc_id;
            }
        }

        /* Now delete this node details node */
        if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) {
            m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_DEL_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__,
                               node_details->node_id);
        } else {
            m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
            m_LOG_GLD_HEADLINE(GLD_ACTIVE_RMV_NODE, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id);
        }
    } else {
        node_details->status = GLND_DOWN_STATE;
    }
    return NCSCC_RC_SUCCESS;
}
Beispiel #3
0
/*****************************************************************************
  PROCEDURE NAME : gld_process_tmr_node_restart_wait_timeout

  DESCRIPTION    :

  ARGUMENTS      :gld_cb      - ptr to the GLD control block
                  evt          - ptr to the event.

  RETURNS        :NCSCC_RC_FAILURE/NCSCC_RC_SUCCESS

  NOTES         : None
*****************************************************************************/
static uint32_t gld_process_tmr_node_restart_wait_timeout(GLSV_GLD_EVT *evt)
{
	GLSV_GLD_CB *gld_cb = evt->gld_cb;
	GLSV_GLD_GLND_DETAILS *node_details;
	GLSV_GLD_GLND_RSC_REF *glnd_rsc;
	SaLckResourceIdT rsc_id;
	uint32_t node_id;

	node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.tmr.mdest_id);
	TRACE_ENTER2("Node restart wait timer expired: node_id %u", node_id);

	if ((node_details =
	     (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details, (uint8_t *)&node_id)) == NULL) {
		LOG_ER("Evenr from unknown glnd: node_id %u", node_id);
		return NCSCC_RC_FAILURE;
	}

	if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) {

		/* checkpoint node_details */
		glsv_gld_a2s_ckpt_node_details(gld_cb, node_details->dest_id, GLSV_GLD_EVT_GLND_DOWN);

		/* If this node is non master for any resource, then send node status to the master */
		gld_process_send_non_master_status(gld_cb, node_details, GLND_DOWN_STATE);

		/* Remove the reference to each of the resource referred by this node */
		glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree, (uint8_t *)0);
		if (glnd_rsc) {
			rsc_id = glnd_rsc->rsc_id;
			while (glnd_rsc) {
				gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details,
						     glnd_rsc->rsc_info->can_orphan);
				glnd_rsc =
				    (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree,
										       (uint8_t *)&rsc_id);
				if (glnd_rsc)
					rsc_id = glnd_rsc->rsc_id;
			}
		}

		/* Now delete this node details node */
		if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) {
			LOG_ER("Patricia tree del failed: node_id %u",
					   node_details->node_id);
		} else {
			m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
			TRACE("Node getting removed on active: node_id %u", node_id);
		}
	} else {
		node_details->status = GLND_DOWN_STATE;
	}
	return NCSCC_RC_SUCCESS;
}
Beispiel #4
0
/****************************************************************************
 * Name          : gld_add_glnd_node
 * Description   : Adds node_details info to the gld_cb and initilizes
                   node_details->rsc_info_tree
 *
 * Arguments     :GLSV_GLD_CB, glnd_mds_dest
 *
 * Return Values :
 *
 * Notes         : None.
 *****************************************************************************/
GLSV_GLD_GLND_DETAILS *gld_add_glnd_node(GLSV_GLD_CB *gld_cb, MDS_DEST glnd_mds_dest)
{
	GLSV_GLD_GLND_DETAILS *node_details;
	NCS_PATRICIA_PARAMS params = { sizeof(uint32_t) };
	TRACE_ENTER2("glnd_mds_dest %" PRIx64, glnd_mds_dest);

	/* Need to add the node details */
	node_details = m_MMGR_ALLOC_GLSV_GLD_GLND_DETAILS;
	if (node_details == NULL) {
		LOG_CR("Node details alloc failed: Error %s", strerror(errno));
		assert(0);
	}
	memset(node_details, 0, sizeof(GLSV_GLD_GLND_DETAILS));

	memcpy(&node_details->dest_id, &glnd_mds_dest, sizeof(MDS_DEST));
	node_details->node_id = m_NCS_NODE_ID_FROM_MDS_DEST(glnd_mds_dest);
	node_details->status = GLND_OPERATIONAL_STATE;

	TRACE("EVT Processing MDS GLND UP: node_id %u", node_details->node_id);

	/* Initialize the pat tree for resource info */
	if ((ncs_patricia_tree_init(&node_details->rsc_info_tree, &params))
	    != NCSCC_RC_SUCCESS) {
		LOG_ER("Patricia tree init failed");
		m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
		node_details = NULL;
		goto end;
	}
	node_details->pat_node.key_info = (uint8_t *)&node_details->node_id;
	if (ncs_patricia_tree_add(&gld_cb->glnd_details, &node_details->pat_node)
	    != NCSCC_RC_SUCCESS) {
		LOG_ER("Patricia tree add failed");
		m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
		node_details = NULL;
		goto end;
	}
 end:
	TRACE_LEAVE2("Node id %u",node_details->node_id);
	return node_details;
}
Beispiel #5
0
/****************************************************************************
 * Name          : gld_cb_destroy
 *
 * Description   : This function is invoked at destroy time. This function will
 *                 free all the dynamically allocated memory
 *
 * Arguments     : gld_cb  - GLD control block pointer.
 *
 * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
 *
 * Notes         : None.
 *****************************************************************************/
uns32 gld_cb_destroy(GLSV_GLD_CB *gld_cb)
{
	GLSV_GLD_GLND_DETAILS *node_details;
	GLSV_GLD_RSC_INFO *rsc_info;
	GLSV_NODE_LIST *node_list;
	GLSV_GLD_GLND_RSC_REF *glnd_rsc;

	/* destroy the patricia trees */
	while ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_getnext(&gld_cb->glnd_details, (uns8 *)0))) {
		while ((glnd_rsc =
			(GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree, (uns8 *)0))) {
			if (ncs_patricia_tree_del(&node_details->rsc_info_tree, (NCS_PATRICIA_NODE *)glnd_rsc) !=
			    NCSCC_RC_SUCCESS) {
				m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_DEL_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__,
						   0);
				return NCSCC_RC_FAILURE;
			}
			m_MMGR_FREE_GLSV_GLD_GLND_RSC_REF(glnd_rsc);
		}
		ncs_patricia_tree_destroy(&node_details->rsc_info_tree);
		if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) {
			m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_DEL_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__,
					   node_details->node_id);
			return NCSCC_RC_FAILURE;
		}

		m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
	}

	while ((rsc_info = (GLSV_GLD_RSC_INFO *)ncs_patricia_tree_getnext(&gld_cb->rsc_info_id, (uns8 *)0))) {
		/* Free the node list */
		while (rsc_info->node_list != NULL) {
			node_list = rsc_info->node_list;
			rsc_info->node_list = node_list->next;
			m_MMGR_FREE_GLSV_NODE_LIST(node_list);
		}

		gld_free_rsc_info(gld_cb, rsc_info);
	}
	return NCSCC_RC_SUCCESS;
}
Beispiel #6
0
/****************************************************************************
 * Name          : gld_rsc_open
 *
 * Description   : This is the function is invoked when a rsc_open event is
 *                 is sent from a GLND. This function will assign a resource id
 *                 and send the information to the GLND
 *
 * Arguments     : evt  - Event structure
 *
 * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE
 *
 * Notes         : None.
 *****************************************************************************/
static uns32 gld_rsc_open(GLSV_GLD_EVT *evt)
{
    GLSV_GLD_CB *gld_cb = evt->gld_cb;
    GLSV_GLD_RSC_INFO *rsc_info;
    GLSV_GLD_GLND_DETAILS *node_details;
    GLSV_NODE_LIST *node_list, **tmp_node_list;
    GLSV_GLND_EVT glnd_evt;
    NCSMDS_INFO snd_mds;
    uns32 res;
    SaAisErrorT error;
    uns32 node_id;
    NCS_BOOL node_first_rsc_open = FALSE;
    GLSV_GLD_GLND_RSC_REF *glnd_rsc = NULL;
    NCS_BOOL orphan_flag = FALSE;

    node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id);
    memset(&snd_mds, '\0', sizeof(NCSMDS_INFO));
    memset(&glnd_evt, '\0', sizeof(GLSV_GLND_EVT));

    if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL))
        return NCSCC_RC_FAILURE;

    /* Find if the node details are available */
    if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details,
                        (uns8 *)&node_id)) == NULL) {
        node_first_rsc_open = TRUE;
        if ((node_details = gld_add_glnd_node(gld_cb, evt->fr_dest_id)) == NULL)
            return NCSCC_RC_FAILURE;
    }

    rsc_info = gld_find_add_rsc_name(gld_cb, &evt->info.rsc_open_info.rsc_name,
                                     evt->info.rsc_open_info.rsc_id, evt->info.rsc_open_info.flag, &error);

    if (rsc_info == NULL) {
        /* based on the error - pass on the info to the glnd */
        glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS;
        glnd_evt.info.rsc_gld_info.rsc_name = evt->info.rsc_open_info.rsc_name;
        glnd_evt.info.rsc_gld_info.error = error;

        snd_mds.i_mds_hdl = gld_cb->mds_handle;
        snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD;
        snd_mds.i_op = MDS_SEND;
        snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt;
        snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND;
        snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH;
        snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND;
        snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id;

        res = ncsmds_api(&snd_mds);
        if (res != NCSCC_RC_SUCCESS) {
            m_LOG_GLD_SVC_PRVDR(GLD_MDS_SEND_ERROR, NCSFL_SEV_ERROR, __FILE__, __LINE__);
        }
        goto err1;
    }
    m_LOG_GLD_EVT(GLD_EVT_RSC_OPEN, NCSFL_SEV_INFO, __FILE__, __LINE__, rsc_info->rsc_id, node_details->node_id);

    gld_rsc_add_node_ref(gld_cb, node_details, rsc_info);

    /* Now add this node to the list of nodes referring this resource */
    node_list = rsc_info->node_list;
    tmp_node_list = &rsc_info->node_list;
    while (node_list != NULL) {
        if (node_list->node_id == node_id)
            break;
        tmp_node_list = &node_list->next;
        node_list = node_list->next;
    }

    if (node_list == NULL) {
        node_list = m_MMGR_ALLOC_GLSV_NODE_LIST;
        memset(node_list, 0, sizeof(GLSV_NODE_LIST));
        node_list->dest_id = node_details->dest_id;
        node_list->node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id);
        *tmp_node_list = node_list;

        /* Send the details to the glnd */
        glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS;
        glnd_evt.info.rsc_gld_info.master_dest_id = rsc_info->node_list->dest_id;
        glnd_evt.info.rsc_gld_info.rsc_id = rsc_info->rsc_id;
        glnd_evt.info.rsc_gld_info.rsc_name = rsc_info->lck_name;
        glnd_evt.info.rsc_gld_info.can_orphan = rsc_info->can_orphan;
        glnd_evt.info.rsc_gld_info.orphan_mode = rsc_info->orphan_lck_mode;
        glnd_evt.info.rsc_gld_info.error = SA_AIS_OK;

        snd_mds.i_mds_hdl = gld_cb->mds_handle;
        snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD;
        snd_mds.i_op = MDS_SEND;
        snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt;
        snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND;
        snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH;
        snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND;
        snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id;

        res = ncsmds_api(&snd_mds);
        if (res != NCSCC_RC_SUCCESS) {
            m_LOG_GLD_SVC_PRVDR(GLD_MDS_SEND_ERROR, NCSFL_SEV_ERROR, __FILE__, __LINE__);
            goto err2;
        }
    }

    /* checkpoint resource */
    glsv_gld_a2s_ckpt_resource(gld_cb, &rsc_info->lck_name, rsc_info->rsc_id, evt->fr_dest_id,
                               rsc_info->saf_rsc_creation_time);

    return NCSCC_RC_SUCCESS;
err2:

    glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_get(&node_details->rsc_info_tree,
               (uns8 *)&rsc_info->rsc_id);
    if ((glnd_rsc == NULL) || (glnd_rsc->rsc_info == NULL)) {
        m_LOG_GLD_LCK_OPER(GLD_OPER_RSC_OPER_ERROR, NCSFL_SEV_ERROR, __FILE__, __LINE__, "",
                           rsc_info->rsc_id, node_details->node_id);
        return NCSCC_RC_FAILURE;
    }

    if (glnd_rsc->rsc_info->saf_rsc_no_of_users > 0)
        glnd_rsc->rsc_info->saf_rsc_no_of_users = glnd_rsc->rsc_info->saf_rsc_no_of_users - 1;

    gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag);
err1:
    if (node_first_rsc_open) {
        /* Now delete this node details node */
        if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) {
            m_LOG_GLD_HEADLINE(GLD_PATRICIA_TREE_DEL_FAILED, NCSFL_SEV_ERROR, __FILE__, __LINE__,
                               node_details->node_id);
        } else {
            m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
            m_LOG_GLD_HEADLINE(GLD_ACTIVE_RMV_NODE, NCSFL_SEV_NOTICE, __FILE__, __LINE__, node_id);
        }
    }
    return NCSCC_RC_FAILURE;

}
Beispiel #7
0
/****************************************************************************
 * Name          : gld_rsc_open
 *
 * Description   : This is the function is invoked when a rsc_open event is
 *                 is sent from a GLND. This function will assign a resource id
 *                 and send the information to the GLND
 *
 * Arguments     : evt  - Event structure
 *
 * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE
 *
 * Notes         : None.
 *****************************************************************************/
static uint32_t gld_rsc_open(GLSV_GLD_EVT *evt)
{
	GLSV_GLD_CB *gld_cb = evt->gld_cb;
	GLSV_GLD_RSC_INFO *rsc_info;
	GLSV_GLD_GLND_DETAILS *node_details;
	GLSV_NODE_LIST *node_list, **tmp_node_list;
	GLSV_GLND_EVT glnd_evt;
	NCSMDS_INFO snd_mds;
	uint32_t res = NCSCC_RC_FAILURE;;
	SaAisErrorT error;
	uint32_t node_id;
	bool node_first_rsc_open = false;
	GLSV_GLD_GLND_RSC_REF *glnd_rsc = NULL;
	bool orphan_flag = false;
	TRACE_ENTER2("component name %s", gld_cb->comp_name.value);

	node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id);
	memset(&snd_mds, '\0', sizeof(NCSMDS_INFO));
	memset(&glnd_evt, '\0', sizeof(GLSV_GLND_EVT));

	if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL))
		goto end;

	/* Find if the node details are available */
	if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details,
									   (uint8_t *)&node_id)) == NULL) {
		node_first_rsc_open = true;
		if ((node_details = gld_add_glnd_node(gld_cb, evt->fr_dest_id)) == NULL)
			goto end;
	}

	rsc_info = gld_find_add_rsc_name(gld_cb, &evt->info.rsc_open_info.rsc_name,
					 evt->info.rsc_open_info.rsc_id, evt->info.rsc_open_info.flag, &error);

	if (rsc_info == NULL) {
		/* based on the error - pass on the info to the glnd */
		glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS;
		glnd_evt.info.rsc_gld_info.rsc_name = evt->info.rsc_open_info.rsc_name;
		glnd_evt.info.rsc_gld_info.error = error;

		snd_mds.i_mds_hdl = gld_cb->mds_handle;
		snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD;
		snd_mds.i_op = MDS_SEND;
		snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt;
		snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND;
		snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH;
		snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND;
		snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id;

		res = ncsmds_api(&snd_mds);
		if (res != NCSCC_RC_SUCCESS) {
			LOG_ER("MDS Send failed");
		}
		goto err1;
	}
	TRACE_1("EVT Processing rsc open: rsc_id %u node_id %u", rsc_info->rsc_id, node_details->node_id);

	gld_rsc_add_node_ref(gld_cb, node_details, rsc_info);

	/* Now add this node to the list of nodes referring this resource */
	node_list = rsc_info->node_list;
	tmp_node_list = &rsc_info->node_list;
	while (node_list != NULL) {
		if (node_list->node_id == node_id)
			break;
		tmp_node_list = &node_list->next;
		node_list = node_list->next;
	}

	if (node_list == NULL) {
		node_list = m_MMGR_ALLOC_GLSV_NODE_LIST;
		memset(node_list, 0, sizeof(GLSV_NODE_LIST));
		node_list->dest_id = node_details->dest_id;
		node_list->node_id = m_NCS_NODE_ID_FROM_MDS_DEST(evt->fr_dest_id);
		*tmp_node_list = node_list;

		/* Send the details to the glnd */
		glnd_evt.type = GLSV_GLND_EVT_RSC_GLD_DETAILS;
		glnd_evt.info.rsc_gld_info.master_dest_id = rsc_info->node_list->dest_id;
		glnd_evt.info.rsc_gld_info.rsc_id = rsc_info->rsc_id;
		glnd_evt.info.rsc_gld_info.rsc_name = rsc_info->lck_name;
		glnd_evt.info.rsc_gld_info.can_orphan = rsc_info->can_orphan;
		glnd_evt.info.rsc_gld_info.orphan_mode = rsc_info->orphan_lck_mode;
		glnd_evt.info.rsc_gld_info.error = SA_AIS_OK;

		snd_mds.i_mds_hdl = gld_cb->mds_handle;
		snd_mds.i_svc_id = NCSMDS_SVC_ID_GLD;
		snd_mds.i_op = MDS_SEND;
		snd_mds.info.svc_send.i_msg = (NCSCONTEXT)&glnd_evt;
		snd_mds.info.svc_send.i_to_svc = NCSMDS_SVC_ID_GLND;
		snd_mds.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH;
		snd_mds.info.svc_send.i_sendtype = MDS_SENDTYPE_SND;
		snd_mds.info.svc_send.info.snd.i_to_dest = node_details->dest_id;

		res = ncsmds_api(&snd_mds);
		if (res != NCSCC_RC_SUCCESS) {
			LOG_ER("MDS Send failed");
			goto err2;
		}
	}

	/* checkpoint resource */
	glsv_gld_a2s_ckpt_resource(gld_cb, &rsc_info->lck_name, rsc_info->rsc_id, evt->fr_dest_id,
				   rsc_info->saf_rsc_creation_time);

	res = NCSCC_RC_SUCCESS;
	goto end;
 err2:

	glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_get(&node_details->rsc_info_tree,
								  (uint8_t *)&rsc_info->rsc_id);
	if ((glnd_rsc == NULL) || (glnd_rsc->rsc_info == NULL)) {
		LOG_ER("Rsc operation for unopened rsc: rsc_id %u node_id %u",
				   rsc_info->rsc_id, node_details->node_id);
		goto end;
	}

	if (glnd_rsc->rsc_info->saf_rsc_no_of_users > 0)
		glnd_rsc->rsc_info->saf_rsc_no_of_users = glnd_rsc->rsc_info->saf_rsc_no_of_users - 1;

	gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag);
 err1:
	if (node_first_rsc_open) {
		/* Now delete this node details node */
		if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) {
			LOG_ER("Patricia tree del failed: node_id %u ", node_details->node_id);
		} else {
			m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);
			TRACE("Node getting removed on active: node_id %u", node_id);
		}
	}
	res = NCSCC_RC_FAILURE;
 end:
	TRACE_LEAVE2("return value %u", res);
	return res;

}
/****************************************************************************
 * Name          : glsv_gld_mds_glnd_down
 *
 * Description   : MDS indicated that a glnd has gone down
 *
 * Arguments     : async_evt  - Event structure
 *
 * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE
 *
 * Notes         : None.
 *****************************************************************************/
static uint32_t glsv_gld_standby_mds_glnd_down(GLSV_GLD_A2S_CKPT_EVT *async_evt)
{
	GLSV_GLD_CB *gld_cb;
	GLSV_GLD_GLND_DETAILS *node_details = NULL;
	GLSV_GLD_GLND_RSC_REF *glnd_rsc = NULL;
	bool orphan_flag;
	SaLckResourceIdT rsc_id;
	uint32_t node_id;
	uint32_t rc = NCSCC_RC_SUCCESS;
	TRACE_ENTER();

	if (async_evt == NULL) {
		rc = NCSCC_RC_FAILURE;
		goto end;
	}	
	node_id = m_NCS_NODE_ID_FROM_MDS_DEST(async_evt->info.glnd_mds_info.mdest_id);

	if ((gld_cb = (NCSCONTEXT)ncshm_take_hdl(NCS_SERVICE_ID_GLD, gl_gld_hdl))
	    == NULL) {
		LOG_ER("Handle take failed");
		rc = NCSCC_RC_FAILURE;
		goto end;
	}

	orphan_flag = async_evt->info.rsc_details.orphan;

	if ((node_details = (GLSV_GLD_GLND_DETAILS *)ncs_patricia_tree_get(&gld_cb->glnd_details,
									   (uint8_t *)&node_id)) == NULL) {
		LOG_ER("Patricia tree get failed: node_id %u", node_id);
		rc = NCSCC_RC_FAILURE;
		goto end;
	}

	/* Remove the reference to each of the resource referred by this node */
	glnd_rsc = (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree, (uint8_t *)0);
	if (glnd_rsc) {
		rsc_id = glnd_rsc->rsc_id;
		while (glnd_rsc) {
			gld_rsc_rmv_node_ref(gld_cb, glnd_rsc->rsc_info, glnd_rsc, node_details, orphan_flag);
			glnd_rsc =
			    (GLSV_GLD_GLND_RSC_REF *)ncs_patricia_tree_getnext(&node_details->rsc_info_tree,
									       (uint8_t *)&rsc_id);
			if (glnd_rsc)
				rsc_id = glnd_rsc->rsc_id;
		}
	}
	/* Cancel the restart timer if started */
	if (node_details->restart_timer.tmr_id != TMR_T_NULL)
		gld_stop_tmr(&node_details->restart_timer);

	/* Now delete this node details node */
	if (ncs_patricia_tree_del(&gld_cb->glnd_details, (NCS_PATRICIA_NODE *)node_details) != NCSCC_RC_SUCCESS) {
		LOG_ER("Patricia tree del failed: node_id %u",
				   node_details->node_id);
	}

	m_MMGR_FREE_GLSV_GLD_GLND_DETAILS(node_details);

	ncshm_give_hdl(gld_cb->my_hdl);
 end:
	TRACE_LEAVE();
	return rc;
}