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(¤t, &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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel