233933
From 2f5969a77493814e242e6bac3c6bf7acf3202e0f Mon Sep 17 00:00:00 2001
233933
From: Xavi Hernandez <xhernandez@redhat.com>
233933
Date: Tue, 5 Mar 2019 18:58:20 +0100
233933
Subject: [PATCH 209/221] core: avoid dynamic TLS allocation when possible
233933
233933
Some interdependencies between logging and memory management functions
233933
make it impossible to use the logging framework before initializing
233933
memory subsystem because they both depend on Thread Local Storage
233933
allocated through pthread_key_create() during initialization.
233933
233933
This causes a crash when we try to log something very early in the
233933
initialization phase.
233933
233933
To prevent this, several dynamically allocated TLS structures have
233933
been replaced by static TLS reserved at compile time using '__thread'
233933
keyword. This also reduces the number of error sources, making
233933
initialization simpler.
233933
233933
Upstream patch:
233933
> BUG: 1193929
233933
> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22302
233933
> Change-Id: I8ea2e072411e30790d50084b6b7e909c7bb01d50
233933
> Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
233933
233933
Change-Id: I8ea2e072411e30790d50084b6b7e909c7bb01d50
233933
Updates: bz#1722801
233933
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
233933
Reviewed-on: https://code.engineering.redhat.com/gerrit/174711
233933
Tested-by: RHGS Build Bot <nigelb@redhat.com>
233933
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
233933
---
233933
 api/src/glfs.c                                     |   3 +-
233933
 cli/src/cli.c                                      |   3 +-
233933
 glusterfsd/src/glusterfsd.c                        |   4 +-
233933
 libglusterfs/src/globals.c                         | 289 ++++-----------------
233933
 libglusterfs/src/glusterfs/globals.h               |   6 +-
233933
 libglusterfs/src/glusterfs/mem-pool.h              |   7 +-
233933
 libglusterfs/src/libglusterfs.sym                  |   3 +-
233933
 libglusterfs/src/mem-pool.c                        |  98 +++----
233933
 libglusterfs/src/syncop.c                          | 133 ++--------
233933
 .../changelog/lib/src/gf-changelog-helpers.c       |  51 +---
233933
 xlators/features/changelog/lib/src/gf-changelog.c  |   3 +-
233933
 xlators/nfs/server/src/mount3udp_svc.c             |   6 +-
233933
 12 files changed, 114 insertions(+), 492 deletions(-)
233933
233933
diff --git a/api/src/glfs.c b/api/src/glfs.c
233933
index 6bbb620..f36616d 100644
233933
--- a/api/src/glfs.c
233933
+++ b/api/src/glfs.c
233933
@@ -829,8 +829,7 @@ pub_glfs_new(const char *volname)
233933
      * Do this as soon as possible in case something else depends on
233933
      * pool allocations.
233933
      */
233933
-    mem_pools_init_early();
233933
-    mem_pools_init_late();
233933
+    mem_pools_init();
233933
 
233933
     fs = glfs_new_fs(volname);
233933
     if (!fs)
233933
diff --git a/cli/src/cli.c b/cli/src/cli.c
233933
index ff39a98..99a16a0 100644
233933
--- a/cli/src/cli.c
233933
+++ b/cli/src/cli.c
233933
@@ -795,8 +795,7 @@ main(int argc, char *argv[])
233933
     int ret = -1;
233933
     glusterfs_ctx_t *ctx = NULL;
233933
 
233933
-    mem_pools_init_early();
233933
-    mem_pools_init_late();
233933
+    mem_pools_init();
233933
 
233933
     ctx = glusterfs_ctx_new();
233933
     if (!ctx)
233933
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
233933
index 6aee4c1..2172af4 100644
233933
--- a/glusterfsd/src/glusterfsd.c
233933
+++ b/glusterfsd/src/glusterfsd.c
233933
@@ -2722,8 +2722,6 @@ main(int argc, char *argv[])
233933
     };
233933
     cmd_args_t *cmd = NULL;
233933
 
233933
-    mem_pools_init_early();
233933
-
233933
     gf_check_and_set_mem_acct(argc, argv);
233933
 
233933
     ctx = glusterfs_ctx_new();
233933
@@ -2838,7 +2836,7 @@ main(int argc, char *argv[])
233933
      * the parent, but we want to do it as soon as possible after that in
233933
      * case something else depends on pool allocations.
233933
      */
233933
-    mem_pools_init_late();
233933
+    mem_pools_init();
233933
 
233933
 #ifdef GF_LINUX_HOST_OS
233933
     ret = set_oom_score_adj(ctx);
