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