A problem is that ntfd will queue alarm notifications forever if don't have
any notifications arrive.
The fix is adding periodic checking and writing alarm notifications in a queue
---
 src/ntf/ntfd/NtfAdmin.cc  | 33 ++++++++++++++++++++++++++
 src/ntf/ntfd/NtfAdmin.h   |  2 ++
 src/ntf/ntfd/NtfLogger.cc | 50 +++++++++++++++++++--------------------
 src/ntf/ntfd/NtfLogger.h  |  4 ++++
 src/ntf/ntfd/ntfs_com.h   |  2 ++
 src/ntf/ntfd/ntfs_main.c  | 23 +++++++++++++++++-
 6 files changed, 88 insertions(+), 26 deletions(-)

diff --git a/src/ntf/ntfd/NtfAdmin.cc b/src/ntf/ntfd/NtfAdmin.cc
index 8bbee69c5..7a74e336b 100644
--- a/src/ntf/ntfd/NtfAdmin.cc
+++ b/src/ntf/ntfd/NtfAdmin.cc
@@ -31,8 +31,10 @@
 #include "base/logtrace.h"
 #include "base/osaf_utility.h"
 #include "ntf/common/ntfsv_mem.h"
+#include "base/time.h"
 
 NtfAdmin *NtfAdmin::theNtfAdmin = NULL;