233933
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
233933
index 4fec063..02098e6 100644
233933
--- a/libglusterfs/src/globals.c
233933
+++ b/libglusterfs/src/globals.c
233933
@@ -99,16 +99,19 @@ const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = {
233933
 glusterfs_ctx_t *global_ctx = NULL;
233933
 pthread_mutex_t global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
233933
 xlator_t global_xlator;
233933
-static pthread_key_t this_xlator_key;
233933
-static pthread_key_t synctask_key;
233933
-static pthread_key_t uuid_buf_key;
233933
-static char global_uuid_buf[GF_UUID_BUF_SIZE];
233933
-static pthread_key_t lkowner_buf_key;
233933
-static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
233933
-static pthread_key_t leaseid_buf_key;
233933
 static int gf_global_mem_acct_enable = 1;
233933
 static pthread_once_t globals_inited = PTHREAD_ONCE_INIT;
233933
 
233933
+static pthread_key_t free_key;
233933
+
233933
+static __thread xlator_t *thread_xlator = NULL;
233933
+static __thread void *thread_synctask = NULL;
233933
+static __thread void *thread_leaseid = NULL;
233933
+static __thread struct syncopctx thread_syncopctx = {};
233933
+static __thread char thread_uuid_buf[GF_UUID_BUF_SIZE] = {};
233933
+static __thread char thread_lkowner_buf[GF_LKOWNER_BUF_SIZE] = {};
233933
+static __thread char thread_leaseid_buf[GF_LEASE_ID_BUF_SIZE] = {};
233933
+
233933
 int
233933
 gf_global_mem_acct_enable_get(void)
233933
 {
233933
@@ -122,12 +125,6 @@ gf_global_mem_acct_enable_set(int val)
233933
     return 0;
233933
 }
233933
 
233933
-void
233933
-glusterfs_this_destroy(void *ptr)
233933
-{
233933
-    FREE(ptr);
233933
-}
233933
-
233933
 static struct xlator_cbks global_cbks = {
233933
     .forget = NULL,
233933
     .release = NULL,
233933
@@ -212,18 +209,9 @@ struct volume_options global_xl_options[] = {
233933
 
233933
 static volume_opt_list_t global_xl_opt_list;
233933
 
233933
-int
233933
+void
233933
 glusterfs_this_init()
233933
 {
233933
-    int ret = 0;
233933
-    ret = pthread_key_create(&this_xlator_key, glusterfs_this_destroy);
233933
-    if (ret != 0) {
233933
-        gf_msg("", GF_LOG_WARNING, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
233933
-               "failed to create "
233933
-               "the pthread key");
233933
-        return ret;
233933
-    }
233933
-
233933
     global_xlator.name = "glusterfs";
233933
     global_xlator.type = GF_GLOBAL_XLATOR_NAME;
233933
     global_xlator.cbks = &global_cbks;
233933
@@ -237,301 +225,120 @@ glusterfs_this_init()
233933
     global_xl_opt_list.given_opt = global_xl_options;
233933
 
233933
     list_add_tail(&global_xl_opt_list.list, &global_xlator.volume_options);
233933
-
233933
-    return ret;
233933
 }
233933
 
233933
 xlator_t **
233933
 __glusterfs_this_location()
233933
 {
233933
-    xlator_t **this_location = NULL;
233933
-    int ret = 0;
233933
-
233933
-    this_location = pthread_getspecific(this_xlator_key);
233933
-
233933
-    if (!this_location) {
233933
-        this_location = CALLOC(1, sizeof(*this_location));
233933
-        if (!this_location)
233933
-            goto out;
233933
+    xlator_t **this_location;
233933
 
233933
-        ret = pthread_setspecific(this_xlator_key, this_location);
233933
-        if (ret != 0) {
233933
-            FREE(this_location);
233933
-            this_location = NULL;
233933
-            goto out;
233933
-        }
233933
-    }
233933
-out:
233933
-    if (this_location) {
233933
-        if (!*this_location)
233933
-            *this_location = &global_xlator;
233933
+    this_location = &thread_xlator;
233933
+    if (*this_location == NULL) {
233933
+        thread_xlator = &global_xlator;
233933
     }
233933
+
233933
     return this_location;
233933
 }
233933
 
233933
 xlator_t *
233933
 glusterfs_this_get()
233933
 {
233933
-    xlator_t **this_location = NULL;
233933
-
233933
-    this_location = __glusterfs_this_location();
233933
-    if (!this_location)
233933
-        return &global_xlator;
233933
-
233933
-    return *this_location;
233933
+    return *__glusterfs_this_location();
233933
 }
233933
 
233933
-int
233933
+void
233933
 glusterfs_this_set(xlator_t *this)
233933
 {
233933
-    xlator_t **this_location = NULL;
233933
-
233933
-    this_location = __glusterfs_this_location();
233933
-    if (!this_location)
233933
-        return -ENOMEM;
233933
-
233933
-    *this_location = this;
233933
-
233933
-    return 0;
233933
+    thread_xlator = this;
233933
 }
233933
 
233933
 /* SYNCOPCTX */
233933
-static pthread_key_t syncopctx_key;
233933
-
233933
-static void
233933
-syncopctx_key_destroy(void *ptr)
233933
-{
233933
-    struct syncopctx *opctx = ptr;
233933
-
233933
-    if (opctx) {
233933
-        if (opctx->groups)
233933
-            GF_FREE(opctx->groups);
233933
-
233933
-        GF_FREE(opctx);
233933
-    }
233933
-
233933
-    return;
233933
-}
233933
 
233933
 void *
233933
 syncopctx_getctx()
233933
 {
233933
-    void *opctx = NULL;
233933
-
233933
-    opctx = pthread_getspecific(syncopctx_key);
233933
-
233933
-    return opctx;
233933
-}
233933
-
233933
-int
233933
-syncopctx_setctx(void *ctx)
233933
-{
233933
-    int ret = 0;
233933
-
233933
-    ret = pthread_setspecific(syncopctx_key, ctx);
233933
-
233933
-    return ret;
233933
-}
233933
-
233933
-static int
233933
-syncopctx_init(void)
233933
-{
233933
-    int ret;
233933
-
233933
-    ret = pthread_key_create(&syncopctx_key, syncopctx_key_destroy);
233933
-
233933
-    return ret;
233933
+    return &thread_syncopctx;
233933
 }
233933
 
233933
 /* SYNCTASK */
233933
 
233933
-int
233933
-synctask_init()
233933
-{
233933
-    int ret = 0;
233933
-
233933
-    ret = pthread_key_create(&synctask_key, NULL);
233933
-
233933
-    return ret;
233933
-}
233933
-
233933
 void *
233933
 synctask_get()
233933
 {
233933
-    void *synctask = NULL;
233933
-
233933
-    synctask = pthread_getspecific(synctask_key);
233933
-
233933
-    return synctask;
233933
+    return thread_synctask;
233933
 }
233933
 
233933
-int
233933
+void
233933
 synctask_set(void *synctask)
233933
 {
233933
-    int ret = 0;
233933
-
233933
-    pthread_setspecific(synctask_key, synctask);
233933
-
233933
-    return ret;
233933
+    thread_synctask = synctask;
233933
 }
233933
 
233933
 // UUID_BUFFER
233933
 
233933
-void
233933
-glusterfs_uuid_buf_destroy(void *ptr)
233933
-{
233933
-    FREE(ptr);
233933
-}
233933
-
233933
-int
233933
-glusterfs_uuid_buf_init()
233933
-{
233933
-    int ret = 0;
233933
-
233933
-    ret = pthread_key_create(&uuid_buf_key, glusterfs_uuid_buf_destroy);
233933
-    return ret;
233933
-}
233933
-
233933
 char *
233933
 glusterfs_uuid_buf_get()
233933
 {
233933
-    char *buf;
233933
-    int ret = 0;
233933
-
233933
-    buf = pthread_getspecific(uuid_buf_key);
233933
-    if (!buf) {
233933
-        buf = MALLOC(GF_UUID_BUF_SIZE);
233933
-        ret = pthread_setspecific(uuid_buf_key, (void *)buf);
233933
-        if (ret)
233933
-            buf = global_uuid_buf;
233933
-    }
233933
-    return buf;
233933
+    return thread_uuid_buf;
233933
 }
233933
 
233933
 /* LKOWNER_BUFFER */
233933
 
233933
-void
233933
-glusterfs_lkowner_buf_destroy(void *ptr)
233933
-{
233933
-    FREE(ptr);
233933
-}
233933
-
233933
-int
233933
-glusterfs_lkowner_buf_init()
233933
-{
233933
-    int ret = 0;
233933
-
233933
-    ret = pthread_key_create(&lkowner_buf_key, glusterfs_lkowner_buf_destroy);
233933
-    return ret;
233933
-}
233933
-
233933
 char *
233933
 glusterfs_lkowner_buf_get()
233933
 {
233933
-    char *buf;
233933
-    int ret = 0;
233933
-
233933
-    buf = pthread_getspecific(lkowner_buf_key);
233933
-    if (!buf) {
233933
-        buf = MALLOC(GF_LKOWNER_BUF_SIZE);
233933
-        ret = pthread_setspecific(lkowner_buf_key, (void *)buf);
233933
-        if (ret)
233933
-            buf = global_lkowner_buf;
233933
-    }
233933
-    return buf;
233933
+    return thread_lkowner_buf;
233933
 }
233933
 
233933
 /* Leaseid buffer */
233933
-void
233933
-glusterfs_leaseid_buf_destroy(void *ptr)
233933
-{
233933
-    FREE(ptr);
233933
-}
233933
-
233933
-int
233933
-glusterfs_leaseid_buf_init()
233933
-{
233933
-    int ret = 0;
233933
-
233933
-    ret = pthread_key_create(&leaseid_buf_key, glusterfs_leaseid_buf_destroy);
233933
-    return ret;
233933
-}
233933
 
233933
 char *
233933
 glusterfs_leaseid_buf_get()
233933
 {
233933
     char *buf = NULL;
233933
-    int ret = 0;
233933
 
233933
-    buf = pthread_getspecific(leaseid_buf_key);
233933
-    if (!buf) {
233933
-        buf = CALLOC(1, GF_LEASE_ID_BUF_SIZE);
233933
-        ret = pthread_setspecific(leaseid_buf_key, (void *)buf);
233933
-        if (ret) {
233933
-            FREE(buf);
233933
-            buf = NULL;
233933
-        }
233933
+    buf = thread_leaseid;
233933
+    if (buf == NULL) {
233933
+        buf = thread_leaseid_buf;
233933
+        thread_leaseid = buf;
233933
     }
233933
+
233933
     return buf;
233933
 }
233933
 
233933
 char *
233933
 glusterfs_leaseid_exist()
233933
 {
233933
-    return pthread_getspecific(leaseid_buf_key);
233933
+    return thread_leaseid;
233933
 }
233933
 
233933
 static void
233933
-gf_globals_init_once()
233933
+glusterfs_cleanup(void *ptr)
233933
 {
233933
-    int ret = 0;
233933
-
233933
-    ret = glusterfs_this_init();
233933
-    if (ret) {
233933
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_TRANSLATOR_INIT_FAILED,
233933
-               "ERROR: glusterfs-translator init failed");
233933
-        goto out;
233933
-    }
233933
-
233933
-    ret = glusterfs_uuid_buf_init();
233933
-    if (ret) {
233933
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_UUID_BUF_INIT_FAILED,
233933
-               "ERROR: glusterfs uuid buffer init failed");
233933
-        goto out;
233933
+    if (thread_syncopctx.groups != NULL) {
233933
+        GF_FREE(thread_syncopctx.groups);
233933
     }
233933
 
233933
-    ret = glusterfs_lkowner_buf_init();
233933
-    if (ret) {
233933
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LKOWNER_BUF_INIT_FAILED,
233933
-               "ERROR: glusterfs lkowner buffer init failed");
233933
-        goto out;
233933
-    }
233933
+    mem_pool_thread_destructor();
233933
+}
233933
 
233933
-    ret = glusterfs_leaseid_buf_init();
233933
-    if (ret) {
233933
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LEASEID_BUF_INIT_FAILED,
233933
-               "ERROR: glusterfs leaseid buffer init failed");
233933
-        goto out;
233933
-    }
233933
+static void
233933
+gf_globals_init_once()
233933
+{
233933
+    int ret = 0;
233933
 
233933
-    ret = synctask_init();
233933
-    if (ret) {
233933
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCTASK_INIT_FAILED,
233933
-               "ERROR: glusterfs synctask init failed");
233933
-        goto out;
233933
-    }
233933
+    glusterfs_this_init();
233933
 
233933
-    ret = syncopctx_init();
233933
-    if (ret) {
233933
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCOPCTX_INIT_FAILED,
233933
-               "ERROR: glusterfs syncopctx init failed");
233933
-        goto out;
233933
-    }
233933
-out:
233933
+    /* This is needed only to cleanup the potential allocation of
233933
+     * thread_syncopctx.groups. */
233933
+    ret = pthread_key_create(&free_key, glusterfs_cleanup);
233933
+    if (ret != 0) {
233933
+        gf_msg("", GF_LOG_ERROR, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
233933
+               "failed to create the pthread key");
233933
 
233933
-    if (ret) {
233933
         gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
233933
                "Exiting as global initialization failed");
233933
+
233933
         exit(ret);
233933
     }
233933
 }
