e7a346
From db15e8fe12b7148b2da975d915573cb24c4ee1c9 Mon Sep 17 00:00:00 2001
e7a346
From: Atin Mukherjee <amukherj@redhat.com>
e7a346
Date: Thu, 22 Nov 2018 09:58:52 +0530
e7a346
Subject: [PATCH 475/493] glusterd: perform store operation in cleanup lock
e7a346
e7a346
All glusterd store operation and cleanup thread should work under a
e7a346
critical section to avoid any partial store write.
e7a346
e7a346
> Change-Id: I4f12e738f597a1f925c87ea2f42565dcf9ecdb9d
e7a346
> Fixes: bz#1652430
e7a346
> Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
e7a346
upstream patch: https://review.gluster.org/#/c/glusterfs/+/21702/
e7a346
e7a346
Change-Id: I4f12e738f597a1f925c87ea2f42565dcf9ecdb9d
e7a346
BUG: 1654161
e7a346
Signed-off-by: Sanju Rakonde <srakonde@redhat.com>
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/158804
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
---
e7a346
 glusterfsd/src/glusterfsd.c                | 73 ++++++++++++++++--------------
e7a346
 libglusterfs/src/glusterfs.h               |  1 +
e7a346
 xlators/mgmt/glusterd/src/glusterd-store.c | 10 +++-
e7a346
 3 files changed, 49 insertions(+), 35 deletions(-)
e7a346
e7a346
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
e7a346
index 03bca24..57effbd 100644
e7a346
--- a/glusterfsd/src/glusterfsd.c
e7a346
+++ b/glusterfsd/src/glusterfsd.c
e7a346
@@ -1395,43 +1395,46 @@ cleanup_and_exit (int signum)
e7a346
         if (ctx->cleanup_started)
e7a346
                 return;
e7a346
 
e7a346
-        ctx->cleanup_started = 1;
e7a346
+        pthread_mutex_lock(&ctx->cleanup_lock);
e7a346
+        {
e7a346
+                ctx->cleanup_started = 1;
e7a346
 
e7a346
-        /* signout should be sent to all the bricks in case brick mux is enabled
e7a346
-         * and multiple brick instances are attached to this process
e7a346
-         */
e7a346
-        if (ctx->active) {
e7a346
-                top = ctx->active->first;
e7a346
-                for (trav_p = &top->children; *trav_p;
e7a346
-                     trav_p = &(*trav_p)->next) {
e7a346
-                        victim = (*trav_p)->xlator;
e7a346
-                        glusterfs_mgmt_pmap_signout (ctx, victim->name);
e7a346
+                /* signout should be sent to all the bricks in case brick mux
e7a346
+                 * is enabled and multiple brick instances are attached to this
e7a346
+                 * process
e7a346
+                 */
e7a346
+                if (ctx->active) {
e7a346
+                        top = ctx->active->first;
e7a346
+                        for (trav_p = &top->children; *trav_p;
e7a346
+                             trav_p = &(*trav_p)->next) {
e7a346
+                                victim = (*trav_p)->xlator;
e7a346
+                                glusterfs_mgmt_pmap_signout (ctx, victim->name);
e7a346
+                        }
e7a346
+                } else {
e7a346
+                        glusterfs_mgmt_pmap_signout (ctx, NULL);
e7a346
                 }
e7a346
-        } else {
e7a346
-                glusterfs_mgmt_pmap_signout (ctx, NULL);
e7a346
-        }
e7a346
 
e7a346
-        /* below part is a racy code where the rpcsvc object is freed.
e7a346
-         * But in another thread (epoll thread), upon poll error in the
e7a346
-         * socket the transports are cleaned up where again rpcsvc object
e7a346
-         * is accessed (which is already freed by the below function).
e7a346
-         * Since the process is about to be killed dont execute the function
e7a346
-         * below.
e7a346
-         */
e7a346
-        /* if (ctx->listener) { */
e7a346
-        /*         (void) glusterfs_listener_stop (ctx); */
e7a346
-        /* } */
e7a346
+                /* below part is a racy code where the rpcsvc object is freed.
e7a346
+                 * But in another thread (epoll thread), upon poll error in the
e7a346
+                 * socket the transports are cleaned up where again rpcsvc object
e7a346
+                 * is accessed (which is already freed by the below function).
e7a346
+                 * Since the process is about to be killed dont execute the
e7a346
+                 * function below.
e7a346
+                 */
e7a346
+                /* if (ctx->listener) { */
e7a346
+                /*         (void) glusterfs_listener_stop (ctx); */
e7a346
+                /* } */
e7a346
 
e7a346
-        /* Call fini() of FUSE xlator first:
e7a346
-         * so there are no more requests coming and
e7a346
-         * 'umount' of mount point is done properly */
e7a346
-        trav = ctx->master;
e7a346
-        if (trav && trav->fini) {
e7a346
-                THIS = trav;
e7a346
-                trav->fini (trav);
e7a346
-        }
e7a346
+                /* Call fini() of FUSE xlator first:
e7a346
+                 * so there are no more requests coming and
e7a346
+                 * 'umount' of mount point is done properly */
e7a346
+                trav = ctx->master;
e7a346
+                if (trav && trav->fini) {
e7a346
+                        THIS = trav;
e7a346
+                        trav->fini (trav);
e7a346
+                }
e7a346
 
e7a346
-        glusterfs_pidfile_cleanup (ctx);
e7a346
+                glusterfs_pidfile_cleanup (ctx);
e7a346
 
e7a346
 #if 0
e7a346
         /* TODO: Properly do cleanup_and_exit(), with synchronization */
e7a346
@@ -1442,8 +1445,9 @@ cleanup_and_exit (int signum)
e7a346
         }
e7a346
 #endif
e7a346
 
e7a346
-        trav = NULL;
e7a346
-
e7a346
+                trav = NULL;
e7a346
+        }
e7a346
+        pthread_mutex_unlock(&ctx->cleanup_lock);
e7a346
         /* NOTE: Only the least significant 8 bits i.e (signum & 255)
e7a346
            will be available to parent process on calling exit() */
