osaf/services/saf/logsv/lgs/Makefile.am   |    3 +-
 osaf/services/saf/logsv/lgs/lgs_evt.c     |   14 +++
 osaf/services/saf/logsv/lgs/lgs_mds.c     |    7 +
 osaf/services/saf/logsv/lgs/lgs_mdsdown.c |  133 ++++++++++++++++++++++++++++++
 osaf/services/saf/logsv/lgs/lgs_mdsdown.h |   56 ++++++++++++
 tests/logsv/tet_saLogInitialize.c         |   26 +++++
 6 files changed, 238 insertions(+), 1 deletions(-)


Sometimes, Log service can handle LGSV_INITIALIZE_REQ before handle
LGSV_LGS_EVT_LGA_DOWN, although LGSV_LGS_EVT_LGA_DOWN was sent first.

When Log service handle down message later, it will destroy every log agents
(include new created log agent).
>From now, handle of this log agent in log user is not valid anymore.

Solution: Log service need to prevent log user create new log agent when Log 
service
have not handled down message completely. Just tell user try again.

diff --git a/osaf/services/saf/logsv/lgs/Makefile.am 
b/osaf/services/saf/logsv/lgs/Makefile.am
--- a/osaf/services/saf/logsv/lgs/Makefile.am
+++ b/osaf/services/saf/logsv/lgs/Makefile.am
@@ -61,7 +61,8 @@ osaflogd_SOURCES = \
        lgs_filehdl.c \
        lgs_mbcsv_v3.c \
        lgs_config.c \
-       lgs_mbcsv_v5.c
+       lgs_mbcsv_v5.c \
+       lgs_mdsdown.c
 
 osaflogd_LDADD = \
        $(top_builddir)/osaf/tools/safimm/src/libimmutil.la \
diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.c 
b/osaf/services/saf/logsv/lgs/lgs_evt.c
--- a/osaf/services/saf/logsv/lgs/lgs_evt.c
+++ b/osaf/services/saf/logsv/lgs/lgs_evt.c
@@ -27,6 +27,7 @@
 #include "lgs_util.h"
 #include "lgs_fmt.h"
 #include "lgs_config.h"
+#include "lgs_mdsdown.h"
 
 #include "lgs_mbcsv_v1.h"
 #include "lgs_mbcsv_v2.h"
