diff options
Diffstat (limited to 'xlators/protocol/server/src/server.c')
| -rw-r--r-- | xlators/protocol/server/src/server.c | 796 |
1 files changed, 351 insertions, 445 deletions
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 908f62a7b..589bd7b36 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ @@ -34,33 +25,56 @@ #include "statedump.h" #include "defaults.h" #include "authenticate.h" -#include "rpcsvc.h" void grace_time_handler (void *data) { - server_connection_t *conn = NULL; - xlator_t *this = NULL; - gf_boolean_t cancelled = _gf_false; - gf_boolean_t detached = _gf_false; + client_t *client = NULL; + xlator_t *this = NULL; + gf_timer_t *timer = NULL; + server_ctx_t *serv_ctx = NULL; + gf_boolean_t cancelled = _gf_false; + gf_boolean_t detached = _gf_false; - conn = data; - this = conn->this; + client = data; + this = client->this; - GF_VALIDATE_OR_GOTO (THIS->name, conn, out); GF_VALIDATE_OR_GOTO (THIS->name, this, out); - gf_log (this->name, GF_LOG_INFO, "grace timer expired for %s", conn->id); + gf_log (this->name, GF_LOG_INFO, "grace timer expired for %s", + client->client_uid); - cancelled = server_cancel_conn_timer (this, conn); + serv_ctx = server_ctx_get (client, this); + + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed"); + goto out; + } + + LOCK (&serv_ctx->fdtable_lock); + { + if (serv_ctx->grace_timer) { + timer = serv_ctx->grace_timer; + serv_ctx->grace_timer = NULL; + } + } + UNLOCK (&serv_ctx->fdtable_lock); + if (timer) { + gf_timer_call_cancel (this->ctx, timer); + cancelled = _gf_true; + } if (cancelled) { - //conn should not be destroyed in conn_put, so take a ref. - server_conn_ref (conn); - server_connection_put (this, conn, &detached); + + /* + * client must not be destroyed in gf_client_put(), + * so take a ref. + */ + gf_client_ref (client); + gf_client_put (client, &detached); if (detached)//reconnection did not happen :-( - server_connection_cleanup (this, conn, - INTERNAL_LOCKS | POSIX_LOCKS); - server_conn_unref (conn); + server_connection_cleanup (this, client, + INTERNAL_LOCKS | POSIX_LOCKS); + gf_client_unref (client); } out: return; @@ -116,8 +130,6 @@ ret: return iob; } - - int server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec *payload, int payloadcount, @@ -128,19 +140,24 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, struct iovec rsp = {0,}; server_state_t *state = NULL; char new_iobref = 0; - server_connection_t *conn = NULL; + client_t *client = NULL; gf_boolean_t lk_heal = _gf_false; + server_conf_t *conf = NULL; + gf_barrier_t *barrier = NULL; + gf_barrier_payload_t *stub = NULL; + gf_boolean_t barriered = _gf_false; GF_VALIDATE_OR_GOTO ("server", req, ret); if (frame) { state = CALL_STATE (frame); frame->local = NULL; - conn = SERVER_CONNECTION(frame); + client = frame->root->client; + conf = (server_conf_t *) client->this->private; } - if (conn) - lk_heal = ((server_conf_t *) conn->this->private)->lk_heal; + if (client) + lk_heal = ((server_conf_t *) client->this->private)->lk_heal; if (!iobref) { iobref = iobref_new (); @@ -159,6 +176,32 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, iobref_add (iobref, iob); + if (conf) + barrier = conf->barrier; + if (barrier) { + /* todo: write's with fd flags set to O_SYNC and O_DIRECT */ + LOCK (&barrier->lock); + { + if (is_fop_barriered (barrier->fops, req->procnum) && + (barrier_add_to_queue (barrier))) { + stub = gf_barrier_payload (req, &rsp, frame, + payload, + payloadcount, iobref, + iob, new_iobref); + if (stub) { + gf_barrier_enqueue (barrier, stub); + barriered = _gf_true; + } else { + gf_log ("", GF_LOG_ERROR, "Failed to " + " barrier fop %"PRIu64, + ((uint64_t)1 << req->procnum)); + } + } + } + UNLOCK (&barrier->lock); + if (barriered == _gf_true) + goto out; + } /* Then, submit the message for transmission. */ ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount, iobref); @@ -174,13 +217,14 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg, iobuf_unref (iob); if (ret == -1) { gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed"); - if (frame && conn && !lk_heal) { - server_connection_cleanup (frame->this, conn, + if (frame && client && !lk_heal) { + server_connection_cleanup (frame->this, client, INTERNAL_LOCKS | POSIX_LOCKS); } else { + gf_log_callingfn ("", GF_LOG_ERROR, + "Reply submission failed"); /* TODO: Failure of open(dir), create, inodelk, entrylk or lk fops send failure must be handled specially. */ - ; } goto ret; } @@ -192,185 +236,17 @@ ret: } if (frame) { - if (frame->root->trans) - server_conn_unref (frame->root->trans); + gf_client_unref (client); STACK_DESTROY (frame->root); } if (new_iobref) { iobref_unref (iobref); } - - return ret; -} - -/* */ -int -server_fd_to_dict (xlator_t *this, dict_t *dict) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN] = {0,}; - int count = 0; - int ret = -1; - - GF_VALIDATE_OR_GOTO (THIS->name, this, out); - GF_VALIDATE_OR_GOTO (this->name, dict, out); - - conf = this->private; - if (!conf) - return -1; - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) - return -1; - - list_for_each_entry (trav, &conf->conns, list) { - memset (key, 0, sizeof (key)); - snprintf (key, sizeof (key), "conn%d", count++); - fdtable_dump_to_dict (trav->fdtable, key, dict); - } - pthread_mutex_unlock (&conf->mutex); - - ret = dict_set_int32 (dict, "conncount", count); -out: - return ret; -} - -int -server_fd (xlator_t *this) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN]; - int i = 1; - int ret = -1; - gf_boolean_t section_added = _gf_false; - - GF_VALIDATE_OR_GOTO ("server", this, out); - - conf = this->private; - if (!conf) { - gf_log (this->name, GF_LOG_WARNING, - "conf null in xlator"); - return -1; - } - - gf_proc_dump_add_section("xlator.protocol.server.conn"); - section_added = _gf_true; - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) - goto out; - - list_for_each_entry (trav, &conf->conns, list) { - if (trav->id) { - gf_proc_dump_build_key(key, - "conn","%d.id", i); - gf_proc_dump_write(key, "%s", trav->id); - } - - gf_proc_dump_build_key(key,"conn","%d.ref",i) - gf_proc_dump_write(key, "%d", trav->ref); - if (trav->bound_xl) { - gf_proc_dump_build_key(key, - "conn","%d.bound_xl", i); - gf_proc_dump_write(key, "%s", trav->bound_xl->name); - } - - gf_proc_dump_build_key(key, - "conn","%d.id", i); - fdtable_dump(trav->fdtable,key); - i++; - } - pthread_mutex_unlock (&conf->mutex); - - ret = 0; out: - if (ret) { - if (section_added == _gf_false) - gf_proc_dump_add_section("xlator.protocol.server.conn"); - gf_proc_dump_write ("Unable to dump the list of connections", - "(Lock acquisition failed) %s", - this?this->name:"server"); - } return ret; } -void -ltable_dump (server_connection_t *trav) -{ - char key[GF_DUMP_MAX_BUF_LEN] = {0,}; - struct _locker *locker = NULL; - char locker_data[GF_MAX_LOCK_OWNER_LEN] = {0,}; - int count = 0; - - gf_proc_dump_build_key(key, - "conn","bound_xl.ltable.inodelk.%s", - trav->bound_xl?trav->bound_xl->name:""); - gf_proc_dump_add_section(key); - - list_for_each_entry (locker, &trav->ltable->inodelk_lockers, lockers) { - count++; - gf_proc_dump_write("volume", "%s", locker->volume); - if (locker->fd) { - gf_proc_dump_write("fd", "%p", locker->fd); - gf_proc_dump_write("gfid", "%s", - uuid_utoa (locker->fd->inode->gfid)); - } else { - gf_proc_dump_write("fd", "%s", locker->loc.path); - gf_proc_dump_write("gfid", "%s", - uuid_utoa (locker->loc.inode->gfid)); - } - gf_proc_dump_write("pid", "%d", locker->pid); - gf_proc_dump_write("lock length", "%d", locker->owner.len); - lkowner_unparse (&locker->owner, locker_data, - locker->owner.len); - gf_proc_dump_write("lock owner", "%s", locker_data); - memset (locker_data, 0, sizeof (locker_data)); - - gf_proc_dump_build_key (key, "inode", "%d", count); - gf_proc_dump_add_section (key); - if (locker->fd) - inode_dump (locker->fd->inode, key); - else - inode_dump (locker->loc.inode, key); - } - - count = 0; - locker = NULL; - gf_proc_dump_build_key(key, - "conn","bound_xl.ltable.entrylk.%s", - trav->bound_xl?trav->bound_xl->name:""); - gf_proc_dump_add_section(key); - - list_for_each_entry (locker, &trav->ltable->entrylk_lockers, - lockers) { - count++; - gf_proc_dump_write("volume", "%s", locker->volume); - if (locker->fd) { - gf_proc_dump_write("fd", "%p", locker->fd); - gf_proc_dump_write("gfid", "%s", - uuid_utoa (locker->fd->inode->gfid)); - } else { - gf_proc_dump_write("fd", "%s", locker->loc.path); - gf_proc_dump_write("gfid", "%s", - uuid_utoa (locker->loc.inode->gfid)); - } - gf_proc_dump_write("pid", "%d", locker->pid); - gf_proc_dump_write("lock length", "%d", locker->owner.len); - lkowner_unparse (&locker->owner, locker_data, locker->owner.len); - gf_proc_dump_write("lock data", "%s", locker_data); - memset (locker_data, 0, sizeof (locker_data)); - - gf_proc_dump_build_key (key, "inode", "%d", count); - gf_proc_dump_add_section (key); - if (locker->fd) - inode_dump (locker->fd->inode, key); - else - inode_dump (locker->loc.inode, key); - } -} int server_priv_to_dict (xlator_t *this, dict_t *dict) @@ -477,104 +353,6 @@ out: return ret; } -int -server_inode_to_dict (xlator_t *this, dict_t *dict) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[32] = {0,}; - int count = 0; - int ret = -1; - xlator_t *prev_bound_xl = NULL; - - GF_VALIDATE_OR_GOTO (THIS->name, this, out); - GF_VALIDATE_OR_GOTO (this->name, dict, out); - - conf = this->private; - if (!conf) - return -1; - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) - return -1; - - list_for_each_entry (trav, &conf->conns, list) { - if (trav->bound_xl && trav->bound_xl->itable) { - /* Presently every brick contains only one - * bound_xl for all connections. This will lead - * to duplicating of the inode lists, if listing - * is done for every connection. This simple check - * prevents duplication in the present case. If - * need arises the check can be improved. - */ - if (trav->bound_xl == prev_bound_xl) - continue; - prev_bound_xl = trav->bound_xl; - - memset (key, 0, sizeof (key)); - snprintf (key, sizeof (key), "conn%d", count); - inode_table_dump_to_dict (trav->bound_xl->itable, - key, dict); - count++; - } - } - pthread_mutex_unlock (&conf->mutex); - - ret = dict_set_int32 (dict, "conncount", count); - -out: - if (prev_bound_xl) - prev_bound_xl = NULL; - return ret; -} - -int -server_inode (xlator_t *this) -{ - server_conf_t *conf = NULL; - server_connection_t *trav = NULL; - char key[GF_DUMP_MAX_BUF_LEN]; - int i = 1; - int ret = -1; - - GF_VALIDATE_OR_GOTO ("server", this, out); - - conf = this->private; - if (!conf) { - gf_log (this->name, GF_LOG_WARNING, - "conf null in xlator"); - return -1; - } - - ret = pthread_mutex_trylock (&conf->mutex); - if (ret) - goto out; - - list_for_each_entry (trav, &conf->conns, list) { - ret = pthread_mutex_trylock (&trav->lock); - if (!ret) - { - gf_proc_dump_build_key(key, - "conn","%d.ltable", i); - gf_proc_dump_add_section(key); - ltable_dump (trav); - i++; - pthread_mutex_unlock (&trav->lock); - }else - continue; - } - pthread_mutex_unlock (&conf->mutex); - - ret = 0; -out: - if (ret) - gf_proc_dump_write ("Unable to dump the lock table", - "(Lock acquisition failed) %s", - this?this->name:"server"); - - return ret; -} - static int get_auth_types (dict_t *this, char *key, data_t *value, void *data) @@ -616,84 +394,85 @@ out: return 0; } +int +_check_for_auth_option (dict_t *d, char *k, data_t *v, + void *tmp) +{ + int ret = 0; + xlator_t *xl = NULL; + char *tail = NULL; + char *tmp_addr_list = NULL; + char *addr = NULL; + char *tmp_str = NULL; + + xl = tmp; + + tail = strtail (k, "auth."); + if (!tail) + goto out; + + /* fast fwd thru module type */ + tail = strchr (tail, '.'); + if (!tail) + goto out; + tail++; + + tail = strtail (tail, xl->name); + if (!tail) + goto out; + + if (*tail == '.') { + /* when we are here, the key is checked for + * valid auth.allow.<xlator> + * Now we verify the ip address + */ + if (!strcmp (v->data, "*")) { + ret = 0; + goto out; + } + + tmp_addr_list = gf_strdup (v->data); + addr = strtok_r (tmp_addr_list, ",", &tmp_str); + if (!addr) + addr = v->data; + + while (addr) { + if (valid_internet_address (addr, _gf_true)) { + ret = 0; + } else { + ret = -1; + gf_log (xl->name, GF_LOG_ERROR, + "internet address '%s'" + " does not conform to" + " standards.", addr); + goto out; + } + if (tmp_str) + addr = strtok_r (NULL, ",", &tmp_str); + else + addr = NULL; + } + + GF_FREE (tmp_addr_list); + tmp_addr_list = NULL; + } +out: + return ret; +} int validate_auth_options (xlator_t *this, dict_t *dict) { int error = -1; xlator_list_t *trav = NULL; - char *tail = NULL; - char *tmp_addr_list = NULL; - char *addr = NULL; - char *tmp_str = NULL; GF_VALIDATE_OR_GOTO ("server", this, out); GF_VALIDATE_OR_GOTO ("server", dict, out); trav = this->children; while (trav) { - int _check_for_auth_option (dict_t *d, char *k, data_t *v, - void *tmp) - { - int ret = 0; - tail = strtail (k, "auth."); - if (!tail) - goto internal_out; - - /* fast fwd thru module type */ - tail = strchr (tail, '.'); - if (!tail) - goto internal_out; - tail++; - - tail = strtail (tail, trav->xlator->name); - if (!tail) - goto internal_out; - - if (*tail == '.') { - - /* when we are here, the key is checked for - * valid auth.allow.<xlator> - * Now we verify the ip address - */ - if (!strcmp (v->data, "*")) { - ret = 0; - goto internal_out; - } - - tmp_addr_list = gf_strdup (v->data); - addr = strtok_r (tmp_addr_list, ",", &tmp_str); - if (!addr) - addr = v->data; - - while (addr) { - - if (valid_internet_address (addr, - _gf_true)) { - ret = 0; - } else { - ret = -1; - gf_log (this->name, GF_LOG_ERROR, - "internet address '%s'" - " does not conform to" - " standards.", addr); - goto internal_out; - - } - if (tmp_str) - addr = strtok_r (NULL, ",", - &tmp_str); - else - addr = NULL; - } - - GF_FREE (tmp_addr_list); - tmp_addr_list = NULL; - } - internal_out: - return ret; - } - error = dict_foreach (dict, _check_for_auth_option, NULL); + error = dict_foreach (dict, _check_for_auth_option, + trav->xlator); if (-1 == error) { gf_log (this->name, GF_LOG_ERROR, @@ -706,7 +485,6 @@ validate_auth_options (xlator_t *this, dict_t *dict) } out: - GF_FREE (tmp_addr_list); return error; } @@ -717,9 +495,10 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, { gf_boolean_t detached = _gf_false; xlator_t *this = NULL; - rpc_transport_t *xprt = NULL; - server_connection_t *conn = NULL; + rpc_transport_t *trans = NULL; server_conf_t *conf = NULL; + client_t *client = NULL; + server_ctx_t *serv_ctx = NULL; if (!xl || !data) { gf_log_callingfn ("server", GF_LOG_WARNING, @@ -728,7 +507,7 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, } this = xl; - xprt = data; + trans = data; conf = this->private; switch (event) { @@ -736,17 +515,17 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, { /* Have a structure per new connection */ /* TODO: Should we create anything here at all ? * / - conn = create_server_conn_state (this, xprt); - if (!conn) + client->conn = create_server_conn_state (this, trans); + if (!client->conn) goto out; - xprt->protocol_private = conn; + trans->protocol_private = client->conn; */ - INIT_LIST_HEAD (&xprt->list); + INIT_LIST_HEAD (&trans->list); pthread_mutex_lock (&conf->mutex); { - list_add_tail (&xprt->list, &conf->xprt_list); + list_add_tail (&trans->list, &conf->xprt_list); } pthread_mutex_unlock (&conf->mutex); @@ -759,50 +538,58 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, */ pthread_mutex_lock (&conf->mutex); { - list_del_init (&xprt->list); + list_del_init (&trans->list); } pthread_mutex_unlock (&conf->mutex); - conn = get_server_conn_state (this, xprt); - if (!conn) + client = trans->xl_private; + if (!client) break; gf_log (this->name, GF_LOG_INFO, "disconnecting connection" - "from %s", conn->id); + "from %s", client->client_uid); /* If lock self heal is off, then destroy the conn object, else register a grace timer event */ if (!conf->lk_heal) { - server_conn_ref (conn); - server_connection_put (this, conn, &detached); + gf_client_ref (client); + gf_client_put (client, &detached); if (detached) - server_connection_cleanup (this, conn, - INTERNAL_LOCKS | - POSIX_LOCKS); - server_conn_unref (conn); - } else { - put_server_conn_state (this, xprt); - server_connection_cleanup (this, conn, INTERNAL_LOCKS); + server_connection_cleanup (this, client, + INTERNAL_LOCKS | POSIX_LOCKS); + gf_client_unref (client); + break; + } + trans->xl_private = NULL; + server_connection_cleanup (this, client, INTERNAL_LOCKS); + + serv_ctx = server_ctx_get (client, this); - pthread_mutex_lock (&conn->lock); - { - if (conn->timer) - goto unlock; + if (serv_ctx == NULL) { + gf_log (this->name, GF_LOG_INFO, + "server_ctx_get() failed"); + goto out; + } + + LOCK (&serv_ctx->fdtable_lock); + { + if (!serv_ctx->grace_timer) { - gf_log (this->name, GF_LOG_INFO, "starting a grace " - "timer for %s", conn->id); + gf_log (this->name, GF_LOG_INFO, + "starting a grace timer for %s", + client->client_uid); - conn->timer = gf_timer_call_after (this->ctx, - conf->grace_tv, - grace_time_handler, - conn); + serv_ctx->grace_timer = + gf_timer_call_after (this->ctx, + conf->grace_ts, + grace_time_handler, + client); } - unlock: - pthread_mutex_unlock (&conn->lock); } + UNLOCK (&serv_ctx->fdtable_lock); break; case RPCSVC_EVENT_TRANSPORT_DESTROY: - /*- conn obj has been disassociated from xprt on first + /*- conn obj has been disassociated from trans on first * disconnect. * conn cleanup and destruction is handed over to * grace_time_handler or the subsequent handler that 'owns' @@ -839,13 +626,16 @@ static int _delete_auth_opt (dict_t *this, char *key, data_t *value, void *data) { char *auth_option_pattern[] = { "auth.addr.*.allow", - "auth.addr.*.reject"}; + "auth.addr.*.reject", + NULL}; + int i = 0; - if (fnmatch ( auth_option_pattern[0], key, 0) != 0) - dict_del (this, key); - - if (fnmatch ( auth_option_pattern[1], key, 0) != 0) - dict_del (this, key); + for (i = 0; auth_option_pattern[i]; i++) { + if (fnmatch (auth_option_pattern[i], key, 0) == 0) { + dict_del (this, key); + break; + } + } return 0; } @@ -855,12 +645,16 @@ static int _copy_auth_opt (dict_t *unused, char *key, data_t *value, void *xl_dict) { char *auth_option_pattern[] = { "auth.addr.*.allow", - "auth.addr.*.reject"}; - if (fnmatch ( auth_option_pattern[0], key, 0) != 0) - dict_set ((dict_t *)xl_dict, key, (value)); + "auth.addr.*.reject", + NULL}; + int i = 0; - if (fnmatch ( auth_option_pattern[1], key, 0) != 0) - dict_set ((dict_t *)xl_dict, key, (value)); + for (i = 0; auth_option_pattern [i]; i++) { + if (fnmatch (auth_option_pattern[i], key, 0) == 0) { + dict_set ((dict_t *)xl_dict, key, value); + break; + } + } return 0; } @@ -889,14 +683,14 @@ server_init_grace_timer (xlator_t *this, dict_t *options, ret = dict_get_int32 (options, "grace-timeout", &grace_timeout); if (!ret) - conf->grace_tv.tv_sec = grace_timeout; + conf->grace_ts.tv_sec = grace_timeout; else - conf->grace_tv.tv_sec = 10; + conf->grace_ts.tv_sec = 10; gf_log (this->name, GF_LOG_DEBUG, "Server grace timeout " - "value = %"PRIu64, conf->grace_tv.tv_sec); + "value = %"PRIu64, conf->grace_ts.tv_sec); - conf->grace_tv.tv_usec = 0; + conf->grace_ts.tv_nsec = 0; ret = 0; out: @@ -934,21 +728,15 @@ reconfigure (xlator_t *this, dict_t *options) gf_log (this->name, GF_LOG_WARNING, "'trace' takes on only boolean values. " "Neglecting option"); - ret = -1; + ret = -1; goto out; - } - conf->trace = trace; - gf_log (this->name, GF_LOG_TRACE, "Reconfigured trace" - " to %d", conf->trace); + } + conf->trace = trace; + gf_log (this->name, GF_LOG_TRACE, "Reconfigured trace" + " to %d", conf->trace); - } + } - /*ret = dict_get_str (options, "statedump-path", &statedump_path); - if (!ret) { - gf_path_strip_trailing_slashes (statedump_path); - GF_FREE (this->ctx->statedump_path); - this->ctx->statedump_path = gf_strdup (statedump_path); - }*/ GF_OPTION_RECONF ("statedump-path", statedump_path, options, path, out); if (!statedump_path) { @@ -986,6 +774,8 @@ reconfigure (xlator_t *this, dict_t *options) } (void) rpcsvc_set_allow_insecure (rpc_conf, options); + (void) rpcsvc_set_root_squash (rpc_conf, options); + (void) rpcsvc_set_outstanding_rpc_limit (rpc_conf, options); list_for_each_entry (listeners, &(rpc_conf->listeners), list) { if (listeners->trans != NULL) { if (listeners->trans->reconfigure ) @@ -1002,6 +792,26 @@ out: return ret; } +static int32_t +client_destroy_cbk (xlator_t *this, client_t *client) +{ + void *tmp = NULL; + server_ctx_t *ctx = NULL; + + client_ctx_del (client, this, &tmp); + + ctx = tmp; + + if (ctx == NULL) + return 0; + + gf_fd_fdtable_destroy (ctx->fdtable); + LOCK_DESTROY (&ctx->fdtable_lock); + GF_FREE (ctx); + + return 0; +} + int init (xlator_t *this) { @@ -1009,6 +819,8 @@ init (xlator_t *this) server_conf_t *conf = NULL; rpcsvc_listener_t *listener = NULL; char *statedump_path = NULL; + gf_barrier_t *barrier = NULL; + char *str = NULL; GF_VALIDATE_OR_GOTO ("init", this, out); if (this->children == NULL) { @@ -1028,7 +840,6 @@ init (xlator_t *this) GF_VALIDATE_OR_GOTO(this->name, conf, out); - INIT_LIST_HEAD (&conf->conns); INIT_LIST_HEAD (&conf->xprt_list); pthread_mutex_init (&conf->mutex, NULL); @@ -1150,6 +961,37 @@ init (xlator_t *this) } } #endif + /* barrier related */ + barrier = GF_CALLOC (1, sizeof (*barrier),1); + if (!barrier) { + gf_log (this->name, GF_LOG_WARNING, + "WARNING: Failed to allocate barrier"); + ret = -1; + goto out; + } + + LOCK_INIT (&barrier->lock); + INIT_LIST_HEAD (&barrier->queue); + barrier->on = _gf_false; + + GF_OPTION_INIT ("barrier-queue-length", barrier->max_size, + int64, out); + GF_OPTION_INIT ("barrier-timeout", barrier->time_out, + uint64, out); + + ret = dict_get_str (this->options, "barrier-fops", &str); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, + "setting barrier fops to default value"); + } + ret = gf_barrier_fops_configure (this, barrier, str); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "invalid barrier fops specified"); + goto out; + } + + conf->barrier = barrier; this->private = conf; ret = 0; @@ -1203,29 +1045,65 @@ int notify (xlator_t *this, int32_t event, void *data, ...) { int ret = 0; + int32_t val = 0; + dict_t *dict = NULL; + dict_t *output = NULL; + va_list ap; + + dict = data; + va_start (ap, data); + output = va_arg (ap, dict_t*); + va_end (ap); + switch (event) { + case GF_EVENT_VOLUME_BARRIER_OP: + ret = dict_get_int32 (dict, "barrier", &val); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Wrong BARRIER event"); + goto out; + } + /* !val un-barrier, if val, barrier */ + if (val) { + ret = gf_barrier_start (this); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Barrier start failed"); + } else { + ret = gf_barrier_stop (this); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Barrier stop failed"); + } + ret = dict_set_int32 (output, "barrier-status", ret); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Failed to set barrier-status in dict"); + break; + + /* todo: call default_notify to make other xlators handle it.*/ default: default_notify (this, event, data); break; } - +out: return ret; } -struct xlator_fops fops = { -}; +struct xlator_fops fops; struct xlator_cbks cbks = { + .client_destroy = client_destroy_cbk, }; struct xlator_dumpops dumpops = { .priv = server_priv, - .fd = server_fd, - .inode = server_inode, + .fd = gf_client_dump_fdtables, + .inode = gf_client_dump_inodes, .priv_to_dict = server_priv_to_dict, - .fd_to_dict = server_fd_to_dict, - .inode_to_dict = server_inode_to_dict, + .fd_to_dict = gf_client_dump_fdtables_to_dict, + .inode_to_dict = gf_client_dump_inodes_to_dict, }; @@ -1253,6 +1131,8 @@ struct volume_options options[] = { .min = 0, .max = (1 * GF_UNIT_MB), .default_value = "16384", + .description = "Specifies the maximum megabytes of memory to be " + "used in the inode cache." }, { .key = {"verify-volfile-checksum"}, .type = GF_OPTION_TYPE_BOOL @@ -1267,9 +1147,17 @@ struct volume_options options[] = { { .key = {"rpc-auth-allow-insecure"}, .type = GF_OPTION_TYPE_BOOL, }, + { .key = {"root-squash"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "Map requests from uid/gid 0 to the anonymous " + "uid/gid. Note that this does not apply to any other" + "uids or gids that might be equally sensitive, such as" + "user bin or group staff." + }, { .key = {"statedump-path"}, .type = GF_OPTION_TYPE_PATH, - .default_value = "/tmp", + .default_value = DEFAULT_VAR_RUN_DIRECTORY, .description = "Specifies directory in which gluster should save its" " statedumps. By default it is the /tmp directory" }, @@ -1285,7 +1173,8 @@ struct volume_options options[] = { {.key = {"tcp-window-size"}, .type = GF_OPTION_TYPE_SIZET, .min = GF_MIN_SOCKET_WINDOW_SIZE, - .max = GF_MAX_SOCKET_WINDOW_SIZE + .max = GF_MAX_SOCKET_WINDOW_SIZE, + .description = "Specifies the window size for tcp socket." }, /* The following two options are defined in addr.c, redifined here * @@ -1303,6 +1192,23 @@ struct volume_options options[] = { "hostnames to connect to the server. By default, all" " connections are allowed." }, - + {.key = {"barrier-timeout"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "60", + .min = 0, + .max = 360, + .description = "Barrier timeout in seconds", + }, + {.key = {"barrier-queue-length"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "4096", + .min = 0, + .max = 16384, + .description = "Barrier queue length", + }, + {.key = {"barrier-fops"}, + .type = GF_OPTION_TYPE_STR, + .description = "Allow a comma seperated fop lists", + }, { .key = {NULL} }, }; |
