Changed according to comment from Minh.
OM Handle is now initialized only when imcn process start and
is reinitialized if SA_AIS_ERR_UNAVAILABLE
Also comment about resource handling in case of error in get_rdn_attr_name()
long_description
---
src/ntf/ntfimcnd/ntfimcn_imm.c | 122 +++++++++++++++++++++++++++++-----------
src/ntf/ntfimcnd/ntfimcn_imm.h | 9 ---
src/ntf/ntfimcnd/ntfimcn_main.h | 1 +
3 files changed, 90 insertions(+), 42 deletions(-)
diff --git a/src/ntf/ntfimcnd/ntfimcn_imm.c b/src/ntf/ntfimcnd/ntfimcn_imm.c
index d751a724c..fd97a5c6a 100644
--- a/src/ntf/ntfimcnd/ntfimcn_imm.c
+++ b/src/ntf/ntfimcnd/ntfimcn_imm.c
@@ -42,6 +42,11 @@
#include "ntfimcn_notifier.h"
/*
+ * Global variables
+ */
+extern ntfimcn_cb_t ntfimcn_cb; /* See ntfimcn_main.c */
+
+/*
* Global, scope file
*/
/* Release code, major version, minor version */
@@ -81,13 +86,73 @@ struct {
#define NOTIFYING_OBJECT "safApp=safImmService"
-extern ntfimcn_cb_t ntfimcn_cb;
+static bool initializeImmOmHandle(SaImmHandleT* immOmHandle);
+static void finalizeImmOmHandle(SaImmHandleT immOmHandle);
+
+/**
+ * Get a class description for the given className
+ *
+ * Handles SA_AIS_ERR_TRY_AGAIN loop
+ * Also retries once if SA_AIS_ERR_UNAVAILABLE
+ * Note: Uses saImmOmClassDescriptionGet_2() that allocates memory that
+ * has to be freed by calling saImmOmClassDescriptionMemoryFree_2()
+ *
+ * See AIS saImmOmClassDescriptionGet_2
+ * @param className[in]
+ * @param attrDescr[out]
+ * @return AIS return code
+ */
+static SaAisErrorT getClassDescription(const SaImmClassNameT className,
+ SaImmAttrDefinitionT_2 ***attrDescr)
+{
+ SaImmClassCategoryT classCategory;
+ struct timespec timeout_ts;
+ struct timespec delay_ts;
+ SaAisErrorT ais_rc;
+
+ osaf_millis_to_timespec(sleep_delay_ms, &delay_ts);
+ osaf_set_millis_timeout(max_waiting_time_7s, &timeout_ts);
+
+ for (int i = 0; i <= 1; i++) {
+ while (osaf_is_timeout(&timeout_ts) == false) {
+ ais_rc = saImmOmClassDescriptionGet_2(
+ ntfimcn_cb.immOmHandle,
+ className, &classCategory, attrDescr);
+ if ((ais_rc != SA_AIS_ERR_TRY_AGAIN) &&
+ (ais_rc != SA_AIS_ERR_TIMEOUT)) {
+ break;
+ }
+ osaf_nanosleep(&delay_ts);
+ }
+
+ /*
+ * If SA_AIS_ERR_UNAVAILABLE we may have left the CLM cluster
+ * The old handle must be finalized, a new initialized and one
+ * new attempt to get the class description shall be done.
+ */
+ if (ais_rc == SA_AIS_ERR_UNAVAILABLE) {
+ finalizeImmOmHandle(ntfimcn_cb.immOmHandle);
+ if (initializeImmOmHandle(&ntfimcn_cb.immOmHandle) ==
+ false) {
+ break; /* Failed to initialize OM handle */
+ }
+ } else break;
+ }
+
+ if (ais_rc != SA_AIS_OK) {
+ LOG_NO("%s saImmOmClassDescriptionGet_2 failed %s",
+ __FUNCTION__, saf_error(ais_rc));
+ }
+
+ return ais_rc;
+}
/**
* Get name of rdn attribute from IMM
*
* Note:
* Uses in file global struct s_get_rdn_attr_name
+ * Uses global immOmHandle in struct ntfimcn_cb_t
*
* @param className[in]
*
@@ -96,10 +161,8 @@ extern ntfimcn_cb_t ntfimcn_cb;
static char *get_rdn_attr_name(const SaImmClassNameT className)
{
SaAisErrorT rc;
- int msecs_waited;
int i = 0;
- SaImmClassCategoryT classCategory;
SaImmAttrDefinitionT_2 **attrDescr;
TRACE_ENTER();
@@ -118,25 +181,8 @@ static char *get_rdn_attr_name(const SaImmClassNameT
className)
memcpy(s_get_rdn_attr_name.saved_className, className,
strlen(className) + 1);
- /* Get an IMM OM Handle */
- SaImmHandleT immOmHandle = 0;
- if (getImmOmHandle(&immOmHandle) == false) {
- LOG_ER("getImmOmHandle() Fail");
- goto error;
- }
-
/* Get class description */
- msecs_waited = 0;
- rc = saImmOmClassDescriptionGet_2(immOmHandle, className,
- &classCategory, &attrDescr);
- while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc == SA_AIS_ERR_TIMEOUT)) &&
- (msecs_waited < max_waiting_time_7s)) {
- usleep(sleep_delay_ms * 1000);
- msecs_waited += sleep_delay_ms;
- rc = saImmOmClassDescriptionGet_2(immOmHandle,
- className, &classCategory,
- &attrDescr);
- }
+ rc = getClassDescription(className, &attrDescr);
if (rc != SA_AIS_OK) {
LOG_ER("saImmOmClassDescriptionGet_2 failed %s", saf_error(rc));
goto error;
@@ -160,21 +206,24 @@ static char *get_rdn_attr_name(const SaImmClassNameT
className)
}
/* Free memory allocated for attribute descriptions */
- rc = saImmOmClassDescriptionMemoryFree_2(immOmHandle,
+ rc = saImmOmClassDescriptionMemoryFree_2(ntfimcn_cb.immOmHandle,
attrDescr);
if (rc != SA_AIS_OK) {
- LOG_ER("saImmOmClassDescriptionMemoryFree_2 failed %s",
- saf_error(rc));
+ LOG_NO("saImmOmClassDescriptionMemoryFree_2() Fail %s",
+ saf_error(rc));
goto error;
}
- /* Release the OM Handle */
- finalizeImmOmHandle(immOmHandle);
-
done:
TRACE_LEAVE();
return s_get_rdn_attr_name.attrName;
error:
+ /* NOTE: Resources are allocated by this function
+ * saImmOmClassDescriptionMemoryFree_2() must be called before
+ * returning from this function. Not done here because of
+ * osafassert()
+ */
+ LOG_ER("%s Failed", __FUNCTION__);
osafassert(0);
return 0; /* Dummy */
}
@@ -842,6 +891,15 @@ int ntfimcn_imm_init(ntfimcn_cb_t *cb)
break;
}
+ /*
+ * Initialize an Object Manager
+ * ----------------------------
+ */
+ cb->immOmHandle = 0;
+ if (initializeImmOmHandle(&cb->immOmHandle) == false) {
+ internal_rc = NTFIMCN_INTERNAL_ERROR;
+ }
+
done:
TRACE_LEAVE();
return internal_rc;
@@ -850,12 +908,10 @@ done:
/**
* Initialize an IMM OM Handle
*
- * Note: Writes to syslog if error
- *
* @param immOmHandle[out] Set to OM Handle or 0 if Fail
* @return false if Fail
*/
-bool getImmOmHandle(SaImmOiHandleT* immOmHandle) {
+static bool initializeImmOmHandle(SaImmHandleT* immOmHandle) {
struct timespec timeout_ts;
struct timespec delay_ts;
SaAisErrorT ais_rc;
@@ -874,14 +930,14 @@ bool getImmOmHandle(SaImmOiHandleT* immOmHandle) {
}
if (ais_rc != SA_AIS_OK) {
- LOG_ER("%s saImmOmInitialize failed %s", __FUNCTION__,
+ LOG_NO("%s saImmOmInitialize failed %s", __FUNCTION__,
saf_error(ais_rc));
internal_rc = false;
}
return internal_rc;
}
-void finalizeImmOmHandle(SaImmHandleT immOmHandle) {
+static void finalizeImmOmHandle(SaImmHandleT immOmHandle) {
struct timespec timeout_ts;
struct timespec delay_ts;
SaAisErrorT ais_rc;
@@ -898,7 +954,7 @@ void finalizeImmOmHandle(SaImmHandleT immOmHandle) {
}
if (ais_rc != SA_AIS_OK) {
- LOG_ER("%s saImmOmInitialize failed %s", __FUNCTION__,
+ LOG_NO("%s saImmOmInitialize failed %s", __FUNCTION__,
saf_error(ais_rc));
}
}
\ No newline at end of file
diff --git a/src/ntf/ntfimcnd/ntfimcn_imm.h b/src/ntf/ntfimcnd/ntfimcn_imm.h
index 86825a590..bffe58cc3 100644
--- a/src/ntf/ntfimcnd/ntfimcn_imm.h
+++ b/src/ntf/ntfimcnd/ntfimcn_imm.h
@@ -36,15 +36,6 @@ extern "C" {
*/
int ntfimcn_imm_init(ntfimcn_cb_t *cb);
-/**
- * Initialize an IMM OM Handle
- *
- * @param immOmHandle[out] Set to OM Handle or 0 if Fail
- * @return false if Fail
- */
-bool getImmOmHandle(SaImmOiHandleT* immOmHandle);
-void finalizeImmOmHandle(SaImmOiHandleT immOmHandle);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/ntf/ntfimcnd/ntfimcn_main.h b/src/ntf/ntfimcnd/ntfimcn_main.h
index c8a207377..115d71ef7 100644
--- a/src/ntf/ntfimcnd/ntfimcn_main.h
+++ b/src/ntf/ntfimcnd/ntfimcn_main.h
@@ -40,6 +40,7 @@ extern "C" {
#define NTFIMCN_IMM_ATTR "SaImmAttr"
typedef struct {
+ SaImmHandleT immOmHandle; /* Handle form IMM OM Initialize */
SaImmOiHandleT immOiHandle; /* Handle from IMM OI initialize */
SaSelectionObjectT
immSelectionObject; /* Selection Object to wait for IMM events */