summaryrefslogtreecommitdiffstats
path: root/xlators/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/protocol')
-rw-r--r--xlators/protocol/client/src/client-callback.c52
-rw-r--r--xlators/protocol/client/src/client-handshake.c30
-rw-r--r--xlators/protocol/client/src/client-messages.h1
-rw-r--r--xlators/protocol/client/src/client.c2
-rw-r--r--xlators/protocol/client/src/client.h3
-rw-r--r--xlators/protocol/server/src/server-handshake.c6
-rw-r--r--xlators/protocol/server/src/server.c71
-rw-r--r--xlators/protocol/server/src/server.h2
8 files changed, 155 insertions, 12 deletions
diff --git a/xlators/protocol/client/src/client-callback.c b/xlators/protocol/client/src/client-callback.c
index 16f5441a778..7ee2113762a 100644
--- a/xlators/protocol/client/src/client-callback.c
+++ b/xlators/protocol/client/src/client-callback.c
@@ -81,13 +81,53 @@ out:
return 0;
}
+int
+client_cbk_child_up (struct rpc_clnt *rpc, void *mydata, void *data)
+{
+ clnt_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, rpc, out);
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+ gf_msg_debug (this->name, 0, "Received CHILD_UP");
+ conf->child_up = _gf_true;
+
+ this->notify (this, GF_EVENT_CHILD_UP, NULL);
+out:
+ return 0;
+}
+
+int
+client_cbk_child_down (struct rpc_clnt *rpc, void *mydata, void *data)
+{
+ clnt_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, rpc, out);
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+ gf_msg_debug (this->name, 0, "Received CHILD_DOWN");
+ conf->child_up = _gf_false;
+
+ this->notify (this, GF_EVENT_CHILD_DOWN, NULL);
+out:
+ return 0;
+}
+
rpcclnt_cb_actor_t gluster_cbk_actors[GF_CBK_MAXVALUE] = {
- [GF_CBK_NULL] = {"NULL", GF_CBK_NULL, client_cbk_null },
- [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, client_cbk_fetchspec },
- [GF_CBK_INO_FLUSH] = {"INO_FLUSH", GF_CBK_INO_FLUSH, client_cbk_ino_flush },
- [GF_CBK_CACHE_INVALIDATION] = {"CACHE_INVALIDATION",
- GF_CBK_CACHE_INVALIDATION,
- client_cbk_cache_invalidation },
+ [GF_CBK_NULL] = {"NULL", GF_CBK_NULL, client_cbk_null },
+ [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, client_cbk_fetchspec },
+ [GF_CBK_INO_FLUSH] = {"INO_FLUSH", GF_CBK_INO_FLUSH, client_cbk_ino_flush },
+ [GF_CBK_CACHE_INVALIDATION] = {"CACHE_INVALIDATION", GF_CBK_CACHE_INVALIDATION, client_cbk_cache_invalidation },
+ [GF_CBK_CHILD_UP] = {"CHILD_UP", GF_CBK_CHILD_UP, client_cbk_child_up },
+ [GF_CBK_CHILD_DOWN] = {"CHILD_DOWN", GF_CBK_CHILD_DOWN, client_cbk_child_down },
};
diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c
index 3b170b8d186..5352e549abf 100644
--- a/xlators/protocol/client/src/client-handshake.c
+++ b/xlators/protocol/client/src/client-handshake.c
@@ -129,13 +129,26 @@ client_notify_parents_child_up (xlator_t *this)
clnt_conf_t *conf = NULL;
int ret = 0;
+ GF_VALIDATE_OR_GOTO("client", this, out);
conf = this->private;
- ret = client_notify_dispatch_uniq (this, GF_EVENT_CHILD_UP, NULL);
- if (ret)
- gf_msg (this->name, GF_LOG_INFO, 0,
- PC_MSG_CHILD_UP_NOTIFY_FAILED, "notify of CHILD_UP "
- "failed");
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+
+ if (conf->child_up) {
+ ret = client_notify_dispatch_uniq (this, GF_EVENT_CHILD_UP,
+ NULL);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_INFO, 0,
+ PC_MSG_CHILD_UP_NOTIFY_FAILED,
+ "notify of CHILD_UP failed");
+ goto out;
+ }
+ } else {
+ gf_msg (this->name, GF_LOG_INFO, 0, PC_MSG_CHILD_STATUS,
+ "Defering sending CHILD_UP message as the client "
+ "translators are not yet ready to serve.");
+ }
+out:
return 0;
}
@@ -1157,6 +1170,13 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
goto out;
}
+ ret = dict_get_uint32 (reply, "child_up", &conf->child_up);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING, 0, PC_MSG_DICT_GET_FAILED,
+ "failed to find key 'child_up' in the options");
+ goto out;
+ }
+
ret = dict_get_uint32 (reply, "clnt-lk-version", &lk_ver);
if (ret) {
gf_msg (this->name, GF_LOG_WARNING, 0, PC_MSG_DICT_GET_FAILED,
diff --git a/xlators/protocol/client/src/client-messages.h b/xlators/protocol/client/src/client-messages.h
index 0fc9d31729c..a4b391b8331 100644
--- a/xlators/protocol/client/src/client-messages.h
+++ b/xlators/protocol/client/src/client-messages.h
@@ -617,6 +617,7 @@
* @recommendedaction
*
*/
+#define PC_MSG_CHILD_STATUS (GLFS_PC_BASE + 64)
/*------------*/
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
index 29fe44c4974..f1f58eb822e 100644
--- a/xlators/protocol/client/src/client.c
+++ b/xlators/protocol/client/src/client.c
@@ -2467,6 +2467,8 @@ init (xlator_t *this)
pthread_mutex_init (&conf->lock, NULL);
INIT_LIST_HEAD (&conf->saved_fds);
+ conf->child_up = _gf_false;
+
/* Initialize parameters for lock self healing*/
conf->lk_version = 1;
conf->grace_timer = NULL;
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
index 415fabbd7e1..a4d4d9f75a5 100644
--- a/xlators/protocol/client/src/client.h
+++ b/xlators/protocol/client/src/client.h
@@ -133,6 +133,9 @@ typedef struct clnt_conf {
gf_boolean_t destroy; /* if enabled implies fini was called
* on @this xlator instance */
+
+ gf_boolean_t child_up; /* Set to true, when child is up, and
+ * false, when child is down */
} clnt_conf_t;
typedef struct _client_fd_ctx {
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
index 293509c5d3f..fe5dfbab516 100644
--- a/xlators/protocol/server/src/server-handshake.c
+++ b/xlators/protocol/server/src/server-handshake.c
@@ -385,6 +385,12 @@ server_setvolume (rpcsvc_request_t *req)
goto fail;
}
+ ret = dict_set_int32 (reply, "child_up", conf->child_up);
+ if (ret < 0)
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ PS_MSG_DICT_GET_FAILED, "Failed to set 'child_up' "
+ "in the reply dict");
+
buf = memdup (args.dict.dict_val, args.dict.dict_len);
if (buf == NULL) {
op_ret = -1;
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index d07b840b3fc..24e31500453 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -958,6 +958,8 @@ init (xlator_t *this)
if (ret)
conf->conf_dir = CONFDIR;
+ conf->child_up = _gf_false;
+
/*ret = dict_get_str (this->options, "statedump-path", &statedump_path);
if (!ret) {
gf_path_strip_trailing_slashes (statedump_path);
@@ -1237,6 +1239,35 @@ out:
}
int
+server_process_child_event (xlator_t *this, int32_t event, void *data,
+ enum gf_cbk_procnum cbk_procnum)
+{
+ int ret = -1;
+ server_conf_t *conf = NULL;
+ rpc_transport_t *xprt = NULL;
+
+ GF_VALIDATE_OR_GOTO(this->name, data, out);
+
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ rpcsvc_callback_submit (conf->rpc, xprt,
+ &server_cbk_prog,
+ cbk_procnum,
+ NULL, 0);
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int
notify (xlator_t *this, int32_t event, void *data, ...)
{
int ret = -1;
@@ -1246,6 +1277,10 @@ notify (xlator_t *this, int32_t event, void *data, ...)
server_conf_t *conf = NULL;
va_list ap;
+ GF_VALIDATE_OR_GOTO (THIS->name, this, out);
+ conf = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
dict = data;
va_start (ap, data);
output = va_arg (ap, dict_t*);
@@ -1272,7 +1307,41 @@ notify (xlator_t *this, int32_t event, void *data, ...)
conf->parent_up = _gf_true;
- /* fall through and notify the event to children */
+ default_notify (this, event, data);
+ break;
+ }
+
+ case GF_EVENT_CHILD_UP:
+ {
+ conf->child_up = _gf_true;
+ ret = server_process_child_event (this, event, data,
+ GF_CBK_CHILD_UP);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ PS_MSG_SERVER_EVENT_UPCALL_FAILED,
+ "server_process_child_event failed");
+ goto out;
+ }
+
+ default_notify (this, event, data);
+ break;
+ }
+
+ case GF_EVENT_CHILD_DOWN:
+ {
+ conf->child_up = _gf_false;
+ ret = server_process_child_event (this, event, data,
+ GF_CBK_CHILD_DOWN);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ PS_MSG_SERVER_EVENT_UPCALL_FAILED,
+ "server_process_child_event failed");
+ goto out;
+ }
+
+ default_notify (this, event, data);
+ break;
+
}
default:
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
index c0e2752cad7..7980d300be7 100644
--- a/xlators/protocol/server/src/server.h
+++ b/xlators/protocol/server/src/server.h
@@ -72,6 +72,8 @@ struct server_conf {
* in case if volume set options
* (say *.allow | *.reject) are
* tweeked */
+ gf_boolean_t child_up; /* Set to true, when child is up, and
+ * false, when child is down */
};
typedef struct server_conf server_conf_t;