233933
diff --git a/libglusterfs/src/glusterfs/globals.h b/libglusterfs/src/glusterfs/globals.h
233933
index e45db14..55476f6 100644
233933
--- a/libglusterfs/src/glusterfs/globals.h
233933
+++ b/libglusterfs/src/glusterfs/globals.h
233933
@@ -147,7 +147,7 @@ xlator_t **
233933
 __glusterfs_this_location(void);
233933
 xlator_t *
233933
 glusterfs_this_get(void);
233933
-int
233933
+void
233933
 glusterfs_this_set(xlator_t *);
233933
 
233933
 extern xlator_t global_xlator;
233933
@@ -156,13 +156,11 @@ extern struct volume_options global_xl_options[];
233933
 /* syncopctx */
233933
 void *
233933
 syncopctx_getctx(void);
233933
-int
233933
-syncopctx_setctx(void *ctx);
233933
 
233933
 /* task */
233933
 void *
233933
 synctask_get(void);
233933
-int
233933
+void
233933
 synctask_set(void *);
233933
 
233933
 /* uuid_buf */
233933
diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h
233933
index 0250b59..c5a486b 100644
233933
--- a/libglusterfs/src/glusterfs/mem-pool.h
233933
+++ b/libglusterfs/src/glusterfs/mem-pool.h
233933
@@ -279,9 +279,7 @@ struct mem_pool_shared {
233933
 };