+static const unsigned kTimeoutMs = 5000;
 
 /**
  * This is the constructor. The cluster-wide unique counter for
@@ -743,6 +745,26 @@ void NtfAdmin::checkNotificationList() {
   TRACE_LEAVE();
 }
 
+/**
+ * Calculate timeout periodic checking
+ */
+int NtfAdmin::GeneratePollTimeout(struct timespec last) {
+  if (logger.Empty() || !activeController()) return -1;
+  struct timespec passed_time;
+  struct timespec current = base::ReadMonotonicClock();
+  osaf_timespec_subtract(&current, &last, &passed_time);
+  auto passed_time_ms = osaf_timespec_to_millis(&passed_time);
+  return (passed_time_ms < kTimeoutMs) ? (kTimeoutMs - passed_time_ms) : 0;
+}
+
+/**
+ * Periodic logging alarm notification when queue available
+ */
+void NtfAdmin::PeriodicCheck() {
+  if (logger.Empty() || !activeController()) return;
+  logger.DequeueLoggerBuffer();
+}
+
 /**
  * Check if a certain client exists.
  *
@@ -1265,6 +1287,17 @@ void discardedClear(unsigned int clientId,
   return NtfAdmin::theNtfAdmin->discardedClear(clientId, subscriptionId);
 }
 
+void PeriodicCheck() {
+  osafassert(NtfAdmin::theNtfAdmin != NULL);
+  return NtfAdmin::theNtfAdmin->PeriodicCheck();
+}
+
+int GeneratePollTimeout(struct timespec last) {
+  if (!activeController()) return -1;
+  osafassert(NtfAdmin::theNtfAdmin != NULL);
+  return NtfAdmin::theNtfAdmin->GeneratePollTimeout(last);
+}
+
 /************************C Wrappers related to CLM Integration
  * **************************/
 void add_member_node(NODE_ID node_id) {
diff --git a/src/ntf/ntfd/NtfAdmin.h b/src/ntf/ntfd/NtfAdmin.h
index 4808ca94d..a75e389e7 100644
--- a/src/ntf/ntfd/NtfAdmin.h
+++ b/src/ntf/ntfd/NtfAdmin.h
@@ -109,6 +109,8 @@ class NtfAdmin {
   uint32_t send_cluster_membership_msg_to_clients(
       SaClmClusterChangesT cluster_change, NODE_ID node_id);
   bool is_stale_client(unsigned int clientId);
+  void PeriodicCheck();
+  int GeneratePollTimeout(struct timespec last);
 
  private:
   void processNotification(unsigned int clientId,
diff --git a/src/ntf/ntfd/NtfLogger.cc b/src/ntf/ntfd/NtfLogger.cc
index f272a9a5a..06e6444df 100644
--- a/src/ntf/ntfd/NtfLogger.cc
+++ b/src/ntf/ntfd/NtfLogger.cc
@@ -108,7 +108,7 @@ void saLogStreamOpenCallback(SaInvocationT invocation,
 
 void saLogWriteLogCallback(SaInvocationT invocation, SaAisErrorT error) {
   TRACE_ENTER2("Callback for notificationId %llu", invocation);
-
+  NtfAdmin::theNtfAdmin->logger.SetErrorCb(error);
   if (SA_AIS_OK != error) {
     NtfSmartPtr notification;
 
@@ -142,30 +142,9 @@ void NtfLogger::log(NtfSmartPtr& newNotification) {
   TRACE_ENTER2("Notification Id=%llu received in logger. Logger buffer size 
%d",
                newNotification->getNotificationId(),
                static_cast<int>(queuedNotificationList.size()));
-  uint32_t is_buffer_full = isLoggerBufferFull();
-
-  // Check if there are not logged notifications in logger buffer
-  while (queuedNotificationList.empty() == false) {
-    NtfSmartPtr notification = queuedNotificationList.front();
-    queuedNotificationList.pop_front();
-    TRACE_2("Log queued notification: %llu", 
notification->getNotificationId());
-    if (SA_AIS_OK != this->logNotification(notification)) {
-      TRACE_2("Push back queued notification: %llu",
-              notification->getNotificationId());
-      queuedNotificationList.push_front(notification);  // Keep order
-      queueNotifcation(newNotification);
-      TRACE_LEAVE();
-      return;
-    }
-  }
-
-  // The new notification should be only logged if the buffer is not full
-  // and the type of notification is alarm.
-  if ((is_buffer_full == false) &&
-      (isAlarmNotification(newNotification) == true)) {
-    if (logNotification(newNotification) != SA_AIS_OK)
-      queueNotifcation(newNotification);
-  }
+  if (!isLoggerBufferFull() && isAlarmNotification(newNotification))
+    queueNotifcation(newNotification);
+  DequeueLoggerBuffer();
 
   TRACE_LEAVE();
 }
@@ -402,3 +381,24 @@ bool NtfLogger::isAlarmNotification(NtfSmartPtr& notif) {
   else
     return false;
 }
+
+void NtfLogger::DequeueLoggerBuffer() {
+  TRACE_ENTER();
+  // Check if there are not logged notifications in logger buffer
+  while (!Empty()) {
+    NtfSmartPtr notification = queuedNotificationList.front();
+    queuedNotificationList.pop_front();
+    TRACE_2("Log queued notification: %llu",
+            notification->getNotificationId());
+    if (SA_AIS_OK != this->logNotification(notification)) {
+      TRACE_2("Push back queued notification: %llu",
+              notification->getNotificationId());
+      queuedNotificationList.push_front(notification);  // Keep order
+      break;
+    }
+    if (cb_error != SA_AIS_OK) {
+      break;
+    }
+  }
+  TRACE_LEAVE();
+}
diff --git a/src/ntf/ntfd/NtfLogger.h b/src/ntf/ntfd/NtfLogger.h
index cd4053e2f..44fe8fe30 100644
--- a/src/ntf/ntfd/NtfLogger.h
+++ b/src/ntf/ntfd/NtfLogger.h
@@ -69,6 +69,9 @@ class NtfLogger {
   bool isAlarmNotification(NtfSmartPtr& notif);
 
   void resetLoggerBufferFullFlag();
+  void DequeueLoggerBuffer();
+  bool Empty() { return queuedNotificationList.empty(); }
+  void SetErrorCb(SaAisErrorT error) { cb_error = error; }
 
  private:
   SaAisErrorT initLog();
@@ -79,6 +82,7 @@ class NtfLogger {
   QueuedNotificationsList queuedNotificationList;
 
   uint32_t logger_buffer_capacity;
+  SaAisErrorT cb_error;
 
   // The flag if logger buffer is full. This is set when checking the logger
   // buffer size and is reset if the write callback return with SA_AIS_OK
diff --git a/src/ntf/ntfd/ntfs_com.h b/src/ntf/ntfd/ntfs_com.h
index b9e37da09..61ef4c627 100644
--- a/src/ntf/ntfd/ntfs_com.h
+++ b/src/ntf/ntfd/ntfs_com.h
@@ -204,6 +204,8 @@ uint32_t count_member_nodes();
 bool is_client_clm_member(NODE_ID node_id, SaVersionT *client_ver);
 bool is_clm_init();
 bool is_stale_client(unsigned int clientId);
+void PeriodicCheck();
+int GeneratePollTimeout(struct timespec last);
 
 #ifdef __cplusplus
 }
diff --git a/src/ntf/ntfd/ntfs_main.c b/src/ntf/ntfd/ntfs_main.c
index d74ddc926..176ceef01 100644
--- a/src/ntf/ntfd/ntfs_main.c
+++ b/src/ntf/ntfd/ntfs_main.c
@@ -35,6 +35,8 @@
 #include "base/daemon.h"
 #include "nid/agent/nid_api.h"
 #include "base/ncs_main_papi.h"
+#include "base/osaf_time.h"
+#include "ntf/ntfd/ntfs_com.h"
 
 #include "ntfs.h"
 #include "ntfs_imcnutil.h"
@@ -304,6 +306,10 @@ int main(int argc, char *argv[])
        int term_fd;
 
        TRACE_ENTER();
+       struct timespec last;
+       osaf_clock_gettime(CLOCK_MONOTONIC, &last);
+       const int kMaxEvent = 50;
+       int num_events = 0;
 
        daemonize(argc, argv);
 
@@ -334,7 +340,8 @@ int main(int argc, char *argv[])
                fds[FD_CLM].fd = ntfs_cb->clmSelectionObject;
                fds[FD_CLM].events = POLLIN;
 
-               int ret = poll(fds, SIZE_FDS, -1);
+               int timeout = GeneratePollTimeout(last);
+               int ret = poll(fds, SIZE_FDS, timeout);
                if (ret == -1) {
                        if (errno == EINTR)
                                continue;
@@ -343,6 +350,13 @@ int main(int argc, char *argv[])
                        break;
                }
 
+               if (ret == 0) {
+                       PeriodicCheck();
+                       osaf_clock_gettime(CLOCK_MONOTONIC, &last);
+                       num_events = 0;
+                       continue;
+               }
+
                if (fds[FD_TERM].revents & POLLIN) {
                        TRACE("Exit via FD_TERM calling stop_ntfimcn()");
                        (void)stop_ntfimcn();
@@ -406,6 +420,13 @@ int main(int argc, char *argv[])
                /* process all the log callbacks */
                if (fds[FD_LOG].revents & POLLIN)
                        logEvent();
+
+               num_events++;
+               if (num_events >= kMaxEvent) {
+                       PeriodicCheck();
+                       num_events = 0;
+                       osaf_clock_gettime(CLOCK_MONOTONIC, &last);
+               }
        }
 
 done:
-- 
2.25.1



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

Reply via email to