From 0b91f5be63813e6494283a8ac7d6e1e4348c9f13 Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Tue, 5 Apr 2011 04:03:43 +0000 Subject: protocol/client: make sure to send only genuine events up to parent that way parent notify logic is fine. also, remove 'xlator_notify()' call in code, instead use 'default_notify()' Signed-off-by: Amar Tumballi Signed-off-by: Vijay Bellur BUG: 2584 (Inode number changes on a directory when one of subvolumes is down in replicate) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2584 --- xlators/protocol/client/src/client-handshake.c | 49 ++++++++++---------------- xlators/protocol/client/src/client.c | 27 +++++++++++--- xlators/protocol/client/src/client.h | 4 +++ 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c index 4577dda5d65..5aabe57e041 100644 --- a/xlators/protocol/client/src/client-handshake.c +++ b/xlators/protocol/client/src/client-handshake.c @@ -345,24 +345,16 @@ unwind: int client_notify_parents_child_up (xlator_t *this) { - xlator_list_t *parent = NULL; - - /* As fuse is not 'parent' of any translator now, triggering its - CHILD_UP event is hacky in case client has only client protocol */ - if (!this->parents && this->ctx && this->ctx->master) { - /* send notify to 'ctx->master' if it exists */ - xlator_notify (this->ctx->master, GF_EVENT_CHILD_UP, - this->graph); - } else { + clnt_conf_t *conf = NULL; + int ret = 0; - parent = this->parents; - while (parent) { - xlator_notify (parent->xlator, GF_EVENT_CHILD_UP, - this); - parent = parent->next; - } - } + conf = this->private; + ret = default_notify (this, GF_EVENT_CHILD_UP, NULL); + if (ret) + gf_log (this->name, GF_LOG_INFO, + "notify of CHILD_UP failed"); + conf->last_sent_event = GF_EVENT_CHILD_UP; return 0; } @@ -757,7 +749,6 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m clnt_conf_t *conf = NULL; xlator_t *this = NULL; dict_t *reply = NULL; - xlator_list_t *parent = NULL; char *process_uuid = NULL; char *remote_error = NULL; char *remote_subvol = NULL; @@ -820,13 +811,11 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m remote_error ? remote_error : strerror (op_errno)); errno = op_errno; if (op_errno == ESTALE) { - parent = this->parents; - while (parent) { - xlator_notify (parent->xlator, - GF_EVENT_VOLFILE_MODIFIED, - this); - parent = parent->next; - } + ret = default_notify (this, GF_EVENT_VOLFILE_MODIFIED, NULL); + if (ret) + gf_log (this->name, GF_LOG_INFO, + "notify of VOLFILE_MODIFIED failed"); + conf->last_sent_event = GF_EVENT_VOLFILE_MODIFIED; } goto out; } @@ -878,13 +867,11 @@ out: * background, for now, don't hang here, * tell the parents that i am all ok.. */ - parent = this->parents; - while (parent) { - xlator_notify (parent->xlator, - GF_EVENT_CHILD_CONNECTING, this); - parent = parent->next; - } - + ret = default_notify (this, GF_EVENT_CHILD_CONNECTING, NULL); + if (ret) + gf_log (this->name, GF_LOG_INFO, + "notify of CHILD_CONNECTING failed"); + conf->last_sent_event = GF_EVENT_CHILD_CONNECTING; conf->connecting= 1; } diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 51c35ef8c70..16ac4d2124b 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -1584,10 +1584,14 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, "handshake msg returned %d", ret); } else { //conf->rpc->connected = 1; - ret = default_notify (this, GF_EVENT_CHILD_UP, NULL); - if (ret) - gf_log (this->name, GF_LOG_DEBUG, - "default notify failed"); + if (conf->last_sent_event != GF_EVENT_CHILD_UP) { + ret = default_notify (this, GF_EVENT_CHILD_UP, + NULL); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, + "default notify failed"); + conf->last_sent_event = GF_EVENT_CHILD_UP; + } } break; } @@ -1599,7 +1603,16 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, if (conf->connected) gf_log (this->name, GF_LOG_NORMAL, "disconnected"); - default_notify (this, GF_EVENT_CHILD_DOWN, NULL); + + /* If the CHILD_DOWN event goes to parent xlator + multiple times, the logic of parent xlator notify + may get screwed up.. (eg. CHILD_MODIFIED event in + replicate), hence make sure events which are passed + to parent are genuine */ + if (conf->last_sent_event != GF_EVENT_CHILD_DOWN) { + default_notify (this, GF_EVENT_CHILD_DOWN, NULL); + conf->last_sent_event = GF_EVENT_CHILD_DOWN; + } } else { if (conf->connected) gf_log (this->name, GF_LOG_DEBUG, @@ -1648,6 +1661,7 @@ notify (xlator_t *this, int32_t event, void *data, ...) "got %d, calling default_notify ()", event); default_notify (this, event, data); + conf->last_sent_event = event; break; } @@ -2008,6 +2022,8 @@ init (xlator_t *this) LOCK_INIT (&conf->rec_lock); + conf->last_sent_event = -1; /* To start with we don't have any events */ + this->private = conf; /* If it returns -1, then its a failure, if it returns +1 we need @@ -2025,6 +2041,7 @@ init (xlator_t *this) goto out; } + ret = client_init_rpc (this); out: if (ret) diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index f3bc0073e0a..dfae8fb2c22 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -59,6 +59,10 @@ typedef struct clnt_conf { connection is established */ gf_lock_t rec_lock; int skip_notify; + + int last_sent_event; /* Flag used to make sure we are + not repeating the same event + which was sent earlier */ } clnt_conf_t; typedef struct _client_fd_ctx { -- cgit