256ebe
From edc238e40060773f5f5fd59fcdad8ae27d65749f Mon Sep 17 00:00:00 2001
256ebe
From: Mohammed Rafi KC <rkavunga@redhat.com>
256ebe
Date: Mon, 29 Apr 2019 13:22:32 +0530
256ebe
Subject: [PATCH 139/141] ec/shd: Cleanup self heal daemon resources during ec
256ebe
 fini
256ebe
256ebe
We were not properly cleaning self-heal daemon resources
256ebe
during ec fini. With shd multiplexing, it is absolutely
256ebe
necessary to cleanup all the resources during ec fini.
256ebe
256ebe
Back port of
256ebe
 upstream patch: https://review.gluster.org/#/c/glusterfs/+/22644/
256ebe
 >Change-Id: Iae4f1bce7d8c2e1da51ac568700a51088f3cc7f2
256ebe
 >fixes: bz#1703948
256ebe
 >Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
256ebe
256ebe
BUG: 1703434
256ebe
Change-Id: I98ae03178d3176772c62e34baa08a5c35b8f7217
256ebe
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
256ebe
Reviewed-on: https://code.engineering.redhat.com/gerrit/169994
256ebe
Tested-by: RHGS Build Bot <nigelb@redhat.com>
256ebe
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
256ebe
---
256ebe
 libglusterfs/src/syncop-utils.c          |  2 +
256ebe
 xlators/cluster/afr/src/afr-self-heald.c |  5 +++
256ebe
 xlators/cluster/ec/src/ec-heald.c        | 77 +++++++++++++++++++++++++++-----
256ebe
 xlators/cluster/ec/src/ec-heald.h        |  3 ++
256ebe
 xlators/cluster/ec/src/ec-messages.h     |  3 +-
256ebe
 xlators/cluster/ec/src/ec.c              | 47 +++++++++++++++++++
256ebe
 6 files changed, 124 insertions(+), 13 deletions(-)
