diff options
author | Pranith Kumar K <pranithk@gluster.com> | 2012-07-25 15:08:46 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2012-07-25 08:16:27 -0700 |
commit | 8180d474a9f4aad495168102399b0465ad8efb06 (patch) | |
tree | 10fd223134847c6dc3c06a9938b5932fad0c0a5d | |
parent | 9d3dff4cf2b4f29f514b9eae00330dfe3e144fff (diff) |
features/index: Fix race in this->private initialization
RCA:
In index_worker function at the time of assigning priv from
this->private, this->private may not be set in init() function
of index xlator.
Fix:
Set this->private before creating the thread.
Additional Changes:
Added code to handle error path completely.
Test cases:
Attached the process to gdb and simulated failures.
executed fini in gdb using call fini(this) after init
was successful.
Change-Id: I1874a30d009a35352173b827574cf83daf431453
BUG: 843071
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Reviewed-on: http://review.gluster.com/3728
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r-- | xlators/features/index/src/index.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index 508eb91a..0f00f7d9 100644 --- a/xlators/features/index/src/index.c +++ b/xlators/features/index/src/index.c @@ -1029,6 +1029,9 @@ init (xlator_t *this) int ret = -1; index_priv_t *priv = NULL; pthread_t thread; + gf_boolean_t mutex_inited = _gf_false; + gf_boolean_t cond_inited = _gf_false; + gf_boolean_t attr_inited = _gf_false; if (!this->children || this->children->next) { gf_log (this->name, GF_LOG_ERROR, @@ -1051,14 +1054,22 @@ init (xlator_t *this) "pthread_cond_init failed (%d)", ret); goto out; } + cond_inited = _gf_true; if ((ret = pthread_mutex_init(&priv->mutex, NULL)) != 0) { gf_log (this->name, GF_LOG_ERROR, "pthread_mutex_init failed (%d)", ret); goto out; } + mutex_inited = _gf_true; + + if ((ret = pthread_attr_init (&priv->w_attr)) != 0) { + gf_log (this->name, GF_LOG_ERROR, + "pthread_attr_init failed (%d)", ret); + goto out; + } + attr_inited = _gf_true; - pthread_attr_init (&priv->w_attr); ret = pthread_attr_setstacksize (&priv->w_attr, INDEX_THREAD_STACK_SIZE); if (ret == EINVAL) { @@ -1070,18 +1081,26 @@ init (xlator_t *this) uuid_generate (priv->xattrop_vgfid); INIT_LIST_HEAD (&priv->callstubs); + this->private = priv; ret = pthread_create (&thread, &priv->w_attr, index_worker, this); if (ret) { gf_log (this->name, GF_LOG_WARNING, "Failed to create " "worker thread, aborting"); goto out; } - this->private = priv; ret = 0; out: - if (!this->private && priv) - GF_FREE (priv); - + if (ret) { + if (cond_inited) + pthread_cond_destroy (&priv->cond); + if (mutex_inited) + pthread_mutex_destroy (&priv->mutex); + if (attr_inited) + pthread_attr_destroy (&priv->w_attr); + if (priv) + GF_FREE (priv); + this->private = NULL; + } return ret; } @@ -1095,6 +1114,9 @@ fini (xlator_t *this) goto out; this->private = NULL; LOCK_DESTROY (&priv->lock); + pthread_cond_destroy (&priv->cond); + pthread_mutex_destroy (&priv->mutex); + pthread_attr_destroy (&priv->w_attr); GF_FREE (priv); out: return; |