summaryrefslogtreecommitdiffstats
path: root/xlators/protocol/server
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/protocol/server')
-rw-r--r--xlators/protocol/server/src/server-helpers.c112
-rw-r--r--xlators/protocol/server/src/server-helpers.h6
-rw-r--r--xlators/protocol/server/src/server-protocol.c39
-rw-r--r--xlators/protocol/server/src/server-protocol.h7
4 files changed, 158 insertions, 6 deletions
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 88dada1516e..0e22f0ba5fa 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -645,13 +645,14 @@ out:
int
-server_connection_cleanup (xlator_t *this, server_connection_t *conn)
+server_connection_cleanup (xlator_t *this, server_connection_t *conn, transport_t *trans)
{
char do_cleanup = 0;
struct _lock_table *ltable = NULL;
fdentry_t *fdentries = NULL;
uint32_t fd_count = 0;
int ret = 0;
+ int i = 0;
if (conn == NULL) {
goto out;
@@ -659,6 +660,12 @@ server_connection_cleanup (xlator_t *this, server_connection_t *conn)
pthread_mutex_lock (&conn->lock);
{
+ for (i = 0; i < TRANSPORTS_PER_SERVER_CONN; i++) {
+ if (conn->transports[i] == trans) {
+ conn->transports[i] = NULL;
+ transport_unref (trans);
+ }
+ }
conn->active_transports--;
if (conn->active_transports == 0) {
if (conn->ltable) {
@@ -850,11 +857,12 @@ out:
server_connection_t *
-server_connection_get (xlator_t *this, const char *id)
+server_connection_get (xlator_t *this, const char *id, transport_t *trans)
{
server_connection_t *conn = NULL;
server_connection_t *trav = NULL;
server_conf_t *conf = NULL;
+ int i = 0;
conf = this->private;
@@ -878,10 +886,30 @@ server_connection_get (xlator_t *this, const char *id)
list_add (&conn->list, &conf->conns);
}
+ if (conn->active_transports == TRANSPORTS_PER_SERVER_CONN) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Maximum number of connections allowed is %d",
+ TRANSPORTS_PER_SERVER_CONN);
+ goto unlock;
+ }
+
+ for (i = 0; i < TRANSPORTS_PER_SERVER_CONN; i++) {
+ if (!conn->transports[i])
+ break;
+ }
+
+ if (i == TRANSPORTS_PER_SERVER_CONN) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Could not find a vacant slot");
+ goto unlock;
+ }
+
+ conn->transports[i] = transport_ref (trans);
conn->ref++;
conn->active_transports++;
}
+unlock:
pthread_mutex_unlock (&conf->mutex);
return conn;
@@ -918,3 +946,83 @@ server_connection_put (xlator_t *this, server_connection_t *conn)
out:
return;
}
+
+void
+server_child_down (xlator_t *this, xlator_t *bound_xl)
+{
+ server_conf_t *conf = NULL;
+ server_connection_t *trav = NULL;
+ transport_t *trans = NULL;
+ int subvol_idx = 0;
+ int i = 0;
+ xlator_list_t *xltrav = NULL;
+
+ conf = this->private;
+
+ if (conf == NULL)
+ return;
+
+ xltrav = this->children;
+
+ while (xltrav) {
+ if (xltrav->xlator == bound_xl)
+ break;
+ xltrav = xltrav->next;
+ subvol_idx++;
+ }
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvolume %s(%d) went down", bound_xl->name, subvol_idx);
+
+ conf->subvol_list[subvol_idx] = 0;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ if (!list_empty(&conf->conns)) {
+ list_for_each_entry (trav, &conf->conns, list) {
+ if (bound_xl == trav->bound_xl) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "disonnecting conn=%p", trav);
+ for (i = 0; i < TRANSPORTS_PER_SERVER_CONN; i++)
+ {
+ trans = trav->transports[i];
+ if (trans == NULL)
+ continue;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "disconnecting %p(%d)",
+ trans, i);
+ transport_disconnect (trans);
+ }
+ }
+ }
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+}
+
+void
+server_child_up (xlator_t *this, xlator_t *bound_xl)
+{
+ server_conf_t *conf = NULL;
+ int subvol_idx = 0;
+ xlator_list_t *xltrav = NULL;
+
+ conf = this->private;
+
+ if (conf == NULL)
+ return;
+
+ xltrav = this->children;
+
+ while (xltrav) {
+ if (bound_xl == xltrav->xlator) {
+ break;
+ }
+ subvol_idx++;
+ xltrav = xltrav->next;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvolume %s(%d) came up", bound_xl->name, subvol_idx);
+
+ conf->subvol_list[subvol_idx] = 1;
+}
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index 867035d3334..5c584b00aa7 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -69,4 +69,10 @@ gf_direntry_to_bin (dir_entry_t *head, char *bufferp);
void
server_print_request (call_frame_t *frame);
+void
+server_child_up (xlator_t *this, xlator_t *bound_xl);
+
+void
+server_child_down (xlator_t *this, xlator_t *bound_xl);
+
#endif /* __SERVER_HELPERS_H__ */
diff --git a/xlators/protocol/server/src/server-protocol.c b/xlators/protocol/server/src/server-protocol.c
index 0528699acbe..a7f6294f387 100644
--- a/xlators/protocol/server/src/server-protocol.c
+++ b/xlators/protocol/server/src/server-protocol.c
@@ -5654,6 +5654,8 @@ mop_setvolume (call_frame_t *frame, xlator_t *bound_xl,
char *volfile_key = NULL;
uint32_t checksum = 0;
int32_t lru_limit = 1024;
+ xlator_list_t *xltrav = NULL;
+ int subvol_idx = 0;
params = dict_new ();
reply = dict_new ();
@@ -5695,7 +5697,7 @@ mop_setvolume (call_frame_t *frame, xlator_t *bound_xl,
}
- conn = server_connection_get (frame->this, process_uuid);
+ conn = server_connection_get (frame->this, process_uuid, trans);
if (trans->xl_private != conn)
trans->xl_private = conn;
@@ -5862,6 +5864,22 @@ mop_setvolume (call_frame_t *frame, xlator_t *bound_xl,
ret = dict_set_uint64 (reply, "transport-ptr",
((uint64_t) (long) trans));
+ xltrav = frame->this->children;
+ while (xltrav) {
+ if (xltrav->xlator == xl)
+ break;
+ xltrav = xltrav->next;
+ subvol_idx++;
+ }
+
+ if (conf->subvol_list[subvol_idx] == 0) {
+ gf_log (xl->name, GF_LOG_DEBUG,
+ "subvolume %d down (filesystem not accesible), failed to setvolume", subvol_idx);
+ op_ret = -1;
+ op_errno = ENOTCONN;
+ goto fail;
+ }
+
fail:
dict_len = dict_serialized_length (reply);
if (dict_len < 0) {
@@ -6550,6 +6568,8 @@ init (xlator_t *this)
server_conf_t *conf = NULL;
data_t *data = NULL;
data_t *trace = NULL;
+ int i = 0;
+ xlator_list_t *xltrav = NULL;
if (this->children == NULL) {
gf_log (this->name, GF_LOG_ERROR,
@@ -6635,6 +6655,15 @@ init (xlator_t *this)
}
}
+ xltrav = this->children;
+
+ while (xltrav) {
+ i++;
+ xltrav = xltrav->next;
+ }
+
+ conf->subvol_list = calloc (i, sizeof (char));
+
#ifndef GF_DARWIN_HOST_OS
{
struct rlimit lim;
@@ -6736,6 +6765,12 @@ notify (xlator_t *this, int32_t event, void *data, ...)
}
switch (event) {
+ case GF_EVENT_CHILD_DOWN:
+ server_child_down (this, data);
+ break;
+ case GF_EVENT_CHILD_UP:
+ server_child_up (this, data);
+ break;
case GF_EVENT_POLLIN:
ret = protocol_server_pollin (this, trans);
break;
@@ -6756,7 +6791,7 @@ notify (xlator_t *this, int32_t event, void *data, ...)
* FIXME: shouldn't we check for return value?
* what should be done if cleanup fails?
*/
- server_connection_cleanup (this, trans->xl_private);
+ server_connection_cleanup (this, trans->xl_private, trans);
}
}
break;
diff --git a/xlators/protocol/server/src/server-protocol.h b/xlators/protocol/server/src/server-protocol.h
index 78bc138279a..73e7f78911b 100644
--- a/xlators/protocol/server/src/server-protocol.h
+++ b/xlators/protocol/server/src/server-protocol.h
@@ -37,6 +37,7 @@
#define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */
#define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol"
+#define TRANSPORTS_PER_SERVER_CONN 2
typedef struct _server_state server_state_t;
@@ -64,6 +65,7 @@ struct _server_connection {
char *id;
int ref;
int active_transports;
+ transport_t *transports[TRANSPORTS_PER_SERVER_CONN];
pthread_mutex_t lock;
char disconnected;
fdtable_t *fdtable;
@@ -75,7 +77,7 @@ typedef struct _server_connection server_connection_t;
server_connection_t *
-server_connection_get (xlator_t *this, const char *id);
+server_connection_get (xlator_t *this, const char *id, transport_t *trans);
void
server_connection_put (xlator_t *this, server_connection_t *conn);
@@ -84,7 +86,7 @@ int
server_connection_destroy (xlator_t *this, server_connection_t *conn);
int
-server_connection_cleanup (xlator_t *this, server_connection_t *conn);
+server_connection_cleanup (xlator_t *this, server_connection_t *conn, transport_t *trans);
int
server_nop_cbk (call_frame_t *frame, void *cookie,
@@ -107,6 +109,7 @@ typedef struct {
pthread_mutex_t mutex;
struct list_head conns;
gf_boolean_t verify_volfile_checksum;
+ char *subvol_list;
gf_boolean_t trace;
} server_conf_t;