233933
 
233933
 void
233933
-mem_pools_init_early(void); /* basic initialization of memory pools */
233933
-void
233933
-mem_pools_init_late(void); /* start the pool_sweeper thread */
233933
+mem_pools_init(void); /* start the pool_sweeper thread */
233933
 void
233933
 mem_pools_fini(void); /* cleanup memory pools */
233933
 
233933
@@ -306,6 +304,9 @@ void
233933
 mem_pool_destroy(struct mem_pool *pool);
233933
 
233933
 void
233933
+mem_pool_thread_destructor(void);
233933
+
233933
+void
233933
 gf_mem_acct_enable_set(void *ctx);
233933
 
233933
 #endif /* _MEM_POOL_H */
233933
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
233933
index 7a2edef..86215d2 100644
233933
--- a/libglusterfs/src/libglusterfs.sym
233933
+++ b/libglusterfs/src/libglusterfs.sym
233933
@@ -872,8 +872,7 @@ mem_get0
233933
 mem_pool_destroy
233933
 mem_pool_new_fn
233933
 mem_pools_fini
233933
-mem_pools_init_early
233933
-mem_pools_init_late
233933
+mem_pools_init
233933
 mem_put
233933
 mkdir_p
233933
 next_token
233933
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
233933
index 9b4ea52..ab78804 100644
233933
--- a/libglusterfs/src/mem-pool.c
233933
+++ b/libglusterfs/src/mem-pool.c
233933
@@ -353,7 +353,6 @@ free:
233933
     FREE(ptr);