@@ -383,6 +384,10 @@ static uint32_t proc_lga_updn_mds_msg(lg
                        time_t closetime = closetime_tspec.tv_sec;
                        (void)lgs_client_delete_by_mds_dest(evt->fr_dest, 
&closetime);
 
+                       /* Remove this MDS address from LGA_DOWN received 
database, this address entry
+                       was added when mds thread of log server receive 
LGSV_LGS_EVT_LGA_DOWN message */
+                       lgs_mds_down_queue_remove(&evt->fr_dest);
+
                        /*Send an async checkpoint update to STANDBY EDS peer */
                        if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE) {
                                if (lgs_is_peer_v2()) {
@@ -624,6 +629,15 @@ static uint32_t proc_initialize_msg(lgs_
                goto snd_rsp;
        }
 
+       /* Check whether LGA_DOWN from this MDS address was received or not.
+        If LGA_DOWN received, Log server need to reject this initialization 
request.
+        Because when Log server handle this message in mail box later, it will 
clean all clients
+        of this MDS address */
+       if (lgs_mds_down_queue_search(&evt->fr_dest) == SA_TRUE) {
+               ais_rc =SA_AIS_ERR_TRY_AGAIN;
+               goto snd_rsp;
+       }
+
        if ((client = lgs_client_new(evt->fr_dest, 0, NULL)) == NULL) {
                ais_rc = SA_AIS_ERR_NO_MEMORY;
                goto snd_rsp;
diff --git a/osaf/services/saf/logsv/lgs/lgs_mds.c 
b/osaf/services/saf/logsv/lgs/lgs_mds.c
--- a/osaf/services/saf/logsv/lgs/lgs_mds.c
+++ b/osaf/services/saf/logsv/lgs/lgs_mds.c
@@ -17,6 +17,7 @@
 
 #include <ncsencdec_pub.h>
 #include "lgs.h"
+#include "lgs_mdsdown.h"
 #include "osaf_time.h"
 #include "osaf_utility.h"
 
@@ -1120,6 +1121,12 @@ static uint32_t mds_svc_event(struct ncs
                                rc = m_NCS_IPC_SEND(&lgs_mbx, evt, 
LGS_IPC_PRIO_CTRL_MSGS);
                                osafassert(rc == NCSCC_RC_SUCCESS);
                        }
+
+                       /* Add this MDS address into LGA_DOWN received 
database, this address
+                       entry will be deleted when main thread of log server 
actually hanlde
+                       task for LGSV_LGS_EVT_LGA_DOWN message */
+                       rc = lgs_mds_down_queue_insert(&evt->fr_dest);
+                       osafassert(rc == NCSCC_RC_SUCCESS);
                }
        }
 
diff --git a/osaf/services/saf/logsv/lgs/lgs_mdsdown.c 
b/osaf/services/saf/logsv/lgs/lgs_mdsdown.c
new file mode 100644
--- /dev/null
+++ b/osaf/services/saf/logsv/lgs/lgs_mdsdown.c
@@ -0,0 +1,133 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2015 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): Ericsson AB
+ *
+ */
+
+#include "lgs_mdsdown.h"
+#include "lgs.h"
+#include "osaf_utility.h"
+
+/* LGA receive message down database, refer to this database before allow to 
create new LGA */
+static lga_recv_message_down_queue_t lga_recv_down_queue;
+
+/* Mutex for receive message down database */
+static pthread_mutex_t lga_down_queue_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/****************************************************************************
+ * Name          : lgs_mds_down_queue_insert
+ *
+ * Description   : This functions is used to add a mds address to mds
+ *                 received message down queue
+ *
+ * Arguments     : dest - pointer to MDS address
+ *
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ *
+ *****************************************************************************/
+uint32_t lgs_mds_down_queue_insert(const MDS_DEST *dest)
+{
+       uint32_t rc = NCSCC_RC_SUCCESS;
+       osaf_mutex_lock_ordie(&lga_down_queue_lock);
+       /* Store MDS of this LGA into queue to refer later */
+       lga_recv_message_down_t *lga_recv_mess_down = NULL;
+       if ((lga_recv_mess_down = calloc(1,sizeof(lga_recv_message_down_t))) == 
NULL) {
+               LOG_WA("allocation for lga_recv_message_down_t failed");
+               rc = NCSCC_RC_FAILURE;
+               osaf_mutex_unlock_ordie(&lga_down_queue_lock);
+               goto done;
+       }
+       lga_recv_mess_down->mds_dest = *dest;
+       if (lga_recv_down_queue.head == NULL)
+               lga_recv_down_queue.head = lga_recv_mess_down;
+       else {
+               if (lga_recv_down_queue.tail != NULL)
+                       lga_recv_down_queue.tail->next = lga_recv_mess_down;
+       }
+       lga_recv_down_queue.tail = lga_recv_mess_down;
+       osaf_mutex_unlock_ordie(&lga_down_queue_lock);
+
+done:
+       return rc;
+}
+
+/****************************************************************************
+ * Name          : lgs_mds_down_queue_search
+ *
+ * Description   : This functions is used to verify whether a mds address occur
+ *                 in mds received message down queue or not
+ *
+ * Arguments     : dest - pointer to MDS address
+ *
+ * Return Values : SA_TRUE/SA_FALSE
+ *****************************************************************************/
+SaBoolT lgs_mds_down_queue_search(const MDS_DEST *dest)
+{
+       SaBoolT inQueue= SA_FALSE;
+       osaf_mutex_lock_ordie(&lga_down_queue_lock);
+       lga_recv_message_down_t *lga_recv_mess_down = lga_recv_down_queue.head;
+       while (lga_recv_mess_down != NULL) {
+               if (m_NCS_MDS_DEST_EQUAL(&lga_recv_mess_down->mds_dest, dest)) {
+                       inQueue = SA_TRUE;
+                       break;
+               }
+               lga_recv_mess_down = lga_recv_mess_down->next;
+       }
+       osaf_mutex_unlock_ordie(&lga_down_queue_lock);
+       return inQueue;
+}
+
+/****************************************************************************
+ * Name          : lgs_mds_down_queue_remove
+ *
+ * Description   : This functions is used to remove a mds address from mds
+ *                 received message down queue
+ *
+ * Arguments     : dest - pointer to MDS address
+ *
+ * Return Values : none
+ *
+ *****************************************************************************/
+void lgs_mds_down_queue_remove(const MDS_DEST *dest)
+{
+       osaf_mutex_lock_ordie(&lga_down_queue_lock);
+       lga_recv_message_down_t *lga_recv_mes_down = lga_recv_down_queue.head;
+       lga_recv_message_down_t *previous = NULL;
+       while (lga_recv_mes_down != NULL) {
+               if (m_NCS_MDS_DEST_EQUAL(&lga_recv_mes_down->mds_dest, dest)) {
+                       if (lga_recv_mes_down == lga_recv_down_queue.head) {
+                               if (lga_recv_mes_down->next == NULL) {
+                                       lga_recv_down_queue.head = NULL;
+                                       lga_recv_down_queue.tail = NULL;
+                               } else {
+                                       lga_recv_down_queue.head = 
lga_recv_mes_down->next;
+                               }
+                       } else {
+                               if (previous != NULL) {
+                                       if (lga_recv_mes_down->next == NULL)
+                                               lga_recv_down_queue.tail = 
previous;
+                                       previous->next = 
lga_recv_mes_down->next;
+                               }
+                               break;
+                       }
+
+                       free(lga_recv_mes_down);
+                       lga_recv_mes_down = NULL;
+                       break;
+               }
+               previous = lga_recv_mes_down;
+               lga_recv_mes_down = lga_recv_mes_down->next;
+       }
+       osaf_mutex_unlock_ordie(&lga_down_queue_lock);
+}
diff --git a/osaf/services/saf/logsv/lgs/lgs_mdsdown.h 
b/osaf/services/saf/logsv/lgs/lgs_mdsdown.h
new file mode 100644
--- /dev/null
+++ b/osaf/services/saf/logsv/lgs/lgs_mdsdown.h
@@ -0,0 +1,56 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2015 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): Ericsson AB
+ *
+ * This file contain functions to handle problem cause by priority of
+ * LGSV_LGS_EVT_LGA_DOWN is lower than LGSV_INITIALIZE_REQ in mailbox
+ * of logserver. Please refer ticket 1396 for more detail.
+ *
+ * Solution:
+ * When log server receive LGSV_LGS_EVT_LGA_DOWN request in mds thread,
+ * log server add this address to a database to store the information: this
+ * mds address is sent down.
+ *
+ * When log server receive initialize request, log server refer to above
+ * database. If this mds address appears in database, log server will
+ * reject, notify to log client that: please try again.
+ *
+ * When logServer actually implement LGSV_LGS_EVT_LGA_DOWN in mailbox,
+ * log server remove this mds address entry in database!
+ *
+ * After remove that entry, new initialization request will be implemented
+ * normally and log server will return the stable handle for log client.
+ */
+#ifndef __LGS_MDSDOWN_H
+#define __LGS_MDSDOWN_H
+
+#include "lgs.h"
+
+/* Define queue type to store mds addresses */
+typedef struct lga_recv_message_down {
+       MDS_DEST mds_dest;
+       struct lga_recv_message_down *next;
+}lga_recv_message_down_t;
+
+typedef struct lga_recv_message_dow_queue {
+       lga_recv_message_down_t *head;
+       lga_recv_message_down_t *tail;
+}lga_recv_message_down_queue_t;
+
+/* Functions to interact with mds addresses queue */
+uint32_t lgs_mds_down_queue_insert(const MDS_DEST *dest);
+SaBoolT lgs_mds_down_queue_search(const MDS_DEST *dest);
+void lgs_mds_down_queue_remove(const MDS_DEST *dest);
+
+#endif /* ifndef __LGS_MDSDOWN_H */
diff --git a/tests/logsv/tet_saLogInitialize.c 
b/tests/logsv/tet_saLogInitialize.c
--- a/tests/logsv/tet_saLogInitialize.c
+++ b/tests/logsv/tet_saLogInitialize.c
@@ -16,6 +16,7 @@
  */
 
 #include "logtest.h"
