In the scenario of shutting down SC while SC switchover is on going,
ntfd coredump is generated due to failure of pthread_mutex_destroy()
with errorcode:16(EBUSY). That means the mutex had been taken and
was not unlocked at the time phtread_mutex_destroy() is called.

This patch changes the way ntfd stops ntfimcn and cnsruvail_thread()
so that the cnsurvai_thread does not restart ntfimcn in stop sequence.
Therefore, when cnsurval_thread receives cancellation request, this
thread does not do anything that may lead to cancellation point with
a locked mutex.
---
 src/ntf/ntfd/ntfs_imcnutil.c | 58 +++++++++++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 19 deletions(-)

diff --git a/src/ntf/ntfd/ntfs_imcnutil.c b/src/ntf/ntfd/ntfs_imcnutil.c
index dd27a255c..cc257703b 100644
--- a/src/ntf/ntfd/ntfs_imcnutil.c
+++ b/src/ntf/ntfd/ntfs_imcnutil.c
@@ -44,6 +44,8 @@ typedef struct {
        SaAmfHAStateT ha_state;
        pid_t pid;
        pthread_t thread;
+       /* ntfimcn functionality: true(enabled), false(disabled)  */
+       bool ntfimcn_on;
 } init_params_t;
 
 static init_params_t ipar;
@@ -240,8 +242,17 @@ static void *cnsurvail_thread(void *_init_params)
 
        while (1) {
                osaf_mutex_lock_ordie(&ntfimcn_mutex);
-               pid = create_imcnprocess(ipar->ha_state);
-               ipar->pid = pid;
+               /* Only start ntfimcn process if this functionality is
+                * enabled, this is to avoid restarting ntfimcn when ntfd
+                * receives SIGTERM (shutting down)
+                * NOTE: Do not add any code outside below *if @ntfimcn_on*
+                * block that may lead to a thread cancellation point while
+                * ntfimcn_mutex is being locked
+                */
+               if (ipar->ntfimcn_on == true) {
+                       pid = create_imcnprocess(ipar->ha_state);
+                       ipar->pid = pid;
+               }
                osaf_mutex_unlock_ordie(&ntfimcn_mutex);
 
                /* Wait for child process to exit */
@@ -271,7 +282,8 @@ static void *cnsurvail_thread(void *_init_params)
 
 /**
  * Start the imcn process surveillance thread
- *
+ * When surveillance thread is running, this thread
+ * will start and monitor ntfimcn process in cnsurvail_thread()
  * @param ha_state[in]
  */
 static void start_cnprocess(SaAmfHAStateT ha_state)
@@ -285,7 +297,8 @@ static void start_cnprocess(SaAmfHAStateT ha_state)
                osaf_abort(rc);
 
        ipar.ha_state = ha_state;
-
+       ipar.ntfimcn_on = true;
+       ipar.pid = 0;
        rc =
            pthread_create(&ipar.thread, NULL, cnsurvail_thread, (void *)&ipar);
        if (rc != 0)
@@ -330,33 +343,40 @@ void handle_state_ntfimcn(SaAmfHAStateT ha_state)
 }
 
 /**
- * Cancel the surveillance trhead and kill the imcn process.
+ * This function stops functionality of ntfimcn by:
+ * First: Kill imcn process
+ * Second: Cancel the surveillance thread
+ * (in reversed order of start ntfimcn)
  * Use the pid and thread id saved when the process was started
  * This will terminate the process permanently.
  *
- * @return -1 if error
+ * @return 0 if success, abort() on any error
  */
 int stop_ntfimcn(void)
 {
-       void *join_ret;
        int rc = 0;
        TRACE_ENTER();
 
-       if (ipar.ha_state != 0) {
-               TRACE("%s: Cancel the imcn surveillance thread", __FUNCTION__);
-               rc = pthread_cancel(ipar.thread);
-               if (rc != 0)
-                       osaf_abort(rc);
-               rc = pthread_join(ipar.thread, &join_ret);
-               if (rc != 0)
-                       osaf_abort(rc);
-               rc = pthread_mutex_destroy(&ntfimcn_mutex);
-               if (rc != 0)
-                       osaf_abort(rc);
-
+       /* Kill ntfimcn */
+       osaf_mutex_lock_ordie(&ntfimcn_mutex);
+       if (ipar.ntfimcn_on == true) {
+               ipar.ntfimcn_on = false;
                TRACE("%s: Terminating osafntfimcnd process", __FUNCTION__);
                timedwait_imcn_exit();
        }
+       osaf_mutex_unlock_ordie(&ntfimcn_mutex);
+
+       /* Cancel the surveillance thread */
+       TRACE("%s: Cancel the imcn surveillance thread", __FUNCTION__);
+       rc = pthread_cancel(ipar.thread);
+       if (rc != 0)
+               osaf_abort(rc);
+       rc = pthread_join(ipar.thread, NULL);
+       if (rc != 0)
+               osaf_abort(rc);
+       rc = pthread_mutex_destroy(&ntfimcn_mutex);
+       if (rc != 0)
+               osaf_abort(rc);
 
        TRACE_LEAVE();
        return rc;
-- 
2.11.0


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to