e7a346
         exit(abs(signum));
e7a346
@@ -1598,6 +1602,7 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
e7a346
                 goto out;
e7a346
 
e7a346
         pthread_mutex_init (&ctx->notify_lock, NULL);
e7a346
+        pthread_mutex_init(&ctx->cleanup_lock, NULL);
e7a346
         pthread_cond_init (&ctx->notify_cond, NULL);
e7a346
 
e7a346
         ctx->clienttable = gf_clienttable_alloc();
e7a346
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
e7a346
index d06d8cf..c12e94e 100644
e7a346
--- a/libglusterfs/src/glusterfs.h
e7a346
+++ b/libglusterfs/src/glusterfs.h
e7a346
@@ -574,6 +574,7 @@ struct _glusterfs_ctx {
e7a346
         char               btbuf[GF_BACKTRACE_LEN];
e7a346
 
e7a346
         pthread_mutex_t    notify_lock;
e7a346
+        pthread_mutex_t    cleanup_lock;
e7a346
         pthread_cond_t     notify_cond;
e7a346
         int                notifying;
e7a346
 
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
e7a346
index f276fef..b3c4d9a 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
e7a346
@@ -1792,10 +1792,17 @@ out:
e7a346
 int32_t
e7a346
 glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac)
e7a346
 {
e7a346
-        int32_t                 ret = -1;
e7a346
+        int32_t                 ret  = -1;
e7a346
+        glusterfs_ctx_t        *ctx  = NULL;
e7a346
+        xlator_t               *this = NULL;
e7a346
 
e7a346
+        this = THIS;
e7a346
+        GF_ASSERT(this);
e7a346
+        ctx = this->ctx;
e7a346
+        GF_ASSERT(ctx);
e7a346
         GF_ASSERT (volinfo);
e7a346
 
e7a346
+        pthread_mutex_lock(&ctx->cleanup_lock);
e7a346
         pthread_mutex_lock(&volinfo->store_volinfo_lock);
e7a346
         {
e7a346
                 glusterd_perform_volinfo_version_action(volinfo, ac);
e7a346
@@ -1837,6 +1844,7 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a
e7a346
         }
e7a346
 unlock:
e7a346
         pthread_mutex_unlock(&volinfo->store_volinfo_lock);
e7a346
+        pthread_mutex_unlock(&ctx->cleanup_lock);
e7a346
         if (ret)
e7a346
                 glusterd_store_volume_cleanup_tmp(volinfo);
e7a346
 
e7a346
-- 
e7a346
1.8.3.1
e7a346