+#include <unistd.h>
 
 void saLogInitialize_01(void)
 {
@@ -82,6 +83,30 @@ void saLogInitialize_09(void)
     test_validate(rc, SA_AIS_ERR_VERSION);
 }
 
+void saLogMultipleInitialize(void)
+{
+       uint8_t loopNumber = 100;
+       uint8_t tryAgainNumber = 10;
+       uint32_t retryInterval = 100000; /* 100 milisecond */
+       for (uint8_t i = 0; i < loopNumber; i++)
+       {
+               for (uint8_t j = 0; j < tryAgainNumber; j++)
+               {
+                       rc = saLogInitialize(&logHandle, &logCallbacks, 
&logVersion);
+                       if ((rc == SA_AIS_OK) || (rc != SA_AIS_ERR_TRY_AGAIN))
+                               break;
+                       usleep(retryInterval);
+               }
+
+               if (rc == SA_AIS_OK)
+                       rc = saLogFinalize(logHandle);
+
+               if (rc != SA_AIS_OK)
+                       break;
+       }
+       test_validate(rc, SA_AIS_OK);
+}
+
 extern void saLogSelectionObjectGet_01(void);
 extern void saLogSelectionObjectGet_02(void);
 extern void saLogFinalize_01(void);
@@ -105,5 +130,6 @@ extern void saLogDispatch_01(void);
     test_case_add(1, saLogDispatch_01, "saLogDispatch() OK");
     test_case_add(1, saLogFinalize_01, "saLogFinalize() OK");
     test_case_add(1, saLogFinalize_02, "saLogFinalize() with NULL log handle");
+    test_case_add(1, saLogMultipleInitialize, "saLogInitialize() then 
saLogFinalize() immediately multiple time OK");
 }
 

------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to