256ebe
256ebe
diff --git a/libglusterfs/src/syncop-utils.c b/libglusterfs/src/syncop-utils.c
256ebe
index b842142..4167db4 100644
256ebe
--- a/libglusterfs/src/syncop-utils.c
256ebe
+++ b/libglusterfs/src/syncop-utils.c
256ebe
@@ -354,6 +354,8 @@ syncop_mt_dir_scan(call_frame_t *frame, xlator_t *subvol, loc_t *loc, int pid,
256ebe
 
256ebe
     if (frame) {
256ebe
         this = frame->this;
256ebe
+    } else {
256ebe
+        this = THIS;
256ebe
     }
256ebe
 
256ebe
     /*For this functionality to be implemented in general, we need
256ebe
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
256ebe
index 8bc4720..522fe5d 100644
256ebe
--- a/xlators/cluster/afr/src/afr-self-heald.c
256ebe
+++ b/xlators/cluster/afr/src/afr-self-heald.c
256ebe
@@ -524,6 +524,11 @@ afr_shd_full_heal(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
256ebe
     afr_private_t *priv = NULL;
256ebe
 
256ebe
     priv = this->private;
256ebe
+
256ebe
+    if (this->cleanup_starting) {
256ebe
+        return -ENOTCONN;
256ebe
+    }
256ebe
+
256ebe
     if (!priv->shd.enabled)
256ebe
         return -EBUSY;
256ebe
 
256ebe
diff --git a/xlators/cluster/ec/src/ec-heald.c b/xlators/cluster/ec/src/ec-heald.c
256ebe
index cba111a..edf5e11 100644
256ebe
--- a/xlators/cluster/ec/src/ec-heald.c
256ebe
+++ b/xlators/cluster/ec/src/ec-heald.c
256ebe
@@ -71,6 +71,11 @@ disabled_loop:
256ebe
             break;
256ebe
     }
256ebe
 
256ebe
+    if (ec->shutdown) {
256ebe
+        healer->running = _gf_false;
256ebe
+        return -1;
256ebe
+    }
256ebe
+
256ebe
     ret = healer->rerun;
256ebe
     healer->rerun = 0;
256ebe
 
256ebe
@@ -241,9 +246,11 @@ ec_shd_index_sweep(struct subvol_healer *healer)
256ebe
         goto out;
256ebe
     }
256ebe
 
256ebe
+    _mask_cancellation();
256ebe
     ret = syncop_mt_dir_scan(NULL, subvol, &loc, GF_CLIENT_PID_SELF_HEALD,
256ebe
                              healer, ec_shd_index_heal, xdata,
256ebe
                              ec->shd.max_threads, ec->shd.wait_qlength);
256ebe
+    _unmask_cancellation();
256ebe
 out:
256ebe
     if (xdata)
256ebe
         dict_unref(xdata);
256ebe
@@ -263,6 +270,11 @@ ec_shd_full_heal(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
256ebe
     int ret = 0;
256ebe
 
256ebe
     ec = this->private;
256ebe
+
256ebe
+    if (this->cleanup_starting) {
256ebe
+        return -ENOTCONN;
256ebe
+    }
256ebe
+
256ebe
     if (ec->xl_up_count <= ec->fragments) {
256ebe
         return -ENOTCONN;
256ebe
     }
256ebe
@@ -305,11 +317,15 @@ ec_shd_full_sweep(struct subvol_healer *healer, inode_t *inode)
256ebe
 {
256ebe
     ec_t *ec = NULL;
256ebe
     loc_t loc = {0};
256ebe
+    int ret = -1;
256ebe
 
256ebe
     ec = healer->this->private;
256ebe
     loc.inode = inode;
256ebe
-    return syncop_ftw(ec->xl_list[healer->subvol], &loc,
256ebe
-                      GF_CLIENT_PID_SELF_HEALD, healer, ec_shd_full_heal);
256ebe
+    _mask_cancellation();
256ebe
+    ret = syncop_ftw(ec->xl_list[healer->subvol], &loc,
256ebe
+                     GF_CLIENT_PID_SELF_HEALD, healer, ec_shd_full_heal);
256ebe
+    _unmask_cancellation();
256ebe
+    return ret;
256ebe
 }
256ebe
 
256ebe
 void *
256ebe
@@ -317,13 +333,16 @@ ec_shd_index_healer(void *data)
256ebe
 {
256ebe
     struct subvol_healer *healer = NULL;
256ebe
     xlator_t *this = NULL;
256ebe
+    int run = 0;
256ebe
 
256ebe
     healer = data;
256ebe
     THIS = this = healer->this;
256ebe
     ec_t *ec = this->private;
256ebe
 
256ebe
     for (;;) {
256ebe
-        ec_shd_healer_wait(healer);
256ebe
+        run = ec_shd_healer_wait(healer);
256ebe
+        if (run == -1)
256ebe
+            break;
256ebe
 
256ebe
         if (ec->xl_up_count > ec->fragments) {
256ebe
             gf_msg_debug(this->name, 0, "starting index sweep on subvol %s",
256ebe
@@ -352,16 +371,12 @@ ec_shd_full_healer(void *data)
256ebe
 
256ebe
     rootloc.inode = this->itable->root;
256ebe
     for (;;) {
256ebe
-        pthread_mutex_lock(&healer->mutex);
256ebe
-        {
256ebe
-            run = __ec_shd_healer_wait(healer);
256ebe
-            if (!run)
256ebe
-                healer->running = _gf_false;
256ebe
-        }
256ebe
-        pthread_mutex_unlock(&healer->mutex);
256ebe
-
256ebe
-        if (!run)
256ebe
+        run = ec_shd_healer_wait(healer);
256ebe
+        if (run < 0) {
256ebe
             break;
256ebe
+        } else if (run == 0) {
256ebe
+            continue;
256ebe
+        }
256ebe
 
256ebe
         if (ec->xl_up_count > ec->fragments) {
256ebe
             gf_msg(this->name, GF_LOG_INFO, 0, EC_MSG_FULL_SWEEP_START,
256ebe
@@ -562,3 +577,41 @@ out:
256ebe
     dict_del(output, this->name);
256ebe
     return ret;
256ebe
 }
256ebe
+
256ebe
+void
256ebe
+ec_destroy_healer_object(xlator_t *this, struct subvol_healer *healer)
256ebe
+{
256ebe
+    if (!healer)
256ebe
+        return;
256ebe
+
256ebe
+    pthread_cond_destroy(&healer->cond);
256ebe
+    pthread_mutex_destroy(&healer->mutex);
256ebe
+}
256ebe
+
256ebe
+void
256ebe
+ec_selfheal_daemon_fini(xlator_t *this)
256ebe
+{
256ebe
+    struct subvol_healer *healer = NULL;
256ebe
+    ec_self_heald_t *shd = NULL;
256ebe
+    ec_t *priv = NULL;
256ebe
+    int i = 0;
256ebe
+
256ebe
+    priv = this->private;
256ebe
+    if (!priv)
256ebe
+        return;
256ebe
+
256ebe
+    shd = &priv->shd;
256ebe
+    if (!shd->iamshd)
256ebe
+        return;
256ebe
+
256ebe
+    for (i = 0; i < priv->nodes; i++) {
256ebe
+        healer = &shd->index_healers[i];
256ebe
+        ec_destroy_healer_object(this, healer);
256ebe
+
256ebe
+        healer = &shd->full_healers[i];
256ebe
+        ec_destroy_healer_object(this, healer);
256ebe
+    }
256ebe
+
256ebe
+    GF_FREE(shd->index_healers);
256ebe
+    GF_FREE(shd->full_healers);
256ebe
+}
256ebe
diff --git a/xlators/cluster/ec/src/ec-heald.h b/xlators/cluster/ec/src/ec-heald.h
256ebe
index 2eda2a7..8184cf4 100644
256ebe
--- a/xlators/cluster/ec/src/ec-heald.h
256ebe
+++ b/xlators/cluster/ec/src/ec-heald.h
256ebe
@@ -24,4 +24,7 @@ ec_selfheal_daemon_init(xlator_t *this);
256ebe
 void
256ebe
 ec_shd_index_healer_wake(ec_t *ec);
256ebe
 
256ebe
+void
256ebe
+ec_selfheal_daemon_fini(xlator_t *this);
256ebe
+
256ebe
 #endif /* __EC_HEALD_H__ */
256ebe
diff --git a/xlators/cluster/ec/src/ec-messages.h b/xlators/cluster/ec/src/ec-messages.h
256ebe
index 7c28808..ce299bb 100644
256ebe
--- a/xlators/cluster/ec/src/ec-messages.h
256ebe
+++ b/xlators/cluster/ec/src/ec-messages.h
256ebe
@@ -55,6 +55,7 @@ GLFS_MSGID(EC, EC_MSG_INVALID_CONFIG, EC_MSG_HEAL_FAIL,
256ebe
            EC_MSG_CONFIG_XATTR_INVALID, EC_MSG_EXTENSION, EC_MSG_EXTENSION_NONE,
256ebe
            EC_MSG_EXTENSION_UNKNOWN, EC_MSG_EXTENSION_UNSUPPORTED,
256ebe
            EC_MSG_EXTENSION_FAILED, EC_MSG_NO_GF, EC_MSG_MATRIX_FAILED,
256ebe
-           EC_MSG_DYN_CREATE_FAILED, EC_MSG_DYN_CODEGEN_FAILED);
256ebe
+           EC_MSG_DYN_CREATE_FAILED, EC_MSG_DYN_CODEGEN_FAILED,
256ebe
+           EC_MSG_THREAD_CLEANUP_FAILED);
256ebe
 
