Patchwork [BUG:1643,2/2] dht: change behaviour CHILD_UP/DOWN/CONNECTING event propagation

login
register
Submitter Anand Avati
Date 2010-10-11 13:00:55
Message ID <20101011130055.GA10461@dev.gluster.com>
Download mbox | patch
Permalink /patch/5436/
State Accepted
Headers show

Comments

Anand Avati - 2010-10-11 13:00:55
The first CHILD_UP/DOWN/CONNECTING event to pass dht upwards should be only after
all subvols have reported their status atleast once.

Signed-off-by: Anand V. Avati <avati@blackhole.gluster.com>
---
 xlators/cluster/dht/src/dht-common.c |   85 +++++++++++++++++++++++++++++++++-
 xlators/cluster/dht/src/dht-common.h |    1 +
 2 files changed, 85 insertions(+), 1 deletions(-)
Amar Tumballi - 2010-10-11 14:04:25
Reviewed OK.

On Mon, Oct 11, 2010 at 6:30 PM, Anand V. Avati <avati@gluster.com> wrote:

> The first CHILD_UP/DOWN/CONNECTING event to pass dht upwards should be only
> after
> all subvols have reported their status atleast once.
>
> Signed-off-by: Anand V. Avati <avati@blackhole.gluster.com>
> ---
>  xlators/cluster/dht/src/dht-common.c |   85
> +++++++++++++++++++++++++++++++++-
>  xlators/cluster/dht/src/dht-common.h |    1 +
>  2 files changed, 85 insertions(+), 1 deletions(-)
>
>

Patch

diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 42ab4fc..5e498fd 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -4742,6 +4742,13 @@  dht_init_subvolumes (xlator_t *this, dht_conf_t *conf)
 		return -1;
 	}
 
+	conf->last_event = GF_CALLOC (cnt, sizeof (int),
+                                      gf_dht_mt_char);
+	if (!conf->last_event) {
+		gf_log (this->name, GF_LOG_ERROR,
+			"Out of memory");
+		return -1;
+	}
         return 0;
 }
 
@@ -4754,12 +4761,24 @@  dht_notify (xlator_t *this, int event, void *data, ...)
 	int         i      = -1;
 	dht_conf_t *conf   = NULL;
 	int         ret    = -1;
+        int         propagate = 0;
+
+        int         had_heard_from_all = 0;
+        int         have_heard_from_all = 0;
 
 
 	conf = this->private;
         if (!conf)
                 return ret;
 
+        /* had all subvolumes reported status once till now? */
+        had_heard_from_all = 1;
+        for (i = 0; i < conf->subvolume_cnt; i++) {
+                if (!conf->last_event[i]) {
+                        had_heard_from_all = 0;
+                }
+        }
+
 	switch (event) {
 	case GF_EVENT_CHILD_UP:
 		subvol = data;
@@ -4783,6 +4802,7 @@  dht_notify (xlator_t *this, int event, void *data, ...)
 		LOCK (&conf->subvolume_lock);
 		{
 			conf->subvolume_status[cnt] = 1;
+                        conf->last_event[cnt] = event;
 		}
 		UNLOCK (&conf->subvolume_lock);
 
@@ -4811,13 +4831,76 @@  dht_notify (xlator_t *this, int event, void *data, ...)
 		LOCK (&conf->subvolume_lock);
 		{
 			conf->subvolume_status[cnt] = 0;
+                        conf->last_event[cnt] = event;
+		}
+		UNLOCK (&conf->subvolume_lock);
+
+                break;
+
+	case GF_EVENT_CHILD_CONNECTING:
+		subvol = data;
+
+		for (i = 0; i < conf->subvolume_cnt; i++) {
+			if (subvol == conf->subvolumes[i]) {
+				cnt = i;
+				break;
+			}
+		}
+
+		if (cnt == -1) {
+			gf_log (this->name, GF_LOG_DEBUG,
+				"got GF_EVENT_CHILD_CONNECTING bad subvolume %s",
+				subvol->name);
+			break;
+		}
+
+		LOCK (&conf->subvolume_lock);
+		{
+                        conf->last_event[cnt] = event;
 		}
 		UNLOCK (&conf->subvolume_lock);
 
 		break;
+        default:
+                propagate = 1;
+                break;
 	}
 
-	ret = default_notify (this, event, data);
+
+        /* have all subvolumes reported status once by now? */
+        have_heard_from_all = 1;
+        for (i = 0; i < conf->subvolume_cnt; i++) {
+                if (!conf->last_event[i])
+                        have_heard_from_all = 0;
+        }
+
+        /* if all subvols have reported status, no need to hide anything
+           or wait for anything else. Just propagate blindly */
+        if (have_heard_from_all)
+                propagate = 1;
+
+        if (!had_heard_from_all && have_heard_from_all) {
+                /* This is the first event which completes aggregation
+                   of events from all subvolumes. If at least one subvol
+                   had come up, propagate CHILD_UP, but only this time
+                */
+                event = GF_EVENT_CHILD_DOWN;
+
+                for (i = 0; i < conf->subvolume_cnt; i++) {
+                        if (conf->last_event[i] == GF_EVENT_CHILD_UP) {
+                                event = GF_EVENT_CHILD_UP;
+                                break;
+                        }
+
+                        if (conf->last_event[i] == GF_EVENT_CHILD_CONNECTING) {
+                                event = GF_EVENT_CHILD_CONNECTING;
+                                /* continue to check other events for CHILD_UP */
+                        }
+                }
+        }
+
+        if (propagate)
+                ret = default_notify (this, event, data);
 
 	return ret;
 }
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index 7686156..2a0b3b1 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -144,6 +144,7 @@  struct dht_conf {
         int            subvolume_cnt;
         xlator_t     **subvolumes;
 	char          *subvolume_status;
+        int           *last_event;
 	dht_layout_t **file_layouts;
 	dht_layout_t **dir_layouts;
 	dht_layout_t  *default_dir_layout;