233933
 }
233933
 
233933
-static pthread_key_t pool_key;
233933
 static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;
233933
 static struct list_head pool_threads;
233933
 static pthread_mutex_t pool_free_lock = PTHREAD_MUTEX_INITIALIZER;
233933
@@ -361,6 +360,8 @@ static struct list_head pool_free_threads;
233933
 static struct mem_pool_shared pools[NPOOLS];
233933
 static size_t pool_list_size;
233933
 
233933
+static __thread per_thread_pool_list_t *thread_pool_list = NULL;
233933
+
233933
 #if !defined(GF_DISABLE_MEMPOOL)
233933
 #define N_COLD_LISTS 1024
233933
 #define POOL_SWEEP_SECS 30
233933
@@ -373,7 +374,6 @@ typedef struct {
233933
 
233933
 enum init_state {
233933
     GF_MEMPOOL_INIT_NONE = 0,
233933
-    GF_MEMPOOL_INIT_PREINIT,
233933
     GF_MEMPOOL_INIT_EARLY,
233933
     GF_MEMPOOL_INIT_LATE,
233933
     GF_MEMPOOL_INIT_DESTROY
233933
@@ -486,9 +486,9 @@ pool_sweeper(void *arg)
233933
 }
233933
 
233933
 void
233933
-pool_destructor(void *arg)
233933
+mem_pool_thread_destructor(void)
233933
 {
233933
-    per_thread_pool_list_t *pool_list = arg;
233933
+    per_thread_pool_list_t *pool_list = thread_pool_list;
233933
 
233933
     /* The pool-sweeper thread will take it from here.
233933
      *
233933
@@ -499,7 +499,10 @@ pool_destructor(void *arg)
233933
      * This change can modify what mem_put() does, but both possibilities are
233933
      * fine until the sweeper thread kicks in. The real synchronization must be
233933
      * between mem_put() and the sweeper thread. */
233933
-    pool_list->poison = 1;
233933
+    if (pool_list != NULL) {
233933
+        pool_list->poison = 1;
233933
+        thread_pool_list = NULL;
233933
+    }
233933
 }
233933
 
233933
 static __attribute__((constructor)) void
233933
@@ -522,46 +525,14 @@ mem_pools_preinit(void)
233933
     pool_list_size = sizeof(per_thread_pool_list_t) +
233933
                      sizeof(per_thread_pool_t) * (NPOOLS - 1);
233933
 
233933
-    init_done = GF_MEMPOOL_INIT_PREINIT;
233933
+    init_done = GF_MEMPOOL_INIT_EARLY;
233933
 }
233933
 
233933
-/* Use mem_pools_init_early() function for basic initialization. There will be
233933
- * no cleanup done by the pool_sweeper thread until mem_pools_init_late() has
233933
- * been called. Calling mem_get() will be possible after this function has
233933
- * setup the basic structures. */
233933
+/* Call mem_pools_init() once threading has been configured completely. This
233933
+ * prevent the pool_sweeper thread from getting killed once the main() thread
233933
+ * exits during deamonizing. */
233933
 void
