Currently, the adest will be deleted after the adest down timer expired.
It still waste 1.5s if the response is send to a deleted adest.
Solution is to return immediately if not found adest and add a new adest
for a message received from that adest if not detected its service is up.
Additionally, a new TC is created to verify this scenario.
---
 src/mds/apitest/mdstipc_api.c | 112 ++++++++++++++++++++++++++++++++++
 src/mds/mds_c_api.c           |   5 +-
 src/mds/mds_c_sndrcv.c        |  28 ++++++++-
 src/mds/mds_core.h            |   1 +
 4 files changed, 144 insertions(+), 2 deletions(-)

diff --git a/src/mds/apitest/mdstipc_api.c b/src/mds/apitest/mdstipc_api.c
index 8d09761e1..030a638a3 100644
--- a/src/mds/apitest/mdstipc_api.c
+++ b/src/mds/apitest/mdstipc_api.c
@@ -5762,6 +5762,114 @@ void tet_send_response_tp_13()
        test_validate(FAIL, 0);
 }
 
+void tet_send_response_tp_14()
+{
+       int FAIL = 1;
+       mds_shutdown();
+
+       printf("\nTest Case 14: Now send_response to dead Adest don't stuck"
+              " in waiting 1.5s after adest down timer expires\n");
+       /*-------------------------------------------------------------------*/
+       pid_t pid = fork();
+       if (pid == 0) {
+               /* child as sender */
+               MDS_SVC_ID to_svcids[] = {NCSMDS_SVC_ID_EXTERNAL_MIN};
+               mds_startup();
+               if (adest_get_handle() == NCSCC_RC_SUCCESS) {
+                       if (mds_service_install(
+                                       gl_tet_adest.mds_pwe1_hdl,
+                                       NCSMDS_SVC_ID_INTERNAL_MIN, 1,
+                                       NCSMDS_SCOPE_NONE, false, false)
+                                       == NCSCC_RC_SUCCESS) {
+                               if (mds_service_subscribe(
+                                               gl_tet_adest.mds_pwe1_hdl,
+                                               NCSMDS_SVC_ID_INTERNAL_MIN,
+                                               NCSMDS_SCOPE_INTRANODE,
+                                               1, to_svcids)
+                                               == NCSCC_RC_SUCCESS) {
+                                       TET_MDS_MSG msg;
+                                       sleep(1); // Wait for up event
+                                       mds_send_get_response(
+                                           gl_tet_adest.mds_pwe1_hdl,
+                                           NCSMDS_SVC_ID_INTERNAL_MIN,
+                                           NCSMDS_SVC_ID_EXTERNAL_MIN,
+                                           gl_tet_adest.svc[0].svcevt[0].dest,
+                                           100, MDS_SEND_PRIORITY_HIGH,
+                                           &msg);
+                                       mds_service_uninstall(
+                                               gl_tet_adest.mds_pwe1_hdl,
+                                               NCSMDS_SVC_ID_INTERNAL_MIN);
+                                       sleep(30);
+                               }
+                       }
+               }
+               mds_shutdown();
+       } else if (pid > 0) {
+               /* parent as receiver */
+               struct timespec time1, time2, wait_time;
+               MDS_SVC_ID to_svcids[] = {NCSMDS_SVC_ID_INTERNAL_MIN};
+               mds_startup();
+               if (adest_get_handle() == NCSCC_RC_SUCCESS) {
+                       if (mds_service_install(
+                                       gl_tet_adest.mds_pwe1_hdl,
+                                       NCSMDS_SVC_ID_EXTERNAL_MIN, 1,
+                                       NCSMDS_SCOPE_NONE, true, false)
+                                       == NCSCC_RC_SUCCESS) {
+                               if (mds_service_subscribe(
+                                               gl_tet_adest.mds_pwe1_hdl,
+                                               NCSMDS_SVC_ID_EXTERNAL_MIN,
+                                               NCSMDS_SCOPE_INTRANODE,
+                                               1, to_svcids)
+                                               == NCSCC_RC_SUCCESS) {
+                                       while (is_adest_sel_obj_found(0)) {
+                                               if (mds_service_retrieve(
+                                                   gl_tet_adest.mds_pwe1_hdl,
+                                                   NCSMDS_SVC_ID_EXTERNAL_MIN,
+                                                   SA_DISPATCH_ONE)
+                                                 == NCSCC_RC_SUCCESS &&
+                                                 gl_rcvdmsginfo.msg) {
+                                                       // Received the message
+                                                       break;
+                                               }
+                                       }
+                                       sleep(15); // Make sure the adest down
+                                                  // timer expires
+                                       osaf_clock_gettime(CLOCK_MONOTONIC,
+                                                          &time1);
+                                       // Send response
+                                       TET_MDS_MSG msg;
+                                       if (mds_send_response(
+                                           gl_tet_adest.mds_pwe1_hdl,
+                                           NCSMDS_SVC_ID_EXTERNAL_MIN,
+                                           &msg)
+                                           == NCSCC_RC_FAILURE) {
+                                               osaf_clock_gettime(
+                                                   CLOCK_MONOTONIC,
+                                                   &time2);
+                                               osaf_timespec_subtract(
+                                                   &time2,
+                                                   &time1,
+                                                   &wait_time);
+                                               if (osaf_timespec_to_millis(
+                                                   &wait_time) > 50) {
+                                                       printf("\nResponse to"
+                                                       " dead Adest hang >"
+                                                       " 50ms");
+                                               } else {
+                                                       FAIL = 0;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               kill(pid, SIGKILL);
+               mds_shutdown();
+       } else {
+               printf("\nFAIL to fork()\n");
+       }
+       test_validate(FAIL, 0);
+}
+
 void tet_vdest_rcvr_thread()
 {
        MDS_SVC_ID svc_id;
@@ -14423,6 +14531,10 @@ __attribute__((constructor)) static void 
mdsTipcAPI_constructor(void)
        test_case_add(
            9, tet_send_response_tp_13,
            "Now send_response to dead Adest don't stuck in waiting 1.5s");
+       test_case_add(
+           9, tet_send_response_tp_14,
+           "Now send_response to dead Adest don't stuck in waiting 1.5s"
+           " after adest down timer expires");
 
        test_suite_add(10, "Send All test cases");
        test_case_add(
diff --git a/src/mds/mds_c_api.c b/src/mds/mds_c_api.c
index 8e2f899a9..2fa2dc1d4 100644
--- a/src/mds/mds_c_api.c
+++ b/src/mds/mds_c_api.c
@@ -2006,12 +2006,15 @@ uint32_t mds_mcm_svc_up(PW_ENV_ID pwe_id, MDS_SVC_ID 
svc_id, V_DEST_RL role,
                        adest_info->node.key_info =
                                (uint8_t *)&adest_info->adest;
                        adest_info->svc_cnt = 1;
+                       adest_info->is_up = true;
                        ncs_patricia_tree_add(
                            &gl_mds_mcm_cb->adest_list,
                            (NCS_PATRICIA_NODE *)adest_info);
                } else {
-                       if (adest_info->svc_cnt == 0)
+                       if (adest_info->svc_cnt == 0) {
                                stop_mds_down_tmr(adest_info);
+                               adest_info->is_up = true;
+                       }
                        adest_info->svc_cnt++;
                }
        }
diff --git a/src/mds/mds_c_sndrcv.c b/src/mds/mds_c_sndrcv.c
index ee9dd3569..81d399c87 100644
--- a/src/mds/mds_c_sndrcv.c
+++ b/src/mds/mds_c_sndrcv.c
@@ -2715,7 +2715,13 @@ static uint32_t 
mds_mcm_process_disc_queue_checks_redundant(
                                (MDS_ADEST_INFO *)ncs_patricia_tree_get(
                                        &gl_mds_mcm_cb->adest_list,
                                        (uint8_t *)&anchor);
-                       if (adest_info && adest_info->svc_cnt == 0) {
+                       if (adest_info == NULL) {
+                               m_MDS_LOG_NOTIFY(
+                                   "MDS_SND_RCV: Subscription exists but"
+                                   " Adest was down\n");
+                               return NCSCC_RC_FAILURE;
+                       } else if (adest_info && adest_info->svc_cnt == 0 &&
+                                       adest_info->is_up) {
                                m_MDS_LOG_NOTIFY(
                                    "MDS_SND_RCV: Adest <0x%08x, %u> may down,"
                                    " wait for some time for sure",
@@ -4910,6 +4916,26 @@ static uint32_t 
mds_mcm_process_recv_snd_msg_common(MDS_SVC_INFO *svccb,
        uint32_t rc = 0;
 
        m_MDS_ENTER();
+       if (recv->snd_type == MDS_SENDTYPE_SNDRSP ||
+                       recv->snd_type == MDS_SENDTYPE_REDRSP) {
+               MDS_ADEST_INFO *adest_info =
+                       (MDS_ADEST_INFO *)ncs_patricia_tree_get(
+                               &gl_mds_mcm_cb->adest_list,
+                               (uint8_t *)&recv->src_adest);
+               if (!adest_info) {
+                       /* Add adest to adest list */
+                       adest_info = m_MMGR_ALLOC_ADEST_INFO;
+                       memset(adest_info, 0, sizeof(MDS_ADEST_INFO));
+                       adest_info->adest = recv->src_adest;
+                       adest_info->node.key_info =
+                               (uint8_t *)&adest_info->adest;
+                       adest_info->svc_cnt = 0;
+                       adest_info->is_up = false;
+                       ncs_patricia_tree_add(
+                               &gl_mds_mcm_cb->adest_list,
+                               (NCS_PATRICIA_NODE *)adest_info);
+               }
+       }
        if (true == svccb->q_ownership) {
                if (NCSCC_RC_SUCCESS !=
                    mds_mcm_mailbox_post(svccb, recv, recv->pri)) {
diff --git a/src/mds/mds_core.h b/src/mds/mds_core.h
index 661bd85ea..efe7e4b23 100644
--- a/src/mds/mds_core.h
+++ b/src/mds/mds_core.h
@@ -257,6 +257,7 @@ typedef struct mds_adest_info {
   /* Adest info */
   MDS_DEST adest; /* Key for Patricia node */
   uint16_t svc_cnt; /* Adest SVC counter */
+  bool is_up;
   MDS_TMR_REQ_INFO *tmr_req_info;
   uint32_t tmr_hdl;
 } MDS_ADEST_INFO;
-- 
2.25.1



_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to