diff options
Diffstat (limited to 'xlators/protocol/server/src/server-helpers.c')
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 2416 |
1 files changed, 1233 insertions, 1183 deletions
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 7c5106d01b8..6e644912a46 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -1,1457 +1,1507 @@ /* - 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. */ -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - #include "server.h" #include "server-helpers.h" +#include <glusterfs/gidcache.h> +#include "server-messages.h" +#include <glusterfs/syscall.h> +#include <glusterfs/defaults.h> +#include <glusterfs/default-args.h> +#include "server-common.h" #include <fnmatch.h> +#include <pwd.h> +/* based on nfs_fix_aux_groups() */ int -server_decode_groups (call_frame_t *frame, rpcsvc_request_t *req) -{ - int i = 0; - - GF_VALIDATE_OR_GOTO ("server", frame, out); - GF_VALIDATE_OR_GOTO ("server", req, out); - - frame->root->ngrps = req->auxgidcount; - if (frame->root->ngrps == 0) - return 0; - - if (frame->root->ngrps > GF_MAX_AUX_GROUPS) - return -1; - - for (; i < frame->root->ngrps; ++i) - frame->root->groups[i] = req->auxgids[i]; -out: - return 0; -} - -void -server_loc_wipe (loc_t *loc) +gid_resolve(server_conf_t *conf, call_stack_t *root) { - if (loc->parent) { - inode_unref (loc->parent); - loc->parent = NULL; - } - - if (loc->inode) { - inode_unref (loc->inode); - loc->inode = NULL; + int ret = 0; + struct passwd mypw; + char mystrs[1024]; + struct passwd *result; + gid_t *mygroups = NULL; + gid_list_t gl; + int ngroups; + const gid_list_t *agl; + + agl = gid_cache_lookup(&conf->gid_cache, root->uid, 0, 0); + if (agl) { + root->ngrps = agl->gl_count; + + if (root->ngrps > 0) { + ret = call_stack_alloc_groups(root, agl->gl_count); + if (ret == 0) { + memcpy(root->groups, agl->gl_list, + sizeof(gid_t) * agl->gl_count); + } } - if (loc->path) - GF_FREE ((void *)loc->path); -} - - -void -server_resolve_wipe (server_resolve_t *resolve) -{ - if (resolve->path) - GF_FREE ((void *)resolve->path); - - if (resolve->bname) - GF_FREE ((void *)resolve->bname); + gid_cache_release(&conf->gid_cache, agl); - loc_wipe (&resolve->resolve_loc); + return ret; + } + + ret = getpwuid_r(root->uid, &mypw, mystrs, sizeof(mystrs), &result); + if (ret != 0) { + gf_smsg("gid-cache", GF_LOG_ERROR, errno, PS_MSG_GET_UID_FAILED, + "uid=%u", root->uid, NULL); + return -1; + } + + if (!result) { + gf_smsg("gid-cache", GF_LOG_ERROR, 0, PS_MSG_UID_NOT_FOUND, "uid=%u", + root->uid, NULL); + return -1; + } + + gf_msg_trace("gid-cache", 0, "mapped %u => %s", root->uid, result->pw_name); + + ngroups = gf_getgrouplist(result->pw_name, root->gid, &mygroups); + if (ngroups == -1) { + gf_smsg("gid-cache", GF_LOG_ERROR, 0, PS_MSG_MAPPING_ERROR, + "pw_name=%s", result->pw_name, "root->ngtps=%d", root->ngrps, + NULL); + return -1; + } + root->ngrps = (uint16_t)ngroups; + + /* setup a full gid_list_t to add it to the gid_cache */ + gl.gl_id = root->uid; + gl.gl_uid = root->uid; + gl.gl_gid = root->gid; + gl.gl_count = root->ngrps; + + gl.gl_list = GF_MALLOC(root->ngrps * sizeof(gid_t), gf_common_mt_groups_t); + if (gl.gl_list) + memcpy(gl.gl_list, mygroups, sizeof(gid_t) * root->ngrps); + else { + GF_FREE(mygroups); + return -1; + } + + if (root->ngrps > 0) { + call_stack_set_groups(root, root->ngrps, &mygroups); + } + + if (gid_cache_add(&conf->gid_cache, &gl) != 1) + GF_FREE(gl.gl_list); + + return ret; } - -void -free_state (server_state_t *state) +int +server_resolve_groups(call_frame_t *frame, rpcsvc_request_t *req) { - if (state->conn) { - //xprt_svc_unref (state->conn); - state->conn = NULL; - } - - if (state->xprt) { - rpc_transport_unref (state->xprt); - state->xprt = NULL; - } - if (state->fd) { - fd_unref (state->fd); - state->fd = NULL; - } - - if (state->params) { - dict_unref (state->params); - state->params = NULL; - } - - if (state->iobref) { - iobref_unref (state->iobref); - state->iobref = NULL; - } + xlator_t *this = NULL; + server_conf_t *conf = NULL; - if (state->iobuf) { - iobuf_unref (state->iobuf); - state->iobuf = NULL; - } + GF_VALIDATE_OR_GOTO("server", frame, out); + GF_VALIDATE_OR_GOTO("server", req, out); - if (state->dict) { - dict_unref (state->dict); - state->dict = NULL; - } + this = req->trans->xl; + conf = this->private; - if (state->xdata) { - dict_unref (state->xdata); - state->xdata = NULL; - } - - if (state->volume) - GF_FREE ((void *)state->volume); - - if (state->name) - GF_FREE ((void *)state->name); - - server_loc_wipe (&state->loc); - server_loc_wipe (&state->loc2); - - server_resolve_wipe (&state->resolve); - server_resolve_wipe (&state->resolve2); - - GF_FREE (state); + return gid_resolve(conf, frame->root); +out: + return -1; } - int -gf_add_locker (server_connection_t *conn, const char *volume, - loc_t *loc, fd_t *fd, pid_t pid, gf_lkowner_t *owner, - glusterfs_fop_t type) +server_decode_groups(call_frame_t *frame, rpcsvc_request_t *req) { - int32_t ret = -1; - struct _locker *new = NULL; - struct _lock_table *table = NULL; + int i = 0; - GF_VALIDATE_OR_GOTO ("server", volume, out); + GF_VALIDATE_OR_GOTO("server", frame, out); + GF_VALIDATE_OR_GOTO("server", req, out); - new = GF_CALLOC (1, sizeof (struct _locker), gf_server_mt_locker_t); - if (new == NULL) { - goto out; - } - INIT_LIST_HEAD (&new->lockers); + if (call_stack_alloc_groups(frame->root, req->auxgidcount) != 0) + return -1; - new->volume = gf_strdup (volume); - - if (fd == NULL) { - loc_copy (&new->loc, loc); - } else { - new->fd = fd_ref (fd); - } + frame->root->ngrps = req->auxgidcount; + if (frame->root->ngrps == 0) + return 0; - new->pid = pid; - new->owner = *owner; + /* ngrps cannot be bigger than USHRT_MAX(65535) */ + if (frame->root->ngrps > GF_MAX_AUX_GROUPS) + return -1; - pthread_mutex_lock (&conn->lock); - { - table = conn->ltable; - if (type == GF_FOP_ENTRYLK) - list_add_tail (&new->lockers, &table->entrylk_lockers); - else - list_add_tail (&new->lockers, &table->inodelk_lockers); - } - pthread_mutex_unlock (&conn->lock); + for (; i < frame->root->ngrps; ++i) + frame->root->groups[i] = req->auxgids[i]; out: - return ret; + return 0; } - -int -gf_del_locker (server_connection_t *conn, const char *volume, - loc_t *loc, fd_t *fd, gf_lkowner_t *owner, - glusterfs_fop_t type) +void +server_loc_wipe(loc_t *loc) { - struct _locker *locker = NULL; - struct _locker *tmp = NULL; - int32_t ret = -1; - struct list_head *head = NULL; - struct list_head del; - struct _lock_table *table = NULL; - - GF_VALIDATE_OR_GOTO ("server", volume, out); - - INIT_LIST_HEAD (&del); + if (loc->parent) { + inode_unref(loc->parent); + loc->parent = NULL; + } - pthread_mutex_lock (&conn->lock); - { - table = conn->ltable; - if (type == GF_FOP_ENTRYLK) { - head = &table->entrylk_lockers; - } else { - head = &table->inodelk_lockers; - } + if (loc->inode) { + inode_unref(loc->inode); + loc->inode = NULL; + } - list_for_each_entry_safe (locker, tmp, head, lockers) { - if (!is_same_lkowner (&locker->owner, owner) || - strcmp (locker->volume, volume)) - continue; - - if (locker->fd && fd && (locker->fd == fd)) - list_move_tail (&locker->lockers, &del); - else if (locker->loc.inode && loc && - (locker->loc.inode == loc->inode)) - list_move_tail (&locker->lockers, &del); - } - } - pthread_mutex_unlock (&conn->lock); - - tmp = NULL; - locker = NULL; + GF_FREE((void *)loc->path); +} - list_for_each_entry_safe (locker, tmp, &del, lockers) { - list_del_init (&locker->lockers); - if (locker->fd) - fd_unref (locker->fd); - else - loc_wipe (&locker->loc); +void +server_resolve_wipe(server_resolve_t *resolve) +{ + GF_FREE((void *)resolve->path); - GF_FREE (locker->volume); - GF_FREE (locker); - } + GF_FREE((void *)resolve->bname); - ret = 0; -out: - return ret; + loc_wipe(&resolve->resolve_loc); } -static struct _lock_table * -gf_lock_table_new (void) +void +free_state(server_state_t *state) { - struct _lock_table *new = NULL; - - new = GF_CALLOC (1, sizeof (struct _lock_table), gf_server_mt_lock_table_t); - if (new == NULL) { - goto out; - } - INIT_LIST_HEAD (&new->entrylk_lockers); - INIT_LIST_HEAD (&new->inodelk_lockers); -out: - return new; + if (state->fd) { + fd_unref(state->fd); + state->fd = NULL; + } + + if (state->params) { + dict_unref(state->params); + state->params = NULL; + } + + if (state->iobref) { + iobref_unref(state->iobref); + state->iobref = NULL; + } + + if (state->iobuf) { + iobuf_unref(state->iobuf); + state->iobuf = NULL; + } + + if (state->dict) { + dict_unref(state->dict); + state->dict = NULL; + } + + if (state->xdata) { + dict_unref(state->xdata); + state->xdata = NULL; + } + + GF_FREE((void *)state->volume); + + GF_FREE((void *)state->name); + + server_loc_wipe(&state->loc); + server_loc_wipe(&state->loc2); + + server_resolve_wipe(&state->resolve); + server_resolve_wipe(&state->resolve2); + + /* Call rpc_trnasport_unref to avoid crashes at last after free + all resources because of server_rpc_notify (for transport destroy) + call's xlator_mem_cleanup if all xprt are destroyed that internally + call's inode_table_destroy. + */ + if (state->xprt) { + rpc_transport_unref(state->xprt); + state->xprt = NULL; + } + + GF_FREE(state); } static int -server_nop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xdata) +server_connection_cleanup_flush_cbk(call_frame_t *frame, void *cookie, + xlator_t *this, int32_t op_ret, + int32_t op_errno, dict_t *xdata) { - int ret = -1; - server_state_t *state = NULL; - - GF_VALIDATE_OR_GOTO ("server", frame, out); - GF_VALIDATE_OR_GOTO ("server", cookie, out); - GF_VALIDATE_OR_GOTO ("server", this, out); - - if (frame->root->trans) - server_conn_unref (frame->root->trans); - state = CALL_STATE(frame); + int32_t ret = -1; + fd_t *fd = NULL; + client_t *client = NULL; + uint64_t fd_cnt = 0; + xlator_t *victim = NULL; + server_conf_t *conf = NULL; + xlator_t *serv_xl = NULL; + rpc_transport_t *xprt = NULL; + rpc_transport_t *xp_next = NULL; + int32_t detach = (long)cookie; + gf_boolean_t xprt_found = _gf_false; + + GF_VALIDATE_OR_GOTO("server", this, out); + GF_VALIDATE_OR_GOTO("server", frame, out); + + fd = frame->local; + client = frame->root->client; + serv_xl = frame->this; + conf = serv_xl->private; + + fd_unref(fd); + frame->local = NULL; + + if (client) + victim = client->bound_xl; + + if (victim) { + fd_cnt = GF_ATOMIC_DEC(client->fd_cnt); + if (!fd_cnt && conf && detach) { + pthread_mutex_lock(&conf->mutex); + { + list_for_each_entry_safe(xprt, xp_next, &conf->xprt_list, list) + { + if (!xprt->xl_private) + continue; + if (xprt->xl_private == client) { + xprt_found = _gf_true; + break; + } + } + } + pthread_mutex_unlock(&conf->mutex); + if (xprt_found) { + rpc_transport_unref(xprt); + } + } + } - if (state) - free_state (state); - STACK_DESTROY (frame->root); + gf_client_unref(client); + STACK_DESTROY(frame->root); - ret = 0; + ret = 0; out: - return ret; + return ret; } -int -do_lock_table_cleanup (xlator_t *this, server_connection_t *conn, - call_frame_t *frame, struct _lock_table *ltable) +static int +do_fd_cleanup(xlator_t *this, client_t *client, fdentry_t *fdentries, + int fd_count, int32_t detach) { - struct list_head inodelk_lockers, entrylk_lockers; - call_frame_t *tmp_frame = NULL; - struct gf_flock flock = {0, }; - xlator_t *bound_xl = NULL; - struct _locker *locker = NULL, *tmp = NULL; - int ret = -1; - char *path = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); - GF_VALIDATE_OR_GOTO ("server", frame, out); - GF_VALIDATE_OR_GOTO ("server", ltable, out); - - bound_xl = conn->bound_xl; - INIT_LIST_HEAD (&inodelk_lockers); - INIT_LIST_HEAD (&entrylk_lockers); - - list_splice_init (<able->inodelk_lockers, - &inodelk_lockers); - - list_splice_init (<able->entrylk_lockers, &entrylk_lockers); - GF_FREE (ltable); - - flock.l_type = F_UNLCK; - flock.l_start = 0; - flock.l_len = 0; - list_for_each_entry_safe (locker, - tmp, &inodelk_lockers, lockers) { - tmp_frame = copy_frame (frame); - if (tmp_frame == NULL) { - goto out; - } - /* - lock owner = 0 is a special case that tells posix-locks - to release all locks from this transport - */ - tmp_frame->root->pid = 0; - tmp_frame->root->trans = server_conn_ref (conn); - memset (&tmp_frame->root->lk_owner, 0, sizeof (gf_lkowner_t)); - - if (locker->fd) { - GF_ASSERT (locker->fd->inode); - - ret = inode_path (locker->fd->inode, NULL, &path); - - if (ret > 0) { - gf_log (this->name, GF_LOG_INFO, "finodelk " - "released on %s", path); - GF_FREE (path); - } else { - - gf_log (this->name, GF_LOG_INFO, "finodelk " - "released on inode with gfid %s", - uuid_utoa (locker->fd->inode->gfid)); - } - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->finodelk, - locker->volume, - locker->fd, F_SETLK, &flock, NULL); - fd_unref (locker->fd); - } else { - gf_log (this->name, GF_LOG_INFO, "inodelk released " - "on %s", locker->loc.path); - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->inodelk, - locker->volume, - &(locker->loc), F_SETLK, &flock, NULL); - loc_wipe (&locker->loc); - } + fd_t *fd = NULL; + int i = 0, ret = -1; + call_frame_t *tmp_frame = NULL; + xlator_t *bound_xl = NULL; + char *path = NULL; - GF_FREE (locker->volume); + GF_VALIDATE_OR_GOTO("server", this, out); + GF_VALIDATE_OR_GOTO("server", fdentries, out); - list_del_init (&locker->lockers); - GF_FREE (locker); - } + bound_xl = client->bound_xl; - tmp = NULL; - locker = NULL; - list_for_each_entry_safe (locker, tmp, &entrylk_lockers, lockers) { - tmp_frame = copy_frame (frame); - - tmp_frame->root->pid = 0; - tmp_frame->root->trans = server_conn_ref (conn); - memset (&tmp_frame->root->lk_owner, 0, sizeof (gf_lkowner_t)); - - if (locker->fd) { - GF_ASSERT (locker->fd->inode); - - ret = inode_path (locker->fd->inode, NULL, &path); - - if (ret > 0) { - gf_log (this->name, GF_LOG_INFO, "fentrylk " - "released on %s", path); - GF_FREE (path); - } else { - - gf_log (this->name, GF_LOG_INFO, "fentrylk " - "released on inode with gfid %s", - uuid_utoa (locker->fd->inode->gfid)); - } - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->fentrylk, - locker->volume, - locker->fd, NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL); - fd_unref (locker->fd); - } else { - gf_log (this->name, GF_LOG_INFO, "entrylk released " - "on %s", locker->loc.path); - - STACK_WIND (tmp_frame, server_nop_cbk, bound_xl, - bound_xl->fops->entrylk, - locker->volume, - &(locker->loc), NULL, - ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL); - loc_wipe (&locker->loc); - } - - GF_FREE (locker->volume); + for (i = 0; i < fd_count; i++) { + fd = fdentries[i].fd; - list_del_init (&locker->lockers); - GF_FREE (locker); + if (fd != NULL) { + tmp_frame = create_frame(this, this->ctx->pool); + if (tmp_frame == NULL) { + goto out; + } + + tmp_frame->root->type = GF_OP_TYPE_FOP; + GF_ASSERT(fd->inode); + + ret = inode_path(fd->inode, NULL, &path); + + if (ret > 0) { + gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FD_CLEANUP, + "path=%s", path, NULL); + GF_FREE(path); + } else { + gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FD_CLEANUP, + "inode-gfid=%s", uuid_utoa(fd->inode->gfid), NULL); + } + + tmp_frame->local = fd; + tmp_frame->root->pid = 0; + gf_client_ref(client); + tmp_frame->root->client = client; + memset(&tmp_frame->root->lk_owner, 0, sizeof(gf_lkowner_t)); + + STACK_WIND_COOKIE(tmp_frame, server_connection_cleanup_flush_cbk, + (void *)(long)detach, bound_xl, + bound_xl->fops->flush, fd, NULL); } - ret = 0; + } + + GF_FREE(fdentries); + ret = 0; out: - return ret; + return ret; } - -static int -server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, - int32_t op_errno, dict_t *xdata) +int +server_connection_cleanup(xlator_t *this, client_t *client, int32_t flags, + gf_boolean_t *fd_exist) { - int32_t ret = -1; - fd_t *fd = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", cookie, out); - GF_VALIDATE_OR_GOTO ("server", frame, out); + server_ctx_t *serv_ctx = NULL; + fdentry_t *fdentries = NULL; + uint32_t fd_count = 0; + int cd_ret = 0; + int ret = 0; + xlator_t *bound_xl = NULL; + int i = 0; + fd_t *fd = NULL; + uint64_t fd_cnt = 0; + int32_t detach = 0; + + GF_VALIDATE_OR_GOTO("server", this, out); + GF_VALIDATE_OR_GOTO(this->name, client, out); + GF_VALIDATE_OR_GOTO(this->name, flags, out); + + serv_ctx = server_ctx_get(client, client->this); + + if (serv_ctx == NULL) { + gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, NULL); + goto out; + } + + LOCK(&serv_ctx->fdtable_lock); + { + if (serv_ctx->fdtable && (flags & POSIX_LOCKS)) + fdentries = gf_fd_fdtable_get_all_fds(serv_ctx->fdtable, &fd_count); + } + UNLOCK(&serv_ctx->fdtable_lock); + + if (client->bound_xl == NULL) + goto out; + + if (flags & INTERNAL_LOCKS) { + cd_ret = gf_client_disconnect(client); + } + + if (fdentries != NULL) { + /* Loop to configure fd_count on victim brick */ + bound_xl = client->bound_xl; + if (bound_xl) { + for (i = 0; i < fd_count; i++) { + fd = fdentries[i].fd; + if (!fd) + continue; + fd_cnt++; + } + if (fd_cnt) { + if (fd_exist) + (*fd_exist) = _gf_true; + GF_ATOMIC_ADD(client->fd_cnt, fd_cnt); + } + } - fd = frame->local; + /* If fd_exist is not NULL it means function is invoke + by server_rpc_notify at the time of getting DISCONNECT + notification + */ + if (fd_exist) + detach = 1; - fd_unref (fd); - frame->local = NULL; + gf_msg_debug(this->name, 0, + "Performing cleanup on %d " + "fdentries", + fd_count); + ret = do_fd_cleanup(this, client, fdentries, fd_count, detach); + } else + gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_FDENTRY_NULL, NULL); - if (frame->root->trans) - server_conn_unref (frame->root->trans); - STACK_DESTROY (frame->root); + if (cd_ret || ret) + ret = -1; - ret = 0; out: - return ret; + return ret; } - -int -do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame, - fdentry_t *fdentries, int fd_count) +static call_frame_t * +server_alloc_frame(rpcsvc_request_t *req) { - fd_t *fd = NULL; - int i = 0, ret = -1; - call_frame_t *tmp_frame = NULL; - xlator_t *bound_xl = NULL; - char *path = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); - GF_VALIDATE_OR_GOTO ("server", frame, out); - GF_VALIDATE_OR_GOTO ("server", fdentries, out); - - bound_xl = conn->bound_xl; - for (i = 0;i < fd_count; i++) { - fd = fdentries[i].fd; + call_frame_t *frame = NULL; + server_state_t *state = NULL; + client_t *client = NULL; - if (fd != NULL) { - tmp_frame = copy_frame (frame); - if (tmp_frame == NULL) { - goto out; - } + GF_VALIDATE_OR_GOTO("server", req, out); + GF_VALIDATE_OR_GOTO("server", req->trans, out); + GF_VALIDATE_OR_GOTO("server", req->svc, out); + GF_VALIDATE_OR_GOTO("server", req->svc->ctx, out); - GF_ASSERT (fd->inode); + client = req->trans->xl_private; + GF_VALIDATE_OR_GOTO("server", client, out); - ret = inode_path (fd->inode, NULL, &path); + frame = create_frame(client->this, req->svc->ctx->pool); + if (!frame) + goto out; - if (ret > 0) { - gf_log (this->name, GF_LOG_INFO, "fd cleanup on " - "%s", path); - GF_FREE (path); - } else { + frame->root->type = GF_OP_TYPE_FOP; + state = GF_CALLOC(1, sizeof(*state), gf_server_mt_state_t); + if (!state) + goto out; - gf_log (this->name, GF_LOG_INFO, "fd cleanup on" - " inode with gfid %s", - uuid_utoa (fd->inode->gfid)); - } + if (client->bound_xl) + state->itable = client->bound_xl->itable; - tmp_frame->local = fd; + state->xprt = rpc_transport_ref(req->trans); + state->resolve.fd_no = -1; + state->resolve2.fd_no = -1; - tmp_frame->root->pid = 0; - tmp_frame->root->trans = server_conn_ref (conn); - memset (&tmp_frame->root->lk_owner, 0, - sizeof (gf_lkowner_t)); - - STACK_WIND (tmp_frame, - server_connection_cleanup_flush_cbk, - bound_xl, bound_xl->fops->flush, fd, NULL); - } - } + frame->root->client = client; + frame->root->state = state; /* which socket */ - GF_FREE (fdentries); - ret = 0; + frame->this = client->this; +out: + return frame; +} +call_frame_t * +get_frame_from_request(rpcsvc_request_t *req) +{ + call_frame_t *frame = NULL; + client_t *client = NULL; + client_t *tmp_client = NULL; + xlator_t *this = NULL; + server_conf_t *priv = NULL; + clienttable_t *clienttable = NULL; + unsigned int i = 0; + rpc_transport_t *trans = NULL; + server_state_t *state = NULL; + + GF_VALIDATE_OR_GOTO("server", req, out); + + frame = server_alloc_frame(req); + if (!frame) + goto out; + + frame->root->op = req->procnum; + + client = req->trans->xl_private; + this = req->trans->xl; + priv = this->private; + clienttable = this->ctx->clienttable; + + for (i = 0; i < clienttable->max_clients; i++) { + tmp_client = clienttable->cliententries[i].client; + if (client == tmp_client) { + /* for non trusted clients username and password + would not have been set. So for non trusted clients + (i.e clients not from the same machine as the brick, + and clients from outside the storage pool) + do the root-squashing and all-squashing. + TODO: If any client within the storage pool (i.e + mounting within a machine from the pool but using + other machine's ip/hostname from the same pool) + is present treat it as a trusted client + */ + if (!client->auth.username && req->pid != NFS_PID) { + RPC_AUTH_ROOT_SQUASH(req); + RPC_AUTH_ALL_SQUASH(req); + } + + /* Problem: If we just check whether the client is + trusted client and do not do root squashing and + all squashing for them, then for smb clients and + UFO clients root squashing and all squashing will + never happen as they use the fuse mounts done within + the trusted pool (i.e they are trusted clients). + Solution: To fix it, do root squashing and all squashing + for trusted clients also. If one wants to have a client + within the storage pool for which root-squashing does + not happen, then the client has to be mounted with + --no-root-squash option. But for defrag client and + gsyncd client do not do root-squashing and all-squashing. + */ + if (client->auth.username && + req->pid != GF_CLIENT_PID_NO_ROOT_SQUASH && + req->pid != GF_CLIENT_PID_GSYNCD && + req->pid != GF_CLIENT_PID_DEFRAG && + req->pid != GF_CLIENT_PID_SELF_HEALD && + req->pid != GF_CLIENT_PID_QUOTA_MOUNT) { + RPC_AUTH_ROOT_SQUASH(req); + RPC_AUTH_ALL_SQUASH(req); + } + + /* For nfs clients the server processes will be running + within the trusted storage pool machines. So if we + do not do root-squashing and all-squashing for nfs + servers, thinking that its a trusted client, then + root-squashing and all-squashing won't work for nfs + clients. + */ + if (req->pid == NFS_PID) { + RPC_AUTH_ROOT_SQUASH(req); + RPC_AUTH_ALL_SQUASH(req); + } + } + } + + /* Add a ref for this fop */ + if (client) + gf_client_ref(client); + + frame->root->uid = req->uid; + frame->root->gid = req->gid; + frame->root->pid = req->pid; + frame->root->client = client; + frame->root->lk_owner = req->lk_owner; + + if (priv->server_manage_gids) + server_resolve_groups(frame, req); + else + server_decode_groups(frame, req); + trans = req->trans; + if (trans) { + memcpy(&frame->root->identifier, trans->peerinfo.identifier, + sizeof(trans->peerinfo.identifier)); + } + + /* more fields, for the clients which are 3.x series this will be 0 */ + frame->root->flags = req->flags; + frame->root->ctime = req->ctime; + + frame->local = req; + + state = CALL_STATE(frame); + state->client = client; out: - return ret; + return frame; } int -do_connection_cleanup (xlator_t *this, server_connection_t *conn, - struct _lock_table *ltable, fdentry_t *fdentries, int fd_count) +server_build_config(xlator_t *this, server_conf_t *conf) { - int ret = 0; - int saved_ret = 0; - call_frame_t *frame = NULL; - server_state_t *state = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); - - if (!ltable && !fdentries) - goto out; - - frame = create_frame (this, this->ctx->pool); - if (frame == NULL) { - goto out; + data_t *data = NULL; + int ret = -1; + struct stat buf = { + 0, + }; + + GF_VALIDATE_OR_GOTO("server", this, out); + GF_VALIDATE_OR_GOTO("server", conf, out); + + ret = dict_get_int32(this->options, "inode-lru-limit", + &conf->inode_lru_limit); + if (ret < 0) { + conf->inode_lru_limit = 16384; + } + + conf->verify_volfile = 1; + data = dict_get(this->options, "verify-volfile-checksum"); + if (data) { + ret = gf_string2boolean(data->data, &conf->verify_volfile); + if (ret != 0) { + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_WRONG_VALUE, + NULL); } - - if (ltable) - saved_ret = do_lock_table_cleanup (this, conn, frame, ltable); - - if (fdentries != NULL) { - ret = do_fd_cleanup (this, conn, frame, fdentries, fd_count); + } + + data = dict_get(this->options, "trace"); + if (data) { + ret = gf_string2boolean(data->data, &conf->trace); + if (ret != 0) { + gf_smsg(this->name, GF_LOG_WARNING, EINVAL, PS_MSG_INVALID_ENTRY, + NULL); } - - state = CALL_STATE (frame); - if (state) - GF_FREE (state); - - STACK_DESTROY (frame->root); - - if (saved_ret || ret) { - ret = -1; + } + + /* TODO: build_rpc_config (); */ + ret = dict_get_int32(this->options, "limits.transaction-size", + &conf->rpc_conf.max_block_size); + if (ret < 0) { + gf_msg_trace(this->name, 0, + "defaulting limits.transaction-" + "size to %d", + DEFAULT_BLOCK_SIZE); + conf->rpc_conf.max_block_size = DEFAULT_BLOCK_SIZE; + } + + data = dict_get(this->options, "config-directory"); + if (data) { + /* Check whether the specified directory exists, + or directory specified is non standard */ + ret = sys_stat(data->data, &buf); + if ((ret != 0) || !S_ISDIR(buf.st_mode)) { + gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_DIR_NOT_FOUND, + "data=%s", data->data, NULL); + ret = -1; + goto out; + } + /* Make sure that conf-dir doesn't contain ".." in path */ + if ((gf_strstr(data->data, "/", "..")) == -1) { + ret = -1; + gf_smsg(this->name, GF_LOG_ERROR, 0, PS_MSG_CONF_DIR_INVALID, + "data=%s", data->data, NULL); + goto out; } + conf->conf_dir = gf_strdup(data->data); + } + ret = 0; out: - return ret; + return ret; } - -int -server_connection_cleanup (xlator_t *this, server_connection_t *conn, - int32_t flags) +void +print_caller(char *str, int size, call_frame_t *frame) { - struct _lock_table *ltable = NULL; - fdentry_t *fdentries = NULL; - uint32_t fd_count = 0; - int ret = 0; + server_state_t *state = NULL; - GF_VALIDATE_OR_GOTO (this->name, this, out); - GF_VALIDATE_OR_GOTO (this->name, conn, out); - GF_VALIDATE_OR_GOTO (this->name, flags, out); + GF_VALIDATE_OR_GOTO("server", str, out); + GF_VALIDATE_OR_GOTO("server", frame, out); - pthread_mutex_lock (&conn->lock); - { - if (conn->ltable && (flags & INTERNAL_LOCKS)) { - ltable = conn->ltable; - conn->ltable = gf_lock_table_new (); - } - - if (conn->fdtable && (flags & POSIX_LOCKS)) - fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable, - &fd_count); - } - pthread_mutex_unlock (&conn->lock); + state = CALL_STATE(frame); - if (conn->bound_xl) - ret = do_connection_cleanup (this, conn, ltable, - fdentries, fd_count); + snprintf(str, size, " Callid=%" PRId64 ", Client=%s", frame->root->unique, + state->xprt->peerinfo.identifier); out: - return ret; + return; } - -int -server_connection_destroy (xlator_t *this, server_connection_t *conn) +void +server_print_resolve(char *str, int size, server_resolve_t *resolve) { - xlator_t *bound_xl = NULL; - int32_t ret = -1; - struct list_head inodelk_lockers; - struct list_head entrylk_lockers; - struct _lock_table *ltable = NULL; - fdtable_t *fdtable = NULL; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conn, out); + int filled = 0; - bound_xl = (xlator_t *) (conn->bound_xl); + GF_VALIDATE_OR_GOTO("server", str, out); - if (bound_xl) { - pthread_mutex_lock (&(conn->lock)); - { - if (conn->ltable) { - ltable = conn->ltable; - conn->ltable = NULL; - } - if (conn->fdtable) { - fdtable = conn->fdtable; - conn->fdtable = NULL; - } - } - pthread_mutex_unlock (&conn->lock); + if (!resolve) { + snprintf(str, size, "<nul>"); + return; + } + + filled += snprintf(str + filled, size - filled, " Resolve={"); + if (resolve->fd_no != -1) + filled += snprintf(str + filled, size - filled, "fd=%" PRId64 ",", + (uint64_t)resolve->fd_no); + if (resolve->bname) + filled += snprintf(str + filled, size - filled, "bname=%s,", + resolve->bname); + if (resolve->path) + filled += snprintf(str + filled, size - filled, "path=%s", + resolve->path); + + snprintf(str + filled, size - filled, "}"); +out: + return; +} - INIT_LIST_HEAD (&inodelk_lockers); - INIT_LIST_HEAD (&entrylk_lockers); +void +server_print_loc(char *str, int size, loc_t *loc) +{ + int filled = 0; - if (ltable) { - list_splice_init (<able->inodelk_lockers, - &inodelk_lockers); + GF_VALIDATE_OR_GOTO("server", str, out); - list_splice_init (<able->entrylk_lockers, - &entrylk_lockers); - GF_FREE (ltable); - } + if (!loc) { + snprintf(str, size, "<nul>"); + return; + } - GF_ASSERT (list_empty (&inodelk_lockers)); - GF_ASSERT (list_empty (&entrylk_lockers)); + filled += snprintf(str + filled, size - filled, " Loc={"); - if (fdtable) - gf_fd_fdtable_destroy (fdtable); - } + if (loc->path) + filled += snprintf(str + filled, size - filled, "path=%s,", loc->path); + if (loc->inode) + filled += snprintf(str + filled, size - filled, "inode=%p,", + loc->inode); + if (loc->parent) + filled += snprintf(str + filled, size - filled, "parent=%p", + loc->parent); - gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s", - conn->id); + snprintf(str + filled, size - filled, "}"); +out: + return; +} - pthread_mutex_destroy (&conn->lock); - GF_FREE (conn->id); - GF_FREE (conn); - ret = 0; +void +server_print_params(char *str, int size, server_state_t *state) +{ + int filled = 0; + + GF_VALIDATE_OR_GOTO("server", str, out); + + filled += snprintf(str + filled, size - filled, " Params={"); + + if (state->fd) + filled += snprintf(str + filled, size - filled, "fd=%p,", state->fd); + if (state->valid) + filled += snprintf(str + filled, size - filled, "valid=%d,", + state->valid); + if (state->flags) + filled += snprintf(str + filled, size - filled, "flags=%d,", + state->flags); + if (state->wbflags) + filled += snprintf(str + filled, size - filled, "wbflags=%d,", + state->wbflags); + if (state->size) + filled += snprintf(str + filled, size - filled, "size=%zu,", + state->size); + if (state->offset) + filled += snprintf(str + filled, size - filled, "offset=%" PRId64 ",", + state->offset); + if (state->cmd) + filled += snprintf(str + filled, size - filled, "cmd=%d,", state->cmd); + if (state->type) + filled += snprintf(str + filled, size - filled, "type=%d,", + state->type); + if (state->name) + filled += snprintf(str + filled, size - filled, "name=%s,", + state->name); + if (state->mask) + filled += snprintf(str + filled, size - filled, "mask=%d,", + state->mask); + if (state->volume) + filled += snprintf(str + filled, size - filled, "volume=%s,", + state->volume); + +/* FIXME + snprintf (str + filled, size - filled, + "bound_xl=%s}", state->client->bound_xl->name); +*/ out: - return ret; + return; } -server_connection_t* -server_conn_unref (server_connection_t *conn) +int +server_resolve_is_empty(server_resolve_t *resolve) { - server_connection_t *todel = NULL; - xlator_t *this = NULL; + if (resolve->fd_no != -1) + return 0; - pthread_mutex_lock (&conn->lock); - { - conn->ref--; + if (resolve->path != 0) + return 0; - if (!conn->ref) { - todel = conn; - } - } - pthread_mutex_unlock (&conn->lock); + if (resolve->bname != 0) + return 0; - if (todel) { - this = THIS; - server_connection_destroy (this, todel); - conn = NULL; - } - return conn; + return 1; } -server_connection_t* -server_conn_ref (server_connection_t *conn) +void +server_print_reply(call_frame_t *frame, int op_ret, int op_errno) { - pthread_mutex_lock (&conn->lock); - { - conn->ref++; - } - pthread_mutex_unlock (&conn->lock); + server_conf_t *conf = NULL; + server_state_t *state = NULL; + xlator_t *this = NULL; + char caller[512]; + char fdstr[32]; + char *op = "UNKNOWN"; - return conn; -} + GF_VALIDATE_OR_GOTO("server", frame, out); -server_connection_t * -server_connection_get (xlator_t *this, const char *id) -{ - server_connection_t *conn = NULL; - server_connection_t *trav = NULL; - server_conf_t *conf = NULL; + this = frame->this; + conf = this->private; - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", id, out); + GF_VALIDATE_OR_GOTO("server", conf, out); + GF_VALIDATE_OR_GOTO("server", conf->trace, out); - conf = this->private; + state = CALL_STATE(frame); - pthread_mutex_lock (&conf->mutex); - { - list_for_each_entry (trav, &conf->conns, list) { - if (!strncmp (trav->id, id, strlen (id))) { - conn = trav; - conn->bind_ref++; - goto unlock; - } - } + print_caller(caller, 256, frame); + + switch (frame->root->type) { + case GF_OP_TYPE_FOP: + op = (char *)gf_fop_list[frame->root->op]; + break; + default: + op = ""; + } - conn = (void *) GF_CALLOC (1, sizeof (*conn), - gf_server_mt_conn_t); - if (!conn) - goto unlock; - - conn->id = gf_strdup (id); - /*'0' denotes uninitialised lock state*/ - conn->lk_version = 0; - conn->fdtable = gf_fd_fdtable_alloc (); - conn->ltable = gf_lock_table_new (); - conn->this = this; - conn->bind_ref = 1; - conn->ref = 1;//when bind_ref becomes 0 it calls conn_unref - pthread_mutex_init (&conn->lock, NULL); - list_add (&conn->list, &conf->conns); + fdstr[0] = '\0'; + if (state->fd) + snprintf(fdstr, 32, " fd=%p", state->fd); - } -unlock: - pthread_mutex_unlock (&conf->mutex); + gf_smsg(this->name, GF_LOG_INFO, op_errno, PS_MSG_SERVER_MSG, "op=%s", op, + "caller=%s", caller, "op_ret=%d", op_ret, "op_errno=%d", op_errno, + "fdstr=%s", fdstr, NULL); out: - return conn; + return; } -server_connection_t* -server_connection_put (xlator_t *this, server_connection_t *conn, - gf_boolean_t *detached) +void +server_print_request(call_frame_t *frame) { - server_conf_t *conf = NULL; - gf_boolean_t unref = _gf_false; + server_conf_t *conf = NULL; + xlator_t *this = NULL; + server_state_t *state = NULL; + char *op = "UNKNOWN"; + char resolve_vars[256]; + char resolve2_vars[256]; + char loc_vars[256]; + char loc2_vars[256]; + char other_vars[512]; + char caller[512]; - if (detached) - *detached = _gf_false; - conf = this->private; - pthread_mutex_lock (&conf->mutex); - { - conn->bind_ref--; - if (!conn->bind_ref) { - list_del_init (&conn->list); - unref = _gf_true; - } - } - pthread_mutex_unlock (&conf->mutex); - if (unref) { - gf_log (this->name, GF_LOG_INFO, "Shutting down connection %s", - conn->id); - if (detached) - *detached = _gf_true; - server_conn_unref (conn); - conn = NULL; - } - return conn; -} + GF_VALIDATE_OR_GOTO("server", frame, out); -static call_frame_t * -server_alloc_frame (rpcsvc_request_t *req) -{ - call_frame_t *frame = NULL; - server_state_t *state = NULL; - server_connection_t *conn = NULL; + this = frame->this; + conf = this->private; - GF_VALIDATE_OR_GOTO ("server", req, out); - GF_VALIDATE_OR_GOTO ("server", req->trans, out); - GF_VALIDATE_OR_GOTO ("server", req->svc, out); - GF_VALIDATE_OR_GOTO ("server", req->svc->ctx, out); + GF_VALIDATE_OR_GOTO("server", conf, out); - conn = (server_connection_t *)req->trans->xl_private; - GF_VALIDATE_OR_GOTO ("server", conn, out); + if (!conf->trace) + goto out; - frame = create_frame (conn->this, req->svc->ctx->pool); - if (!frame) - goto out; + state = CALL_STATE(frame); - state = GF_CALLOC (1, sizeof (*state), gf_server_mt_state_t); - if (!state) - goto out; + memset(resolve_vars, '\0', 256); + memset(resolve2_vars, '\0', 256); + memset(loc_vars, '\0', 256); + memset(loc2_vars, '\0', 256); + memset(other_vars, '\0', 256); - if (conn->bound_xl) - state->itable = conn->bound_xl->itable; + print_caller(caller, 256, frame); - state->xprt = rpc_transport_ref (req->trans); - state->conn = conn; + if (!server_resolve_is_empty(&state->resolve)) { + server_print_resolve(resolve_vars, 256, &state->resolve); + server_print_loc(loc_vars, 256, &state->loc); + } - state->resolve.fd_no = -1; - state->resolve2.fd_no = -1; + if (!server_resolve_is_empty(&state->resolve2)) { + server_print_resolve(resolve2_vars, 256, &state->resolve2); + server_print_loc(loc2_vars, 256, &state->loc2); + } - frame->root->state = state; /* which socket */ - frame->root->unique = 0; /* which call */ + server_print_params(other_vars, 512, state); - frame->this = conn->this; + switch (frame->root->type) { + case GF_OP_TYPE_FOP: + op = (char *)gf_fop_list[frame->root->op]; + break; + default: + op = ""; + break; + } + + gf_smsg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_MSG, "op=%s", op, + "caller=%s", caller, "resolve_vars=%s", resolve_vars, "loc_vars=%s", + loc_vars, "resolve2_vars=%s", resolve2_vars, "loc2_vars=%s", + loc2_vars, "other_vars=%s", other_vars, NULL); out: - return frame; + return; } - - -call_frame_t * -get_frame_from_request (rpcsvc_request_t *req) +int +serialize_rsp_direntp(gf_dirent_t *entries, gfs3_readdirp_rsp *rsp) { - call_frame_t *frame = NULL; - - GF_VALIDATE_OR_GOTO ("server", req, out); - - frame = server_alloc_frame (req); - if (!frame) + gf_dirent_t *entry = NULL; + gfs3_dirplist *trav = NULL; + gfs3_dirplist *prev = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO("server", entries, out); + GF_VALIDATE_OR_GOTO("server", rsp, out); + + list_for_each_entry(entry, &entries->list, list) + { + trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_dirent_rsp_t); + if (!trav) + goto out; + + trav->d_ino = entry->d_ino; + trav->d_off = entry->d_off; + trav->d_len = entry->d_len; + trav->d_type = entry->d_type; + trav->name = entry->d_name; + + gf_stat_from_iatt(&trav->stat, &entry->d_stat); + + /* if 'dict' is present, pack it */ + if (entry->dict) { + ret = dict_allocate_and_serialize(entry->dict, + (char **)&trav->dict.dict_val, + &trav->dict.dict_len); + if (ret != 0) { + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_DICT_SERIALIZE_FAIL, + NULL); + errno = -ret; + trav->dict.dict_len = 0; goto out; + } + } - frame->root->op = req->procnum; - frame->root->type = req->type; - - frame->root->unique = req->xid; - - frame->root->uid = req->uid; - frame->root->gid = req->gid; - frame->root->pid = req->pid; - frame->root->trans = server_conn_ref (req->trans->xl_private); - frame->root->lk_owner = req->lk_owner; + if (prev) + prev->nextentry = trav; + else + rsp->reply = trav; - server_decode_groups (frame, req); + prev = trav; + trav = NULL; + } - frame->local = req; + ret = 0; out: - return frame; -} + GF_FREE(trav); + return ret; +} int -server_build_config (xlator_t *this, server_conf_t *conf) +serialize_rsp_direntp_v2(gf_dirent_t *entries, gfx_readdirp_rsp *rsp) { - data_t *data = NULL; - int ret = -1; - struct stat buf = {0,}; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", conf, out); + gf_dirent_t *entry = NULL; + gfx_dirplist *trav = NULL; + gfx_dirplist *prev = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO("server", entries, out); + GF_VALIDATE_OR_GOTO("server", rsp, out); + + list_for_each_entry(entry, &entries->list, list) + { + trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_dirent_rsp_t); + if (!trav) + goto out; + + trav->d_ino = entry->d_ino; + trav->d_off = entry->d_off; + trav->d_len = entry->d_len; + trav->d_type = entry->d_type; + trav->name = entry->d_name; + + gfx_stat_from_iattx(&trav->stat, &entry->d_stat); + dict_to_xdr(entry->dict, &trav->dict); + + if (prev) + prev->nextentry = trav; + else + rsp->reply = trav; - ret = dict_get_int32 (this->options, "inode-lru-limit", - &conf->inode_lru_limit); - if (ret < 0) { - conf->inode_lru_limit = 16384; - } + prev = trav; + trav = NULL; + } - conf->verify_volfile = 1; - data = dict_get (this->options, "verify-volfile-checksum"); - if (data) { - ret = gf_string2boolean(data->data, &conf->verify_volfile); - if (ret != 0) { - gf_log (this->name, GF_LOG_WARNING, - "wrong value for 'verify-volfile-checksum', " - "Neglecting option"); - } - } + ret = 0; +out: + GF_FREE(trav); - data = dict_get (this->options, "trace"); - if (data) { - ret = gf_string2boolean (data->data, &conf->trace); - if (ret != 0) { - gf_log (this->name, GF_LOG_WARNING, - "'trace' takes on only boolean values. " - "Neglecting option"); - } - } + return ret; +} - /* TODO: build_rpc_config (); */ - ret = dict_get_int32 (this->options, "limits.transaction-size", - &conf->rpc_conf.max_block_size); - if (ret < 0) { - gf_log (this->name, GF_LOG_TRACE, - "defaulting limits.transaction-size to %d", - DEFAULT_BLOCK_SIZE); - conf->rpc_conf.max_block_size = DEFAULT_BLOCK_SIZE; - } +int +serialize_rsp_dirent(gf_dirent_t *entries, gfs3_readdir_rsp *rsp) +{ + gf_dirent_t *entry = NULL; + gfs3_dirlist *trav = NULL; + gfs3_dirlist *prev = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO("server", rsp, out); + GF_VALIDATE_OR_GOTO("server", entries, out); + + list_for_each_entry(entry, &entries->list, list) + { + trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_dirent_rsp_t); + if (!trav) + goto out; + trav->d_ino = entry->d_ino; + trav->d_off = entry->d_off; + trav->d_len = entry->d_len; + trav->d_type = entry->d_type; + trav->name = entry->d_name; + if (prev) + prev->nextentry = trav; + else + rsp->reply = trav; - data = dict_get (this->options, "config-directory"); - if (data) { - /* Check whether the specified directory exists, - or directory specified is non standard */ - ret = stat (data->data, &buf); - if ((ret != 0) || !S_ISDIR (buf.st_mode)) { - gf_log (this->name, GF_LOG_ERROR, - "Directory '%s' doesn't exist, exiting.", - data->data); - ret = -1; - goto out; - } - /* Make sure that conf-dir doesn't contain ".." in path */ - if ((gf_strstr (data->data, "/", "..")) == -1) { - ret = -1; - gf_log (this->name, GF_LOG_ERROR, - "%s: invalid conf_dir", data->data); - goto out; - } + prev = trav; + } - conf->conf_dir = gf_strdup (data->data); - } - ret = 0; + ret = 0; out: - return ret; + return ret; } -void -put_server_conn_state (xlator_t *this, rpc_transport_t *xprt) +int +serialize_rsp_dirent_v2(gf_dirent_t *entries, gfx_readdir_rsp *rsp) { - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", xprt, out); + gf_dirent_t *entry = NULL; + gfx_dirlist *trav = NULL; + gfx_dirlist *prev = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO("server", rsp, out); + GF_VALIDATE_OR_GOTO("server", entries, out); + + list_for_each_entry(entry, &entries->list, list) + { + trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_dirent_rsp_t); + if (!trav) + goto out; + trav->d_ino = entry->d_ino; + trav->d_off = entry->d_off; + trav->d_len = entry->d_len; + trav->d_type = entry->d_type; + trav->name = entry->d_name; + if (prev) + prev->nextentry = trav; + else + rsp->reply = trav; - xprt->xl_private = NULL; + prev = trav; + } + + ret = 0; out: - return; + return ret; } -server_connection_t * -get_server_conn_state (xlator_t *this, rpc_transport_t *xprt) +int +readdir_rsp_cleanup(gfs3_readdir_rsp *rsp) { - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", xprt, out); + gfs3_dirlist *prev = NULL; + gfs3_dirlist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + GF_FREE(prev); + prev = trav; + } - return (server_connection_t *)xprt->xl_private; -out: - return NULL; + return 0; } -server_connection_t * -create_server_conn_state (xlator_t *this, rpc_transport_t *xprt) +int +readdirp_rsp_cleanup(gfs3_readdirp_rsp *rsp) { - server_connection_t *conn = NULL; - int ret = -1; - - GF_VALIDATE_OR_GOTO ("server", this, out); - GF_VALIDATE_OR_GOTO ("server", xprt, out); - - conn = GF_CALLOC (1, sizeof (*conn), gf_server_mt_conn_t); - if (!conn) - goto out; - - pthread_mutex_init (&conn->lock, NULL); - - conn->fdtable = gf_fd_fdtable_alloc (); - if (!conn->fdtable) - goto out; - - conn->ltable = gf_lock_table_new (); - if (!conn->ltable) - goto out; - - conn->this = this; - - xprt->xl_private = conn; - - ret = 0; -out: - if (ret) - destroy_server_conn_state (conn); + gfs3_dirplist *prev = NULL; + gfs3_dirplist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + GF_FREE(prev->dict.dict_val); + GF_FREE(prev); + prev = trav; + } - return conn; + return 0; } -void -destroy_server_conn_state (server_connection_t *conn) +int +readdir_rsp_cleanup_v2(gfx_readdir_rsp *rsp) { - GF_VALIDATE_OR_GOTO ("server", conn, out); - - if (conn->ltable) { - /* TODO */ - //FREE (conn->ltable); - ; - } - - if (conn->fdtable) - gf_fd_fdtable_destroy (conn->fdtable); - - pthread_mutex_destroy (&conn->lock); + gfx_dirlist *prev = NULL; + gfx_dirlist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + GF_FREE(prev); + prev = trav; + } - GF_FREE (conn); -out: - return; + return 0; } - -void -print_caller (char *str, int size, call_frame_t *frame) +int +readdirp_rsp_cleanup_v2(gfx_readdirp_rsp *rsp) { - server_state_t *state = NULL; - - GF_VALIDATE_OR_GOTO ("server", str, out); - GF_VALIDATE_OR_GOTO ("server", frame, out); - - state = CALL_STATE (frame); - - snprintf (str, size, - " Callid=%"PRId64", Client=%s", - frame->root->unique, - state->xprt->peerinfo.identifier); + gfx_dirplist *prev = NULL; + gfx_dirplist *trav = NULL; + + trav = rsp->reply; + prev = trav; + while (trav) { + trav = trav->nextentry; + GF_FREE(prev->dict.pairs.pairs_val); + GF_FREE(prev); + prev = trav; + } -out: - return; + return 0; } - -void -server_print_resolve (char *str, int size, server_resolve_t *resolve) +static int +common_rsp_locklist(lock_migration_info_t *locklist, gfs3_locklist **reply) { - int filled = 0; - - GF_VALIDATE_OR_GOTO ("server", str, out); + lock_migration_info_t *tmp = NULL; + gfs3_locklist *trav = NULL; + gfs3_locklist *prev = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO("server", locklist, out); + + list_for_each_entry(tmp, &locklist->list, list) + { + trav = GF_CALLOC(1, sizeof(*trav), gf_server_mt_lock_mig_t); + if (!trav) + goto out; + + switch (tmp->flock.l_type) { + case F_RDLCK: + tmp->flock.l_type = GF_LK_F_RDLCK; + break; + case F_WRLCK: + tmp->flock.l_type = GF_LK_F_WRLCK; + break; + case F_UNLCK: + tmp->flock.l_type = GF_LK_F_UNLCK; + break; - if (!resolve) { - snprintf (str, size, "<nul>"); - return; + default: + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_LOCK_ERROR, + "lock_type=%" PRId32, tmp->flock.l_type, NULL); + break; } - filled += snprintf (str + filled, size - filled, - " Resolve={"); - if (resolve->fd_no != -1) - filled += snprintf (str + filled, size - filled, - "fd=%"PRId64",", (uint64_t) resolve->fd_no); - if (resolve->bname) - filled += snprintf (str + filled, size - filled, - "bname=%s,", resolve->bname); - if (resolve->path) - filled += snprintf (str + filled, size - filled, - "path=%s", resolve->path); - - snprintf (str + filled, size - filled, "}"); -out: - return; -} + gf_proto_flock_from_flock(&trav->flock, &tmp->flock); + trav->lk_flags = tmp->lk_flags; -void -server_print_loc (char *str, int size, loc_t *loc) -{ - int filled = 0; + trav->client_uid = tmp->client_uid; - GF_VALIDATE_OR_GOTO ("server", str, out); - - if (!loc) { - snprintf (str, size, "<nul>"); - return; - } + if (prev) + prev->nextentry = trav; + else + *reply = trav; - filled += snprintf (str + filled, size - filled, - " Loc={"); - - if (loc->path) - filled += snprintf (str + filled, size - filled, - "path=%s,", loc->path); - if (loc->inode) - filled += snprintf (str + filled, size - filled, - "inode=%p,", loc->inode); - if (loc->parent) - filled += snprintf (str + filled, size - filled, - "parent=%p", loc->parent); + prev = trav; + trav = NULL; + } - snprintf (str + filled, size - filled, "}"); + ret = 0; out: - return; + GF_FREE(trav); + return ret; } +int +serialize_rsp_locklist(lock_migration_info_t *locklist, + gfs3_getactivelk_rsp *rsp) +{ + int ret = 0; -void -server_print_params (char *str, int size, server_state_t *state) + GF_VALIDATE_OR_GOTO("server", rsp, out); + ret = common_rsp_locklist(locklist, &rsp->reply); +out: + return ret; +} +int +serialize_rsp_locklist_v2(lock_migration_info_t *locklist, + gfx_getactivelk_rsp *rsp) { - int filled = 0; - - GF_VALIDATE_OR_GOTO ("server", str, out); - - filled += snprintf (str + filled, size - filled, - " Params={"); - - if (state->fd) - filled += snprintf (str + filled, size - filled, - "fd=%p,", state->fd); - if (state->valid) - filled += snprintf (str + filled, size - filled, - "valid=%d,", state->valid); - if (state->flags) - filled += snprintf (str + filled, size - filled, - "flags=%d,", state->flags); - if (state->wbflags) - filled += snprintf (str + filled, size - filled, - "wbflags=%d,", state->wbflags); - if (state->size) - filled += snprintf (str + filled, size - filled, - "size=%zu,", state->size); - if (state->offset) - filled += snprintf (str + filled, size - filled, - "offset=%"PRId64",", state->offset); - if (state->cmd) - filled += snprintf (str + filled, size - filled, - "cmd=%d,", state->cmd); - if (state->type) - filled += snprintf (str + filled, size - filled, - "type=%d,", state->type); - if (state->name) - filled += snprintf (str + filled, size - filled, - "name=%s,", state->name); - if (state->mask) - filled += snprintf (str + filled, size - filled, - "mask=%d,", state->mask); - if (state->volume) - filled += snprintf (str + filled, size - filled, - "volume=%s,", state->volume); + int ret = 0; - snprintf (str + filled, size - filled, - "bound_xl=%s}", state->conn->bound_xl->name); + GF_VALIDATE_OR_GOTO("server", rsp, out); + ret = common_rsp_locklist(locklist, &rsp->reply); out: - return; + return ret; } int -server_resolve_is_empty (server_resolve_t *resolve) +getactivelkinfo_rsp_cleanup(gfs3_getactivelk_rsp *rsp) { - if (resolve->fd_no != -1) - return 0; + gfs3_locklist *prev = NULL; + gfs3_locklist *trav = NULL; - if (resolve->path != 0) - return 0; + trav = rsp->reply; + prev = trav; - if (resolve->bname != 0) - return 0; + while (trav) { + trav = trav->nextentry; + GF_FREE(prev); + prev = trav; + } - return 1; + return 0; } - -void -server_print_reply (call_frame_t *frame, int op_ret, int op_errno) +int +getactivelkinfo_rsp_cleanup_v2(gfx_getactivelk_rsp *rsp) { - server_conf_t *conf = NULL; - server_state_t *state = NULL; - xlator_t *this = NULL; - char caller[512]; - char fdstr[32]; - char *op = "UNKNOWN"; + gfs3_locklist *prev = NULL; + gfs3_locklist *trav = NULL; - GF_VALIDATE_OR_GOTO ("server", frame, out); + trav = rsp->reply; + prev = trav; - this = frame->this; - conf = this->private; + while (trav) { + trav = trav->nextentry; + GF_FREE(prev); + prev = trav; + } - GF_VALIDATE_OR_GOTO ("server", conf, out); - GF_VALIDATE_OR_GOTO ("server", conf->trace, out); + return 0; +} - state = CALL_STATE (frame); +int +gf_server_check_getxattr_cmd(call_frame_t *frame, const char *key) +{ + server_conf_t *conf = NULL; + rpc_transport_t *xprt = NULL; - print_caller (caller, 256, frame); + conf = frame->this->private; + if (!conf) + return 0; - switch (frame->root->type) { - case GF_OP_TYPE_FOP: - op = gf_fop_list[frame->root->op]; - break; - case GF_OP_TYPE_MGMT: - op = gf_mgmt_list[frame->root->op]; - break; - default: - op = ""; + if (fnmatch("*list*mount*point*", key, 0) == 0) { + /* list all the client protocol connecting to this process */ + pthread_mutex_lock(&conf->mutex); + { + list_for_each_entry(xprt, &conf->xprt_list, list) + { + gf_smsg("mount-point-list", GF_LOG_INFO, 0, + PS_MSG_MOUNT_PT_FAIL, "identifier=%s", + xprt->peerinfo.identifier, NULL); + } } + pthread_mutex_unlock(&conf->mutex); + } - fdstr[0] = '\0'; - if (state->fd) - snprintf (fdstr, 32, " fd=%p", state->fd); + /* Add more options/keys here */ - gf_log (this->name, GF_LOG_INFO, - "%s%s => (%d, %d)%s", - op, caller, op_ret, op_errno, fdstr); -out: - return; + return 0; } - -void -server_print_request (call_frame_t *frame) +int +gf_server_check_setxattr_cmd(call_frame_t *frame, dict_t *dict) { - server_conf_t *conf = NULL; - xlator_t *this = NULL; - server_state_t *state = NULL; - char resolve_vars[256]; - char resolve2_vars[256]; - char loc_vars[256]; - char loc2_vars[256]; - char other_vars[512]; - char caller[512]; - char *op = "UNKNOWN"; + server_conf_t *conf = NULL; + rpc_transport_t *xprt = NULL; + uint64_t total_read = 0; + uint64_t total_write = 0; - GF_VALIDATE_OR_GOTO ("server", frame, out); + conf = frame->this->private; + if (!conf || !dict) + return 0; - this = frame->this; - conf = this->private; + if (dict_foreach_fnmatch(dict, "*io*stat*dump", dict_null_foreach_fn, + NULL) > 0) { + list_for_each_entry(xprt, &conf->xprt_list, list) + { + total_read += xprt->total_bytes_read; + total_write += xprt->total_bytes_write; + } + gf_smsg("stats", GF_LOG_INFO, 0, PS_MSG_RW_STAT, "total-read=%" PRIu64, + total_read, "total-write=%" PRIu64, total_write, NULL); + } - GF_VALIDATE_OR_GOTO ("server", conf, out); + return 0; +} - if (!conf->trace) - goto out; +server_ctx_t * +server_ctx_get(client_t *client, xlator_t *xlator) +{ + void *tmp = NULL; + server_ctx_t *ctx = NULL; + server_ctx_t *setted_ctx = NULL; - state = CALL_STATE (frame); + client_ctx_get(client, xlator, &tmp); - memset (resolve_vars, '\0', 256); - memset (resolve2_vars, '\0', 256); - memset (loc_vars, '\0', 256); - memset (loc2_vars, '\0', 256); - memset (other_vars, '\0', 256); + ctx = tmp; - print_caller (caller, 256, frame); + if (ctx != NULL) + goto out; - if (!server_resolve_is_empty (&state->resolve)) { - server_print_resolve (resolve_vars, 256, &state->resolve); - server_print_loc (loc_vars, 256, &state->loc); - } + ctx = GF_CALLOC(1, sizeof(server_ctx_t), gf_server_mt_server_conf_t); - if (!server_resolve_is_empty (&state->resolve2)) { - server_print_resolve (resolve2_vars, 256, &state->resolve2); - server_print_loc (loc2_vars, 256, &state->loc2); - } + if (ctx == NULL) + goto out; - server_print_params (other_vars, 512, state); + ctx->fdtable = gf_fd_fdtable_alloc(); - switch (frame->root->type) { - case GF_OP_TYPE_FOP: - op = gf_fop_list[frame->root->op]; - break; - case GF_OP_TYPE_MGMT: - op = gf_mgmt_list[frame->root->op]; - break; - default: - op = ""; - break; - } + if (ctx->fdtable == NULL) { + GF_FREE(ctx); + ctx = NULL; + goto out; + } + + LOCK_INIT(&ctx->fdtable_lock); + + setted_ctx = client_ctx_set(client, xlator, ctx); + if (ctx != setted_ctx) { + LOCK_DESTROY(&ctx->fdtable_lock); + GF_FREE(ctx->fdtable); + GF_FREE(ctx); + ctx = setted_ctx; + } - gf_log (this->name, GF_LOG_INFO, - "%s%s%s%s%s%s%s", - op, caller, - resolve_vars, loc_vars, resolve2_vars, loc2_vars, other_vars); out: - return; + return ctx; } int -serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp) +auth_set_username_passwd(dict_t *input_params, dict_t *config_params, + client_t *client) { - gf_dirent_t *entry = NULL; - gfs3_dirplist *trav = NULL; - gfs3_dirplist *prev = NULL; - int ret = -1; - - GF_VALIDATE_OR_GOTO ("server", entries, out); - GF_VALIDATE_OR_GOTO ("server", rsp, out); - - list_for_each_entry (entry, &entries->list, list) { - trav = GF_CALLOC (1, sizeof (*trav), gf_server_mt_dirent_rsp_t); - if (!trav) - goto out; - - trav->d_ino = entry->d_ino; - trav->d_off = entry->d_off; - trav->d_len = entry->d_len; - trav->d_type = entry->d_type; - trav->name = entry->d_name; - - gf_stat_from_iatt (&trav->stat, &entry->d_stat); - - /* if 'dict' is present, pack it */ - if (entry->dict) { - trav->dict.dict_len = dict_serialized_length (entry->dict); - if (trav->dict.dict_len < 0) { - gf_log (THIS->name, GF_LOG_ERROR, - "failed to get serialized length " - "of reply dict"); - errno = EINVAL; - trav->dict.dict_len = 0; - goto out; - } - - trav->dict.dict_val = GF_CALLOC (1, trav->dict.dict_len, - gf_server_mt_rsp_buf_t); - if (!trav->dict.dict_val) { - errno = ENOMEM; - trav->dict.dict_len = 0; - goto out; - } - - ret = dict_serialize (entry->dict, trav->dict.dict_val); - if (ret < 0) { - gf_log (THIS->name, GF_LOG_ERROR, - "failed to serialize reply dict"); - errno = -ret; - trav->dict.dict_len = 0; - goto out; - } + int ret = 0; + data_t *allow_user = NULL; + data_t *passwd_data = NULL; + char *username = NULL; + char *password = NULL; + char *brick_name = NULL; + char *searchstr = NULL; + char *username_str = NULL; + char *tmp = NULL; + char *username_cpy = NULL; + + ret = dict_get_str(input_params, "username", &username); + if (ret) { + gf_msg_debug("auth/login", 0, + "username not found, returning " + "DONT-CARE"); + /* For non trusted clients username and password + will not be there. So don't reject the client. + */ + ret = 0; + goto out; + } + + ret = dict_get_str(input_params, "password", &password); + if (ret) { + gf_smsg("auth/login", GF_LOG_WARNING, 0, PS_MSG_PASSWORD_NOT_FOUND, + NULL); + goto out; + } + + ret = dict_get_str(input_params, "remote-subvolume", &brick_name); + if (ret) { + gf_smsg("auth/login", GF_LOG_ERROR, 0, + PS_MSG_REMOTE_SUBVOL_NOT_SPECIFIED, NULL); + ret = -1; + goto out; + } + + ret = gf_asprintf(&searchstr, "auth.login.%s.allow", brick_name); + if (-1 == ret) { + ret = 0; + goto out; + } + + allow_user = dict_get(config_params, searchstr); + GF_FREE(searchstr); + + if (allow_user) { + username_cpy = gf_strdup(allow_user->data); + if (!username_cpy) + goto out; + + username_str = strtok_r(username_cpy, " ,", &tmp); + + while (username_str) { + if (!fnmatch(username_str, username, 0)) { + ret = gf_asprintf(&searchstr, "auth.login.%s.password", + username); + if (-1 == ret) + goto out; + + passwd_data = dict_get(config_params, searchstr); + GF_FREE(searchstr); + + if (!passwd_data) { + gf_smsg("auth/login", GF_LOG_ERROR, 0, PS_MSG_LOGIN_ERROR, + NULL); + ret = -1; + goto out; } - if (prev) - prev->nextentry = trav; - else - rsp->reply = trav; - - prev = trav; + ret = strcmp(data_to_str(passwd_data), password); + if (!ret) { + client->auth.username = gf_strdup(username); + client->auth.passwd = gf_strdup(password); + } else { + gf_smsg("auth/login", GF_LOG_ERROR, 0, PS_MSG_LOGIN_ERROR, + "username=%s", username, NULL); + } + break; + } + username_str = strtok_r(NULL, " ,", &tmp); } + } - ret = 0; out: - return ret; -} + GF_FREE(username_cpy); + return ret; +} -int -serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp) +inode_t * +server_inode_new(inode_table_t *itable, uuid_t gfid) { - gf_dirent_t *entry = NULL; - gfs3_dirlist *trav = NULL; - gfs3_dirlist *prev = NULL; - int ret = -1; - - GF_VALIDATE_OR_GOTO ("server", entries, out); - GF_VALIDATE_OR_GOTO ("server", rsp, out); - - list_for_each_entry (entry, &entries->list, list) { - trav = GF_CALLOC (1, sizeof (*trav), gf_server_mt_dirent_rsp_t); - if (!trav) - goto out; - trav->d_ino = entry->d_ino; - trav->d_off = entry->d_off; - trav->d_len = entry->d_len; - trav->d_type = entry->d_type; - trav->name = entry->d_name; - if (prev) - prev->nextentry = trav; - else - rsp->reply = trav; - - prev = trav; - } - - ret = 0; -out: - return ret; + if (__is_root_gfid(gfid)) + return itable->root; + else + return inode_new(itable); } int -readdir_rsp_cleanup (gfs3_readdir_rsp *rsp) +unserialize_req_locklist(gfs3_setactivelk_req *req, lock_migration_info_t *lmi) { - gfs3_dirlist *prev = NULL; - gfs3_dirlist *trav = NULL; + struct gfs3_locklist *trav = NULL; + lock_migration_info_t *temp = NULL; + int ret = -1; - trav = rsp->reply; - prev = trav; - while (trav) { - trav = trav->nextentry; - GF_FREE (prev); - prev = trav; - } + trav = req->request; - return 0; -} - -int -readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp) -{ - gfs3_dirplist *prev = NULL; - gfs3_dirplist *trav = NULL; + INIT_LIST_HEAD(&lmi->list); - trav = rsp->reply; - prev = trav; - while (trav) { - trav = trav->nextentry; - if (prev->dict.dict_val) - GF_FREE (prev->dict.dict_val); - GF_FREE (prev); - prev = trav; + while (trav) { + temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig); + if (temp == NULL) { + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_NO_MEM, NULL); + goto out; } - return 0; -} + INIT_LIST_HEAD(&temp->list); -int -gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key) -{ + gf_proto_flock_to_flock(&trav->flock, &temp->flock); - server_conf_t *conf = NULL; - rpc_transport_t *xprt = NULL; + temp->lk_flags = trav->lk_flags; - conf = frame->this->private; - if (!conf) - return 0; + temp->client_uid = gf_strdup(trav->client_uid); - if (fnmatch ("*list*mount*point*", key, 0) == 0) { - /* list all the client protocol connecting to this process */ - pthread_mutex_lock (&conf->mutex); - { - list_for_each_entry (xprt, &conf->xprt_list, list) { - gf_log ("mount-point-list", GF_LOG_INFO, - "%s", xprt->peerinfo.identifier); - } - } - pthread_mutex_unlock (&conf->mutex); - } + list_add_tail(&temp->list, &lmi->list); - /* Add more options/keys here */ + trav = trav->nextentry; + } - return 0; + ret = 0; +out: + return ret; } int -gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict) +unserialize_req_locklist_v2(gfx_setactivelk_req *req, + lock_migration_info_t *lmi) { + struct gfs3_locklist *trav = NULL; + lock_migration_info_t *temp = NULL; + int ret = -1; - data_pair_t *pair = NULL; - server_conf_t *conf = NULL; - rpc_transport_t *xprt = NULL; - uint64_t total_read = 0; - uint64_t total_write = 0; - - conf = frame->this->private; - if (!conf || !dict) - return 0; - - for (pair = dict->members_list; pair; pair = pair->next) { - /* this exact key is used in 'io-stats' too. - * But this is better place for this information dump. - */ - if (fnmatch ("*io*stat*dump", pair->key, 0) == 0) { - list_for_each_entry (xprt, &conf->xprt_list, list) { - total_read += xprt->total_bytes_read; - total_write += xprt->total_bytes_write; - } - gf_log ("stats", GF_LOG_INFO, - "total-read %"PRIu64", total-write %"PRIu64, - total_read, total_write); - } + trav = req->request; + + INIT_LIST_HEAD(&lmi->list); + + while (trav) { + temp = GF_CALLOC(1, sizeof(*lmi), gf_common_mt_lock_mig); + if (temp == NULL) { + gf_smsg(THIS->name, GF_LOG_ERROR, 0, PS_MSG_NO_MEM, NULL); + goto out; } - return 0; -} + INIT_LIST_HEAD(&temp->list); -gf_boolean_t -server_cancel_conn_timer (xlator_t *this, server_connection_t *conn) -{ - gf_timer_t *timer = NULL; - gf_boolean_t cancelled = _gf_false; + gf_proto_flock_to_flock(&trav->flock, &temp->flock); - if (!this || !conn) { - gf_log (THIS->name, GF_LOG_ERROR, "Invalid arguments to " - "cancel connection timer"); - return cancelled; - } + temp->lk_flags = trav->lk_flags; - pthread_mutex_lock (&conn->lock); - { - if (!conn->timer) - goto unlock; + temp->client_uid = gf_strdup(trav->client_uid); - timer = conn->timer; - conn->timer = NULL; - } -unlock: - pthread_mutex_unlock (&conn->lock); + list_add_tail(&temp->list, &lmi->list); - if (timer) { - gf_timer_call_cancel (this->ctx, timer); - cancelled = _gf_true; - } - return cancelled; + trav = trav->nextentry; + } + + ret = 0; +out: + return ret; } |