233933
-mem_pools_init_early(void)
233933
-{
233933
-    pthread_mutex_lock(&init_mutex);
233933
-    /* Use a pthread_key destructor to clean up when a thread exits.
233933
-     *
233933
-     * We won't increase init_count here, that is only done when the
233933
-     * pool_sweeper thread is started too.
233933
-     */
233933
-    if (init_done == GF_MEMPOOL_INIT_PREINIT ||
233933
-        init_done == GF_MEMPOOL_INIT_DESTROY) {
233933
-        /* key has not been created yet */
233933
-        if (pthread_key_create(&pool_key, pool_destructor) != 0) {
233933
-            gf_log("mem-pool", GF_LOG_CRITICAL,
233933
-                   "failed to initialize mem-pool key");
233933
-        }
233933
-
233933
-        init_done = GF_MEMPOOL_INIT_EARLY;
233933
-    } else {
233933
-        gf_log("mem-pool", GF_LOG_CRITICAL,
233933
-               "incorrect order of mem-pool initialization "
233933
-               "(init_done=%d)",
233933
-               init_done);
233933
-    }
233933
-
233933
-    pthread_mutex_unlock(&init_mutex);
233933
-}
233933
-
233933
-/* Call mem_pools_init_late() once threading has been configured completely.
233933
- * This prevent the pool_sweeper thread from getting killed once the main()
233933
- * thread exits during deamonizing. */
233933
-void
233933
-mem_pools_init_late(void)
233933
+mem_pools_init(void)
233933
 {
233933
     pthread_mutex_lock(&init_mutex);
233933
     if ((init_count++) == 0) {
233933
@@ -580,13 +551,12 @@ mem_pools_fini(void)
233933
     switch (init_count) {
233933
         case 0:
233933
             /*
233933
-             * If init_count is already zero (as e.g. if somebody called
233933
-             * this before mem_pools_init_late) then the sweeper was
233933
-             * probably never even started so we don't need to stop it.
233933
-             * Even if there's some crazy circumstance where there is a
233933
-             * sweeper but init_count is still zero, that just means we'll
233933
-             * leave it running.  Not perfect, but far better than any
233933
-             * known alternative.
233933
+             * If init_count is already zero (as e.g. if somebody called this
233933
+             * before mem_pools_init) then the sweeper was probably never even
233933
+             * started so we don't need to stop it. Even if there's some crazy
233933
+             * circumstance where there is a sweeper but init_count is still
233933
+             * zero, that just means we'll leave it running. Not perfect, but
233933
+             * far better than any known alternative.
233933
              */
233933
             break;
233933
         case 1: {
233933
@@ -594,20 +564,17 @@ mem_pools_fini(void)
233933
             per_thread_pool_list_t *next_pl;
233933
             unsigned int i;
233933
 
233933
-            /* if only mem_pools_init_early() was called, sweeper_tid will
233933
-             * be invalid and the functions will error out. That is not
233933
-             * critical. In all other cases, the sweeper_tid will be valid
233933
-             * and the thread gets stopped. */
233933
+            /* if mem_pools_init() was not called, sweeper_tid will be invalid
233933
+             * and the functions will error out. That is not critical. In all
233933
+             * other cases, the sweeper_tid will be valid and the thread gets
233933
+             * stopped. */
233933
             (void)pthread_cancel(sweeper_tid);
233933
             (void)pthread_join(sweeper_tid, NULL);
233933
 
233933
-            /* Need to clean the pool_key to prevent further usage of the
233933
-             * per_thread_pool_list_t structure that is stored for each
233933
-             * thread.
233933
-             * This also prevents calling pool_destructor() when a thread
233933
-             * exits, so there is no chance on a use-after-free of the
233933
-             * per_thread_pool_list_t structure. */
233933
-            (void)pthread_key_delete(pool_key);
233933
+            /* At this point all threads should have already terminated, so
233933
+             * it should be safe to destroy all pending per_thread_pool_list_t
233933
+             * structures that are stored for each thread. */
233933
+            mem_pool_thread_destructor();
233933
 
233933
             /* free all objects from all pools */
233933
             list_for_each_entry_safe(pool_list, next_pl, &pool_threads,
233933
@@ -642,11 +609,7 @@ mem_pools_fini(void)
233933
 
233933
 #else
233933
 void
233933
-mem_pools_init_early(void)
233933
-{
233933
-}
233933
-void
233933
-mem_pools_init_late(void)
233933
+mem_pools_init(void)
233933
 {
233933
 }
233933
 void
233933
@@ -734,7 +697,7 @@ mem_get_pool_list(void)
233933
     per_thread_pool_list_t *pool_list;
233933
     unsigned int i;
233933
 
233933
-    pool_list = pthread_getspecific(pool_key);
233933
+    pool_list = thread_pool_list;
233933
     if (pool_list) {
233933
         return pool_list;
233933
     }
233933
@@ -767,7 +730,8 @@ mem_get_pool_list(void)
233933
     list_add(&pool_list->thr_list, &pool_threads);
233933
     (void)pthread_mutex_unlock(&pool_lock);
233933
 
233933
-    (void)pthread_setspecific(pool_key, pool_list);
233933
+    thread_pool_list = pool_list;
233933
+
233933
     return pool_list;
233933
 }
233933
 
233933
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
233933
index c05939a..2eb7b49 100644
233933
--- a/libglusterfs/src/syncop.c
233933
+++ b/libglusterfs/src/syncop.c
233933
@@ -26,28 +26,10 @@ syncopctx_setfsuid(void *uid)
233933
 
233933
     opctx = syncopctx_getctx();
233933
 
233933
-    /* alloc for this thread the first time */
233933
-    if (!opctx) {
233933
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
233933
-        if (!opctx) {
233933
-            ret = -1;
233933
-            goto out;
233933
-        }
233933
-
233933
-        ret = syncopctx_setctx(opctx);
233933
-        if (ret != 0) {
233933
-            GF_FREE(opctx);
233933
-            opctx = NULL;
233933
-            goto out;
233933
-        }
233933
-    }
233933
+    opctx->uid = *(uid_t *)uid;
233933
+    opctx->valid |= SYNCOPCTX_UID;
233933
 
233933
 out:
233933
-    if (opctx && uid) {
233933
-        opctx->uid = *(uid_t *)uid;
233933
-        opctx->valid |= SYNCOPCTX_UID;
233933
-    }
233933
-
233933
     return ret;
233933
 }
233933
 
233933
@@ -66,28 +48,10 @@ syncopctx_setfsgid(void *gid)
233933
 
233933
     opctx = syncopctx_getctx();
233933
 
233933
-    /* alloc for this thread the first time */
233933
-    if (!opctx) {
233933
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
233933
-        if (!opctx) {
233933
-            ret = -1;
233933
-            goto out;
233933
-        }
233933
-
233933
-        ret = syncopctx_setctx(opctx);
233933
-        if (ret != 0) {
233933
-            GF_FREE(opctx);
233933
-            opctx = NULL;
233933
-            goto out;
233933
-        }
233933
-    }
233933
+    opctx->gid = *(gid_t *)gid;
233933
+    opctx->valid |= SYNCOPCTX_GID;
233933
 
233933
 out:
233933
-    if (opctx && gid) {
233933
-        opctx->gid = *(gid_t *)gid;
233933
-        opctx->valid |= SYNCOPCTX_GID;
233933
-    }
233933
-
233933
     return ret;
233933
 }
233933
 
233933
@@ -107,43 +71,20 @@ syncopctx_setfsgroups(int count, const void *groups)
233933
 
233933
     opctx = syncopctx_getctx();
233933
 
233933
-    /* alloc for this thread the first time */
233933
-    if (!opctx) {
233933
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
233933
-        if (!opctx) {
233933
-            ret = -1;
233933
-            goto out;
233933
-        }
233933
-
233933
-        ret = syncopctx_setctx(opctx);
233933
-        if (ret != 0) {
233933
-            GF_FREE(opctx);
233933
-            opctx = NULL;
233933
-            goto out;
233933
-        }
233933
-    }
233933
-
233933
     /* resize internal groups as required */
233933
     if (count && opctx->grpsize < count) {
233933
         if (opctx->groups) {
233933
-            tmpgroups = GF_REALLOC(opctx->groups, (sizeof(gid_t) * count));
233933
-            /* NOTE: Not really required to zero the reallocation,
233933
-             * as ngrps controls the validity of data,
233933
-             * making a note irrespective */
233933
-            if (tmpgroups == NULL) {
233933
-                opctx->grpsize = 0;
233933
-                GF_FREE(opctx->groups);
233933
-                opctx->groups = NULL;
233933
-                ret = -1;
233933
-                goto out;
233933
-            }
233933
-        } else {
233933
-            tmpgroups = GF_CALLOC(count, sizeof(gid_t), gf_common_mt_syncopctx);
233933
-            if (tmpgroups == NULL) {
233933
-                opctx->grpsize = 0;
233933
-                ret = -1;
233933
-                goto out;
233933
-            }
233933
+            /* Group list will be updated later, so no need to keep current
233933
+             * data and waste time copying it. It's better to free the current
233933
+             * allocation and then allocate a fresh new memory block. */
233933
+            GF_FREE(opctx->groups);
233933
+            opctx->groups = NULL;
233933
+            opctx->grpsize = 0;
233933
+        }
233933
+        tmpgroups = GF_MALLOC(count * sizeof(gid_t), gf_common_mt_syncopctx);
233933
+        if (tmpgroups == NULL) {
233933
+            ret = -1;
233933
+            goto out;
233933
         }
233933
 
233933
         opctx->groups = tmpgroups;
233933
@@ -177,28 +118,10 @@ syncopctx_setfspid(void *pid)
233933
 
233933
     opctx = syncopctx_getctx();
233933
 
233933
-    /* alloc for this thread the first time */
233933
-    if (!opctx) {
233933
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
233933
-        if (!opctx) {
233933
-            ret = -1;
233933
-            goto out;
233933
-        }
233933
-
233933
-        ret = syncopctx_setctx(opctx);
233933
-        if (ret != 0) {
233933
-            GF_FREE(opctx);
233933
-            opctx = NULL;
233933
-            goto out;
233933
-        }
233933
-    }
233933
+    opctx->pid = *(pid_t *)pid;
233933
+    opctx->valid |= SYNCOPCTX_PID;
233933
 
233933
 out:
233933
-    if (opctx && pid) {
233933
-        opctx->pid = *(pid_t *)pid;
233933
-        opctx->valid |= SYNCOPCTX_PID;
233933
-    }
233933
-
233933
     return ret;
233933
 }
233933
 
233933
@@ -217,28 +140,10 @@ syncopctx_setfslkowner(gf_lkowner_t *lk_owner)
233933
 
233933
     opctx = syncopctx_getctx();
233933
 
233933
-    /* alloc for this thread the first time */
233933
-    if (!opctx) {
233933
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
233933
-        if (!opctx) {
233933
-            ret = -1;
233933
-            goto out;
233933
-        }
233933
-
233933
-        ret = syncopctx_setctx(opctx);
233933
-        if (ret != 0) {
233933
-            GF_FREE(opctx);
233933
-            opctx = NULL;
233933
-            goto out;
233933
-        }
233933
-    }
233933
+    opctx->lk_owner = *lk_owner;
233933
+    opctx->valid |= SYNCOPCTX_LKOWNER;
233933
 
233933
 out:
233933
-    if (opctx && lk_owner) {
233933
-        opctx->lk_owner = *lk_owner;
233933
-        opctx->valid |= SYNCOPCTX_LKOWNER;
233933
-    }
233933
-
233933
     return ret;
233933
 }
233933
 
233933
diff --git a/xlators/features/changelog/lib/src/gf-changelog-helpers.c b/xlators/features/changelog/lib/src/gf-changelog-helpers.c
233933
index 03dac5e..e5a9db4 100644
233933
--- a/xlators/features/changelog/lib/src/gf-changelog-helpers.c
233933
+++ b/xlators/features/changelog/lib/src/gf-changelog-helpers.c
233933
@@ -64,20 +64,7 @@ gf_rfc3986_encode_space_newline(unsigned char *s, char *enc, char *estr)
233933
  *       made a part of libglusterfs.
233933
  */
233933
 
233933
-static pthread_key_t rl_key;
233933
-static pthread_once_t rl_once = PTHREAD_ONCE_INIT;
233933
-
233933
-static void
233933
-readline_destructor(void *ptr)
233933
-{
233933
-    GF_FREE(ptr);
233933
-}
233933
-
233933
-static void
233933
-readline_once(void)
233933
-{
233933
-    pthread_key_create(&rl_key, readline_destructor);
233933
-}
233933
+static __thread read_line_t thread_tsd = {};
233933
 
233933
 static ssize_t
233933
 my_read(read_line_t *tsd, int fd, char *ptr)
233933
@@ -97,27 +84,6 @@ my_read(read_line_t *tsd, int fd, char *ptr)
233933
     return 1;
233933
 }
