Blame SPECS/0139-ec-shd-Cleanup-self-heal-daemon-resources-during-ec-.patch

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