256ebe
 #endif /* !_EC_MESSAGES_H_ */
256ebe
diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
256ebe
index 3c8013e..264582a 100644
256ebe
--- a/xlators/cluster/ec/src/ec.c
256ebe
+++ b/xlators/cluster/ec/src/ec.c
256ebe
@@ -429,6 +429,51 @@ ec_disable_delays(ec_t *ec)
256ebe
 }
256ebe
 
256ebe
 void
256ebe
+ec_cleanup_healer_object(ec_t *ec)
256ebe
+{
256ebe
+    struct subvol_healer *healer = NULL;
256ebe
+    ec_self_heald_t *shd = NULL;
256ebe
+    void *res = NULL;
256ebe
+    int i = 0;
256ebe
+    gf_boolean_t is_join = _gf_false;
256ebe
+
256ebe
+    shd = &ec->shd;
256ebe
+    if (!shd->iamshd)
256ebe
+        return;
256ebe
+
256ebe
+    for (i = 0; i < ec->nodes; i++) {
256ebe
+        healer = &shd->index_healers[i];
256ebe
+        pthread_mutex_lock(&healer->mutex);
256ebe
+        {
256ebe
+            healer->rerun = 1;
256ebe
+            if (healer->running) {
256ebe
+                pthread_cond_signal(&healer->cond);
256ebe
+                is_join = _gf_true;
256ebe
+            }
256ebe
+        }
256ebe
+        pthread_mutex_unlock(&healer->mutex);
256ebe
+        if (is_join) {
256ebe
+            pthread_join(healer->thread, &res;;
256ebe
+            is_join = _gf_false;
256ebe
+        }
256ebe
+
256ebe
+        healer = &shd->full_healers[i];
256ebe
+        pthread_mutex_lock(&healer->mutex);
256ebe
+        {
256ebe
+            healer->rerun = 1;
256ebe
+            if (healer->running) {
256ebe
+                pthread_cond_signal(&healer->cond);
256ebe
+                is_join = _gf_true;
256ebe
+            }
256ebe
+        }
256ebe
+        pthread_mutex_unlock(&healer->mutex);
256ebe
+        if (is_join) {
256ebe
+            pthread_join(healer->thread, &res;;
256ebe
+            is_join = _gf_false;
256ebe
+        }
256ebe
+    }
256ebe
+}
256ebe
+void
256ebe
 ec_pending_fops_completed(ec_t *ec)
256ebe
 {
256ebe
     if (ec->shutdown) {
256ebe
@@ -544,6 +589,7 @@ ec_notify(xlator_t *this, int32_t event, void *data, void *data2)
256ebe
         /* If there aren't pending fops running after we have waken up
256ebe
          * them, we immediately propagate the notification. */
256ebe
         propagate = ec_disable_delays(ec);
256ebe
+        ec_cleanup_healer_object(ec);
256ebe
         goto unlock;
256ebe
     }
256ebe
 
256ebe
@@ -759,6 +805,7 @@ failed:
256ebe
 void
256ebe
 fini(xlator_t *this)
256ebe
 {
256ebe
+    ec_selfheal_daemon_fini(this);
256ebe
     __ec_destroy_private(this);
256ebe
 }
256ebe
 
256ebe
-- 
256ebe
1.8.3.1
256ebe