233933
 
233933
-static int
233933
-gf_readline_init_once(read_line_t **tsd)
233933
-{
233933
-    if (pthread_once(&rl_once, readline_once) != 0)
233933
-        return -1;
233933
-
233933
-    *tsd = pthread_getspecific(rl_key);
233933
-    if (*tsd)
233933
-        goto out;
233933
-
233933
-    *tsd = GF_CALLOC(1, sizeof(**tsd), gf_changelog_mt_libgfchangelog_rl_t);
233933
-    if (!*tsd)
233933
-        return -1;
233933
-
233933
-    if (pthread_setspecific(rl_key, *tsd) != 0)
233933
-        return -1;
233933
-
233933
-out:
233933
-    return 0;
233933
-}
233933
-
233933
 ssize_t
233933
 gf_readline(int fd, void *vptr, size_t maxlen)
233933
 {
233933
@@ -125,10 +91,7 @@ gf_readline(int fd, void *vptr, size_t maxlen)
233933
     size_t rc = 0;
233933
     char c = ' ';
233933
     char *ptr = NULL;
233933
-    read_line_t *tsd = NULL;
233933
-
233933
-    if (gf_readline_init_once(&tsd))
233933
-        return -1;
233933
+    read_line_t *tsd = &thread_tsd;
233933
 
233933
     ptr = vptr;
233933
     for (n = 1; n < maxlen; n++) {
233933
@@ -151,10 +114,7 @@ off_t
233933
 gf_lseek(int fd, off_t offset, int whence)
233933
 {
233933
     off_t off = 0;
233933
-    read_line_t *tsd = NULL;
233933
-
233933
-    if (gf_readline_init_once(&tsd))
233933
-        return -1;
233933
+    read_line_t *tsd = &thread_tsd;
233933
 
233933
     off = sys_lseek(fd, offset, whence);
233933
     if (off == -1)
233933
@@ -169,10 +129,7 @@ gf_lseek(int fd, off_t offset, int whence)
233933
 int
233933
 gf_ftruncate(int fd, off_t length)
233933
 {
233933
-    read_line_t *tsd = NULL;
233933
-
233933
-    if (gf_readline_init_once(&tsd))
233933
-        return -1;
233933
+    read_line_t *tsd = &thread_tsd;
233933
 
233933
     if (sys_ftruncate(fd, 0))
233933
         return -1;
233933
diff --git a/xlators/features/changelog/lib/src/gf-changelog.c b/xlators/features/changelog/lib/src/gf-changelog.c
233933
index 7ed9e55..d6acb37 100644
233933
--- a/xlators/features/changelog/lib/src/gf-changelog.c
233933
+++ b/xlators/features/changelog/lib/src/gf-changelog.c
233933
@@ -237,9 +237,8 @@ gf_changelog_init_master()
233933
 {
233933
     int ret = 0;
233933
 
233933
-    mem_pools_init_early();
233933
     ret = gf_changelog_init_context();
233933
-    mem_pools_init_late();
233933
+    mem_pools_init();
233933
 
233933
     return ret;
233933
 }
233933
diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c
233933
index d5e4169..0688779eb 100644
233933
--- a/xlators/nfs/server/src/mount3udp_svc.c
233933
+++ b/xlators/nfs/server/src/mount3udp_svc.c
233933
@@ -216,11 +216,7 @@ mount3udp_thread(void *argv)
233933
 
233933
     GF_ASSERT(nfsx);
233933
 
233933
-    if (glusterfs_this_set(nfsx)) {
233933
-        gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_XLATOR_SET_FAIL,
233933
-               "Failed to set xlator, nfs.mount-udp will not work");
233933
-        return NULL;
233933
-    }
233933
+    glusterfs_this_set(nfsx);
233933
 
233933
     transp = svcudp_create(RPC_ANYSOCK);
233933
     if (transp == NULL) {
233933
-- 
233933
1.8.3.1
233933