diff options
author | Gluster Ant <bugzilla-bot@gluster.org> | 2018-09-12 17:52:45 +0530 |
---|---|---|
committer | Nigel Babu <nigelb@redhat.com> | 2018-09-12 17:52:45 +0530 |
commit | e16868dede6455cab644805af6fe1ac312775e13 (patch) | |
tree | 15aebdb4fff2d87cf8a72f836816b3aa634da58d /xlators/protocol/server/src/server-handshake.c | |
parent | 45a71c0548b6fd2c757aa2e7b7671a1411948894 (diff) |
Land part 2 of clang-format changes
Change-Id: Ia84cc24c8924e6d22d02ac15f611c10e26db99b4
Signed-off-by: Nigel Babu <nigelb@redhat.com>
Diffstat (limited to 'xlators/protocol/server/src/server-handshake.c')
-rw-r--r-- | xlators/protocol/server/src/server-handshake.c | 1730 |
1 files changed, 876 insertions, 854 deletions
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c index c0b03510191..30e7e4b0478 100644 --- a/xlators/protocol/server/src/server-handshake.c +++ b/xlators/protocol/server/src/server-handshake.c @@ -8,7 +8,6 @@ cases as published by the Free Software Foundation. */ - #include "server.h" #include "server-helpers.h" #include "rpc-common-xdr.h" @@ -22,989 +21,1012 @@ #include "syncop.h" struct __get_xl_struct { - const char *name; - xlator_t *reply; + const char *name; + xlator_t *reply; }; int -gf_compare_client_version (rpcsvc_request_t *req, int fop_prognum, - int mgmt_prognum) +gf_compare_client_version(rpcsvc_request_t *req, int fop_prognum, + int mgmt_prognum) { - int ret = -1; - /* TODO: think.. */ - if (glusterfs3_3_fop_prog.prognum == fop_prognum) - ret = 0; + int ret = -1; + /* TODO: think.. */ + if (glusterfs3_3_fop_prog.prognum == fop_prognum) + ret = 0; - return ret; + return ret; } int -_volfile_update_checksum (xlator_t *this, char *key, uint32_t checksum) +_volfile_update_checksum(xlator_t *this, char *key, uint32_t checksum) { - server_conf_t *conf = NULL; - struct _volfile_ctx *temp_volfile = NULL; - - conf = this->private; - temp_volfile = conf->volfile; - - while (temp_volfile) { - if ((NULL == key) && (NULL == temp_volfile->key)) - break; - if ((NULL == key) || (NULL == temp_volfile->key)) { - temp_volfile = temp_volfile->next; - continue; - } - if (strcmp (temp_volfile->key, key) == 0) - break; - temp_volfile = temp_volfile->next; + server_conf_t *conf = NULL; + struct _volfile_ctx *temp_volfile = NULL; + + conf = this->private; + temp_volfile = conf->volfile; + + while (temp_volfile) { + if ((NULL == key) && (NULL == temp_volfile->key)) + break; + if ((NULL == key) || (NULL == temp_volfile->key)) { + temp_volfile = temp_volfile->next; + continue; } + if (strcmp(temp_volfile->key, key) == 0) + break; + temp_volfile = temp_volfile->next; + } + + if (!temp_volfile) { + temp_volfile = GF_CALLOC(1, sizeof(struct _volfile_ctx), + gf_server_mt_volfile_ctx_t); + if (!temp_volfile) + goto out; + temp_volfile->next = conf->volfile; + temp_volfile->key = (key) ? gf_strdup(key) : NULL; + temp_volfile->checksum = checksum; - if (!temp_volfile) { - temp_volfile = GF_CALLOC (1, sizeof (struct _volfile_ctx), - gf_server_mt_volfile_ctx_t); - if (!temp_volfile) - goto out; - temp_volfile->next = conf->volfile; - temp_volfile->key = (key)? gf_strdup (key): NULL; - temp_volfile->checksum = checksum; - - conf->volfile = temp_volfile; - goto out; - } + conf->volfile = temp_volfile; + goto out; + } - if (temp_volfile->checksum != checksum) { - gf_msg (this->name, GF_LOG_INFO, 0, PS_MSG_REMOUNT_CLIENT_REQD, - "the volume file was modified between a prior access " - "and now. This may lead to inconsistency between " - "clients, you are advised to remount client"); - temp_volfile->checksum = checksum; - } + if (temp_volfile->checksum != checksum) { + gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_REMOUNT_CLIENT_REQD, + "the volume file was modified between a prior access " + "and now. This may lead to inconsistency between " + "clients, you are advised to remount client"); + temp_volfile->checksum = checksum; + } out: - return 0; + return 0; } - static size_t -getspec_build_volfile_path (xlator_t *this, const char *key, char *path, - size_t path_len) +getspec_build_volfile_path(xlator_t *this, const char *key, char *path, + size_t path_len) { - char *filename = NULL; - server_conf_t *conf = NULL; - int ret = -1; - int free_filename = 0; - char data_key[256] = {0,}; - - conf = this->private; - - /* Inform users that this option is changed now */ - ret = dict_get_str (this->options, "client-volume-filename", - &filename); - if (ret == 0) { - gf_msg (this->name, GF_LOG_WARNING, 0, PS_MSG_DEFAULTING_FILE, - "option 'client-volume-filename' is changed to " - "'volume-filename.<key>' which now takes 'key' as an " - "option to choose/fetch different files from server. " - "Refer documentation or contact developers for more " - "info. Currently defaulting to given file '%s'", - filename); - } - - if (key && !filename) { - sprintf (data_key, "volume-filename.%s", key); - ret = dict_get_str (this->options, data_key, &filename); - if (ret < 0) { - /* Make sure that key doesn't contain "../" in path */ - if ((gf_strstr (key, "/", "..")) == -1) { - gf_msg (this->name, GF_LOG_ERROR, EINVAL, - PS_MSG_INVALID_ENTRY, "%s: invalid " - "key", key); - goto out; - } - } + char *filename = NULL; + server_conf_t *conf = NULL; + int ret = -1; + int free_filename = 0; + char data_key[256] = { + 0, + }; + + conf = this->private; + + /* Inform users that this option is changed now */ + ret = dict_get_str(this->options, "client-volume-filename", &filename); + if (ret == 0) { + gf_msg(this->name, GF_LOG_WARNING, 0, PS_MSG_DEFAULTING_FILE, + "option 'client-volume-filename' is changed to " + "'volume-filename.<key>' which now takes 'key' as an " + "option to choose/fetch different files from server. " + "Refer documentation or contact developers for more " + "info. Currently defaulting to given file '%s'", + filename); + } + + if (key && !filename) { + sprintf(data_key, "volume-filename.%s", key); + ret = dict_get_str(this->options, data_key, &filename); + if (ret < 0) { + /* Make sure that key doesn't contain "../" in path */ + if ((gf_strstr(key, "/", "..")) == -1) { + gf_msg(this->name, GF_LOG_ERROR, EINVAL, PS_MSG_INVALID_ENTRY, + "%s: invalid " + "key", + key); + goto out; + } } + } - if (!filename) { - ret = dict_get_str (this->options, - "volume-filename.default", &filename); - if (ret < 0) { - gf_msg_debug (this->name, 0, "no default volume " - "filename given, defaulting to %s", - DEFAULT_VOLUME_FILE_PATH); - } + if (!filename) { + ret = dict_get_str(this->options, "volume-filename.default", &filename); + if (ret < 0) { + gf_msg_debug(this->name, 0, + "no default volume " + "filename given, defaulting to %s", + DEFAULT_VOLUME_FILE_PATH); } + } - if (!filename && key) { - ret = gf_asprintf (&filename, "%s/%s.vol", conf->conf_dir, key); - if (-1 == ret) - goto out; + if (!filename && key) { + ret = gf_asprintf(&filename, "%s/%s.vol", conf->conf_dir, key); + if (-1 == ret) + goto out; - free_filename = 1; - } - if (!filename) - filename = DEFAULT_VOLUME_FILE_PATH; + free_filename = 1; + } + if (!filename) + filename = DEFAULT_VOLUME_FILE_PATH; - ret = -1; + ret = -1; - if ((filename) && (path_len > strlen (filename))) { - strcpy (path, filename); - ret = strlen (filename); - } + if ((filename) && (path_len > strlen(filename))) { + strcpy(path, filename); + ret = strlen(filename); + } out: - if (free_filename) - GF_FREE (filename); + if (free_filename) + GF_FREE(filename); - return ret; + return ret; } int -_validate_volfile_checksum (xlator_t *this, char *key, - uint32_t checksum) +_validate_volfile_checksum(xlator_t *this, char *key, uint32_t checksum) { - char filename[PATH_MAX] = {0,}; - server_conf_t *conf = NULL; - struct _volfile_ctx *temp_volfile = NULL; - int ret = 0; - int fd = 0; - uint32_t local_checksum = 0; - - conf = this->private; - temp_volfile = conf->volfile; - - if (!checksum) - goto out; + char filename[PATH_MAX] = { + 0, + }; + server_conf_t *conf = NULL; + struct _volfile_ctx *temp_volfile = NULL; + int ret = 0; + int fd = 0; + uint32_t local_checksum = 0; + + conf = this->private; + temp_volfile = conf->volfile; + + if (!checksum) + goto out; - if (!temp_volfile) { - ret = getspec_build_volfile_path (this, key, filename, - sizeof (filename)); - if (ret <= 0) - goto out; - fd = open (filename, O_RDONLY); - if (-1 == fd) { - ret = 0; - gf_msg (this->name, GF_LOG_INFO, errno, - PS_MSG_VOL_FILE_OPEN_FAILED, - "failed to open volume file (%s) : %s", - filename, strerror (errno)); - goto out; - } - get_checksum_for_file (fd, &local_checksum); - _volfile_update_checksum (this, key, local_checksum); - sys_close (fd); + if (!temp_volfile) { + ret = getspec_build_volfile_path(this, key, filename, sizeof(filename)); + if (ret <= 0) + goto out; + fd = open(filename, O_RDONLY); + if (-1 == fd) { + ret = 0; + gf_msg(this->name, GF_LOG_INFO, errno, PS_MSG_VOL_FILE_OPEN_FAILED, + "failed to open volume file (%s) : %s", filename, + strerror(errno)); + goto out; } - - temp_volfile = conf->volfile; - while (temp_volfile) { - if ((NULL == key) && (NULL == temp_volfile->key)) - break; - if ((NULL == key) || (NULL == temp_volfile->key)) { - temp_volfile = temp_volfile->next; - continue; - } - if (strcmp (temp_volfile->key, key) == 0) - break; - temp_volfile = temp_volfile->next; + get_checksum_for_file(fd, &local_checksum); + _volfile_update_checksum(this, key, local_checksum); + sys_close(fd); + } + + temp_volfile = conf->volfile; + while (temp_volfile) { + if ((NULL == key) && (NULL == temp_volfile->key)) + break; + if ((NULL == key) || (NULL == temp_volfile->key)) { + temp_volfile = temp_volfile->next; + continue; } + if (strcmp(temp_volfile->key, key) == 0) + break; + temp_volfile = temp_volfile->next; + } - if (!temp_volfile) - goto out; + if (!temp_volfile) + goto out; - if ((temp_volfile->checksum) && - (checksum != temp_volfile->checksum)) - ret = -1; + if ((temp_volfile->checksum) && (checksum != temp_volfile->checksum)) + ret = -1; out: - return ret; + return ret; } - int -server_getspec (rpcsvc_request_t *req) +server_getspec(rpcsvc_request_t *req) { - int32_t ret = -1; - int32_t op_errno = ENOENT; - int32_t spec_fd = -1; - size_t file_len = 0; - char filename[PATH_MAX] = {0,}; - struct stat stbuf = {0,}; - uint32_t checksum = 0; - char *key = NULL; - server_conf_t *conf = NULL; - xlator_t *this = NULL; - gf_getspec_req args = {0,}; - gf_getspec_rsp rsp = {0,}; - - this = req->svc->xl; - conf = this->private; - ret = xdr_to_generic (req->msg[0], &args, - (xdrproc_t)xdr_gf_getspec_req); + int32_t ret = -1; + int32_t op_errno = ENOENT; + int32_t spec_fd = -1; + size_t file_len = 0; + char filename[PATH_MAX] = { + 0, + }; + struct stat stbuf = { + 0, + }; + uint32_t checksum = 0; + char *key = NULL; + server_conf_t *conf = NULL; + xlator_t *this = NULL; + gf_getspec_req args = { + 0, + }; + gf_getspec_rsp rsp = { + 0, + }; + + this = req->svc->xl; + conf = this->private; + ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gf_getspec_req); + if (ret < 0) { + // failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + op_errno = EINVAL; + goto fail; + } + + ret = getspec_build_volfile_path(this, args.key, filename, + sizeof(filename)); + if (ret > 0) { + /* to allocate the proper buffer to hold the file data */ + ret = sys_stat(filename, &stbuf); if (ret < 0) { - //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; - op_errno = EINVAL; - goto fail; + gf_msg(this->name, GF_LOG_ERROR, errno, PS_MSG_STAT_ERROR, + "Unable to stat %s (%s)", filename, strerror(errno)); + op_errno = errno; + goto fail; } - ret = getspec_build_volfile_path (this, args.key, - filename, sizeof (filename)); - if (ret > 0) { - /* to allocate the proper buffer to hold the file data */ - ret = sys_stat (filename, &stbuf); - if (ret < 0){ - gf_msg (this->name, GF_LOG_ERROR, errno, - PS_MSG_STAT_ERROR, "Unable to stat %s (%s)", - filename, strerror (errno)); - op_errno = errno; - goto fail; - } - - spec_fd = open (filename, O_RDONLY); - if (spec_fd < 0) { - gf_msg (this->name, GF_LOG_ERROR, errno, - PS_MSG_FILE_OP_FAILED, "Unable to open %s " - "(%s)", filename, strerror (errno)); - op_errno = errno; - goto fail; - } - ret = file_len = stbuf.st_size; - - if (conf->verify_volfile) { - get_checksum_for_file (spec_fd, &checksum); - _volfile_update_checksum (this, key, checksum); - } + spec_fd = open(filename, O_RDONLY); + if (spec_fd < 0) { + gf_msg(this->name, GF_LOG_ERROR, errno, PS_MSG_FILE_OP_FAILED, + "Unable to open %s " + "(%s)", + filename, strerror(errno)); + op_errno = errno; + goto fail; } + ret = file_len = stbuf.st_size; - if (file_len) { - rsp.spec = GF_CALLOC (file_len, sizeof (char), - gf_server_mt_rsp_buf_t); - if (!rsp.spec) { - ret = -1; - op_errno = ENOMEM; - goto fail; - } - ret = sys_read (spec_fd, rsp.spec, file_len); + if (conf->verify_volfile) { + get_checksum_for_file(spec_fd, &checksum); + _volfile_update_checksum(this, key, checksum); } + } + + if (file_len) { + rsp.spec = GF_CALLOC(file_len, sizeof(char), gf_server_mt_rsp_buf_t); + if (!rsp.spec) { + ret = -1; + op_errno = ENOMEM; + goto fail; + } + ret = sys_read(spec_fd, rsp.spec, file_len); + } - /* convert to XDR */ - op_errno = errno; + /* convert to XDR */ + op_errno = errno; fail: - if (!rsp.spec) - rsp.spec = ""; - rsp.op_errno = gf_errno_to_error (op_errno); - rsp.op_ret = ret; + if (!rsp.spec) + rsp.spec = ""; + rsp.op_errno = gf_errno_to_error(op_errno); + rsp.op_ret = ret; - if (spec_fd != -1) - sys_close (spec_fd); + if (spec_fd != -1) + sys_close(spec_fd); - server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, - (xdrproc_t)xdr_gf_getspec_rsp); + server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, + (xdrproc_t)xdr_gf_getspec_rsp); - return 0; + return 0; } static void -server_first_lookup_done (rpcsvc_request_t *req, gf_setvolume_rsp *rsp) { - - server_submit_reply (NULL, req, rsp, NULL, 0, NULL, - (xdrproc_t)xdr_gf_setvolume_rsp); +server_first_lookup_done(rpcsvc_request_t *req, gf_setvolume_rsp *rsp) +{ + server_submit_reply(NULL, req, rsp, NULL, 0, NULL, + (xdrproc_t)xdr_gf_setvolume_rsp); - GF_FREE (rsp->dict.dict_val); - GF_FREE (rsp); + GF_FREE(rsp->dict.dict_val); + GF_FREE(rsp); } static inode_t * -do_path_lookup (xlator_t *xl, dict_t *dict, inode_t *parinode, char *basename) +do_path_lookup(xlator_t *xl, dict_t *dict, inode_t *parinode, char *basename) { - int ret = 0; - loc_t loc = {0,}; - uuid_t gfid = {0,}; - struct iatt iatt = {0,}; - inode_t *inode = NULL; - - loc.parent = parinode; - loc_touchup (&loc, basename); - loc.inode = inode_new (xl->itable); - - gf_uuid_generate (gfid); - ret = dict_set_gfuuid (dict, "gfid-req", gfid, true); - if (ret) { - gf_log (xl->name, GF_LOG_ERROR, - "failed to set 'gfid-req' for subdir"); - goto out; - } - - ret = syncop_lookup (xl, &loc, &iatt, NULL, dict, NULL); - if (ret < 0) { - gf_log (xl->name, GF_LOG_ERROR, - "first lookup on subdir (%s) failed: %s", - basename, strerror (errno)); - } + int ret = 0; + loc_t loc = { + 0, + }; + uuid_t gfid = { + 0, + }; + struct iatt iatt = { + 0, + }; + inode_t *inode = NULL; + + loc.parent = parinode; + loc_touchup(&loc, basename); + loc.inode = inode_new(xl->itable); + + gf_uuid_generate(gfid); + ret = dict_set_gfuuid(dict, "gfid-req", gfid, true); + if (ret) { + gf_log(xl->name, GF_LOG_ERROR, "failed to set 'gfid-req' for subdir"); + goto out; + } + ret = syncop_lookup(xl, &loc, &iatt, NULL, dict, NULL); + if (ret < 0) { + gf_log(xl->name, GF_LOG_ERROR, "first lookup on subdir (%s) failed: %s", + basename, strerror(errno)); + } - /* Inode linking is required so that the - resolution happens all fine for future fops */ - inode = inode_link (loc.inode, loc.parent, loc.name, &iatt); + /* Inode linking is required so that the + resolution happens all fine for future fops */ + inode = inode_link(loc.inode, loc.parent, loc.name, &iatt); - /* Extra ref so the pointer is valid till client is valid */ - /* FIXME: not a priority, but this can lead to some inode - leaks if subdir is more than 1 level depth. Leak is only - per subdir entry, and not dependent on number of - connections, so it should be fine for now */ - inode_ref (inode); + /* Extra ref so the pointer is valid till client is valid */ + /* FIXME: not a priority, but this can lead to some inode + leaks if subdir is more than 1 level depth. Leak is only + per subdir entry, and not dependent on number of + connections, so it should be fine for now */ + inode_ref(inode); out: - return inode; + return inode; } int -server_first_lookup (xlator_t *this, client_t *client, dict_t *reply) +server_first_lookup(xlator_t *this, client_t *client, dict_t *reply) { - loc_t loc = {0, }; - struct iatt iatt = {0,}; - dict_t *dict = NULL; - int ret = 0; - xlator_t *xl = client->bound_xl; - char *msg = NULL; - inode_t *inode = NULL; - char *bname = NULL; - char *str = NULL; - char *tmp = NULL; - char *saveptr = NULL; - - loc.path = "/"; - loc.name = ""; - loc.inode = xl->itable->root; - loc.parent = NULL; - gf_uuid_copy (loc.gfid, loc.inode->gfid); - - ret = syncop_lookup (xl, &loc, &iatt, NULL, NULL, NULL); - if (ret < 0) - gf_log (xl->name, GF_LOG_ERROR, "lookup on root failed: %s", - strerror (errno)); - /* Ignore error from lookup, don't set - * failure in rsp->op_ret. lookup on a snapview-server - * can fail with ESTALE - */ - /* TODO-SUBDIR-MOUNT: validate above comment with respect to subdir lookup */ - - if (client->subdir_mount) { - str = tmp = gf_strdup (client->subdir_mount); - dict = dict_new (); - inode = xl->itable->root; - bname = strtok_r (str, "/", &saveptr); - while (bname != NULL) { - inode = do_path_lookup (xl, dict, inode, bname); - if (inode == NULL) { - gf_log (this->name, GF_LOG_ERROR, - "first lookup on subdir (%s) failed: %s", - client->subdir_mount, strerror (errno)); - ret = -1; - goto fail; - } - bname = strtok_r (NULL, "/", &saveptr); - } - - /* Can be used in server_resolve() */ - gf_uuid_copy (client->subdir_gfid, inode->gfid); - client->subdir_inode = inode; + loc_t loc = { + 0, + }; + struct iatt iatt = { + 0, + }; + dict_t *dict = NULL; + int ret = 0; + xlator_t *xl = client->bound_xl; + char *msg = NULL; + inode_t *inode = NULL; + char *bname = NULL; + char *str = NULL; + char *tmp = NULL; + char *saveptr = NULL; + + loc.path = "/"; + loc.name = ""; + loc.inode = xl->itable->root; + loc.parent = NULL; + gf_uuid_copy(loc.gfid, loc.inode->gfid); + + ret = syncop_lookup(xl, &loc, &iatt, NULL, NULL, NULL); + if (ret < 0) + gf_log(xl->name, GF_LOG_ERROR, "lookup on root failed: %s", + strerror(errno)); + /* Ignore error from lookup, don't set + * failure in rsp->op_ret. lookup on a snapview-server + * can fail with ESTALE + */ + /* TODO-SUBDIR-MOUNT: validate above comment with respect to subdir lookup + */ + + if (client->subdir_mount) { + str = tmp = gf_strdup(client->subdir_mount); + dict = dict_new(); + inode = xl->itable->root; + bname = strtok_r(str, "/", &saveptr); + while (bname != NULL) { + inode = do_path_lookup(xl, dict, inode, bname); + if (inode == NULL) { + gf_log(this->name, GF_LOG_ERROR, + "first lookup on subdir (%s) failed: %s", + client->subdir_mount, strerror(errno)); + ret = -1; + goto fail; + } + bname = strtok_r(NULL, "/", &saveptr); } - ret = 0; - goto out; + /* Can be used in server_resolve() */ + gf_uuid_copy(client->subdir_gfid, inode->gfid); + client->subdir_inode = inode; + } -fail: - /* we should say to client, it is not possible - to connect */ - ret = gf_asprintf (&msg, "subdirectory for mount \"%s\" is not found", - client->subdir_mount); - if (-1 == ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - PS_MSG_ASPRINTF_FAILED, - "asprintf failed while setting error msg"); - } - ret = dict_set_dynstr (reply, "ERROR", msg); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); + ret = 0; + goto out; - ret = -1; +fail: + /* we should say to client, it is not possible + to connect */ + ret = gf_asprintf(&msg, "subdirectory for mount \"%s\" is not found", + client->subdir_mount); + if (-1 == ret) { + gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED, + "asprintf failed while setting error msg"); + } + ret = dict_set_dynstr(reply, "ERROR", msg); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + + ret = -1; out: - if (dict) - dict_unref (dict); + if (dict) + dict_unref(dict); - inode_unref (loc.inode); + inode_unref(loc.inode); - if (tmp) - GF_FREE (tmp); + if (tmp) + GF_FREE(tmp); - return ret; + return ret; } int -server_setvolume (rpcsvc_request_t *req) +server_setvolume(rpcsvc_request_t *req) { - gf_setvolume_req args = {{0,},}; - gf_setvolume_rsp *rsp = NULL; - client_t *client = NULL; - server_ctx_t *serv_ctx = NULL; - server_conf_t *conf = NULL; - peer_info_t *peerinfo = NULL; - dict_t *reply = NULL; - dict_t *config_params = NULL; - dict_t *params = NULL; - char *name = NULL; - char *client_uid = NULL; - char *clnt_version = NULL; - xlator_t *xl = NULL; - char *msg = NULL; - char *volfile_key = NULL; - xlator_t *this = NULL; - uint32_t checksum = 0; - int32_t ret = -1; - int32_t op_ret = -1; - int32_t op_errno = EINVAL; - char *buf = NULL; - uint32_t opversion = 0; - rpc_transport_t *xprt = NULL; - int32_t fop_version = 0; - int32_t mgmt_version = 0; - glusterfs_ctx_t *ctx = NULL; - struct _child_status *tmp = NULL; - char *subdir_mount = NULL; - char *client_name = NULL; - gf_boolean_t cleanup_starting = _gf_false; - - params = dict_new (); - reply = dict_new (); - ret = xdr_to_generic (req->msg[0], &args, - (xdrproc_t)xdr_gf_setvolume_req); - if (ret < 0) { - //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; - goto fail; - } - ctx = THIS->ctx; - - this = req->svc->xl; - /* this is to ensure config_params is populated with the first brick - * details at first place if brick multiplexing is enabled - */ - config_params = dict_copy_with_ref (this->options, NULL); - - buf = memdup (args.dict.dict_val, args.dict.dict_len); - if (buf == NULL) { - op_ret = -1; - op_errno = ENOMEM; - goto fail; - } - - ret = dict_unserialize (buf, args.dict.dict_len, ¶ms); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "Internal error: failed to unserialize " - "request dictionary"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg \"%s\"", "Internal error: failed " - "to unserialize request dictionary"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - params->extra_free = buf; - buf = NULL; - - ret = dict_get_str (params, "remote-subvolume", &name); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "No remote-subvolume option specified"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - LOCK (&ctx->volfile_lock); + gf_setvolume_req args = { { - xl = get_xlator_by_name (this, name); - if (!xl) - xl = this; - } - UNLOCK (&ctx->volfile_lock); - if (xl == NULL) { - ret = gf_asprintf (&msg, "remote-subvolume \"%s\" is not found", - name); - if (-1 == ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - PS_MSG_ASPRINTF_FAILED, - "asprintf failed while setting error msg"); - goto fail; - } - ret = dict_set_dynstr (reply, "ERROR", msg); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); - - op_ret = -1; - op_errno = ENOENT; - goto fail; - } - - config_params = dict_copy_with_ref (xl->options, config_params); - conf = this->private; - - if (conf->parent_up == _gf_false) { - /* PARENT_UP indicates that all xlators in graph are inited - * successfully - */ - op_ret = -1; - op_errno = EAGAIN; - - ret = dict_set_str (reply, "ERROR", - "xlator graph in server is not initialised " - "yet. Try again later"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error: " - "xlator graph in server is not " - "initialised yet. Try again later"); - goto fail; - } - - list_for_each_entry (tmp, &conf->child_status->status_list, - status_list) { - if (strcmp (tmp->name, name) == 0) - break; - } - - if (!tmp->name) { - gf_msg (this->name, GF_LOG_ERROR, 0, - PS_MSG_CHILD_STATUS_FAILED, - "No xlator %s is found in " - "child status list", name); - } else { - ret = dict_set_int32 (reply, "child_up", tmp->child_up); - if (ret < 0) - gf_msg (this->name, GF_LOG_ERROR, 0, - PS_MSG_DICT_GET_FAILED, - "Failed to set 'child_up' for xlator %s " - "in the reply dict", tmp->name); - } - - ret = dict_get_str (params, "process-uuid", &client_uid); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "UUID not specified"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); - - op_ret = -1; - op_errno = EINVAL; - goto fail; - } - - ret = dict_get_str (params, "subdir-mount", &subdir_mount); - if (ret < 0) { - /* Not a problem at all as the key is optional */ - } - ret = dict_get_str (params, "process-name", &client_name); - if (ret < 0) { - client_name = "unknown"; - } - - client = gf_client_get (this, &req->cred, client_uid, subdir_mount); - if (client == NULL) { - op_ret = -1; - op_errno = ENOMEM; - goto fail; - } - - client->client_name = gf_strdup(client_name); - - gf_msg_debug (this->name, 0, "Connected to %s", client->client_uid); - - serv_ctx = server_ctx_get (client, client->this); - if (serv_ctx == NULL) { - gf_msg (this->name, GF_LOG_INFO, 0, - PS_MSG_SERVER_CTX_GET_FAILED, "server_ctx_get() " - "failed"); - goto fail; + 0, + }, + }; + gf_setvolume_rsp *rsp = NULL; + client_t *client = NULL; + server_ctx_t *serv_ctx = NULL; + server_conf_t *conf = NULL; + peer_info_t *peerinfo = NULL; + dict_t *reply = NULL; + dict_t *config_params = NULL; + dict_t *params = NULL; + char *name = NULL; + char *client_uid = NULL; + char *clnt_version = NULL; + xlator_t *xl = NULL; + char *msg = NULL; + char *volfile_key = NULL; + xlator_t *this = NULL; + uint32_t checksum = 0; + int32_t ret = -1; + int32_t op_ret = -1; + int32_t op_errno = EINVAL; + char *buf = NULL; + uint32_t opversion = 0; + rpc_transport_t *xprt = NULL; + int32_t fop_version = 0; + int32_t mgmt_version = 0; + glusterfs_ctx_t *ctx = NULL; + struct _child_status *tmp = NULL; + char *subdir_mount = NULL; + char *client_name = NULL; + gf_boolean_t cleanup_starting = _gf_false; + + params = dict_new(); + reply = dict_new(); + ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gf_setvolume_req); + if (ret < 0) { + // failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto fail; + } + ctx = THIS->ctx; + + this = req->svc->xl; + /* this is to ensure config_params is populated with the first brick + * details at first place if brick multiplexing is enabled + */ + config_params = dict_copy_with_ref(this->options, NULL); + + buf = memdup(args.dict.dict_val, args.dict.dict_len); + if (buf == NULL) { + op_ret = -1; + op_errno = ENOMEM; + goto fail; + } + + ret = dict_unserialize(buf, args.dict.dict_len, ¶ms); + if (ret < 0) { + ret = dict_set_str(reply, "ERROR", + "Internal error: failed to unserialize " + "request dictionary"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg \"%s\"", + "Internal error: failed " + "to unserialize request dictionary"); + + op_ret = -1; + op_errno = EINVAL; + goto fail; + } + + params->extra_free = buf; + buf = NULL; + + ret = dict_get_str(params, "remote-subvolume", &name); + if (ret < 0) { + ret = dict_set_str(reply, "ERROR", + "No remote-subvolume option specified"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + + op_ret = -1; + op_errno = EINVAL; + goto fail; + } + + LOCK(&ctx->volfile_lock); + { + xl = get_xlator_by_name(this, name); + if (!xl) + xl = this; + } + UNLOCK(&ctx->volfile_lock); + if (xl == NULL) { + ret = gf_asprintf(&msg, "remote-subvolume \"%s\" is not found", name); + if (-1 == ret) { + gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED, + "asprintf failed while setting error msg"); + goto fail; } + ret = dict_set_dynstr(reply, "ERROR", msg); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); - pthread_mutex_lock (&conf->mutex); - if (xl->cleanup_starting) { - cleanup_starting = _gf_true; - } else if (req->trans->xl_private != client) { - req->trans->xl_private = client; - } - pthread_mutex_unlock (&conf->mutex); + op_ret = -1; + op_errno = ENOENT; + goto fail; + } - if (cleanup_starting) { - op_ret = -1; - op_errno = EAGAIN; + config_params = dict_copy_with_ref(xl->options, config_params); + conf = this->private; - ret = dict_set_str (reply, "ERROR", - "cleanup flag is set for xlator. " - " Try again later"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error: " - "cleanup flag is set for xlator. " - "Try again later"); - goto fail; - } + if (conf->parent_up == _gf_false) { + /* PARENT_UP indicates that all xlators in graph are inited + * successfully + */ + op_ret = -1; + op_errno = EAGAIN; - auth_set_username_passwd (params, config_params, client); - if (req->trans->ssl_name) { - if (dict_set_str(params,"ssl-name",req->trans->ssl_name) != 0) { - gf_msg (this->name, GF_LOG_WARNING, 0, - PS_MSG_SSL_NAME_SET_FAILED, "failed to set " - "ssl_name %s", req->trans->ssl_name); - /* Not fatal, auth will just fail. */ - } + ret = dict_set_str(reply, "ERROR", + "xlator graph in server is not initialised " + "yet. Try again later"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error: " + "xlator graph in server is not " + "initialised yet. Try again later"); + goto fail; + } + + list_for_each_entry(tmp, &conf->child_status->status_list, status_list) + { + if (strcmp(tmp->name, name) == 0) + break; + } + + if (!tmp->name) { + gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_CHILD_STATUS_FAILED, + "No xlator %s is found in " + "child status list", + name); + } else { + ret = dict_set_int32(reply, "child_up", tmp->child_up); + if (ret < 0) + gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_DICT_GET_FAILED, + "Failed to set 'child_up' for xlator %s " + "in the reply dict", + tmp->name); + } + + ret = dict_get_str(params, "process-uuid", &client_uid); + if (ret < 0) { + ret = dict_set_str(reply, "ERROR", "UUID not specified"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + + op_ret = -1; + op_errno = EINVAL; + goto fail; + } + + ret = dict_get_str(params, "subdir-mount", &subdir_mount); + if (ret < 0) { + /* Not a problem at all as the key is optional */ + } + ret = dict_get_str(params, "process-name", &client_name); + if (ret < 0) { + client_name = "unknown"; + } + + client = gf_client_get(this, &req->cred, client_uid, subdir_mount); + if (client == NULL) { + op_ret = -1; + op_errno = ENOMEM; + goto fail; + } + + client->client_name = gf_strdup(client_name); + + gf_msg_debug(this->name, 0, "Connected to %s", client->client_uid); + + serv_ctx = server_ctx_get(client, client->this); + if (serv_ctx == NULL) { + gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_SERVER_CTX_GET_FAILED, + "server_ctx_get() " + "failed"); + goto fail; + } + + pthread_mutex_lock(&conf->mutex); + if (xl->cleanup_starting) { + cleanup_starting = _gf_true; + } else if (req->trans->xl_private != client) { + req->trans->xl_private = client; + } + pthread_mutex_unlock(&conf->mutex); + + if (cleanup_starting) { + op_ret = -1; + op_errno = EAGAIN; + + ret = dict_set_str(reply, "ERROR", + "cleanup flag is set for xlator. " + " Try again later"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error: " + "cleanup flag is set for xlator. " + "Try again later"); + goto fail; + } + + auth_set_username_passwd(params, config_params, client); + if (req->trans->ssl_name) { + if (dict_set_str(params, "ssl-name", req->trans->ssl_name) != 0) { + gf_msg(this->name, GF_LOG_WARNING, 0, PS_MSG_SSL_NAME_SET_FAILED, + "failed to set " + "ssl_name %s", + req->trans->ssl_name); + /* Not fatal, auth will just fail. */ } + } - ret = dict_get_int32 (params, "fops-version", &fop_version); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "No FOP version number specified"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); + ret = dict_get_int32(params, "fops-version", &fop_version); + if (ret < 0) { + ret = dict_set_str(reply, "ERROR", "No FOP version number specified"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + } + + ret = dict_get_int32(params, "mgmt-version", &mgmt_version); + if (ret < 0) { + ret = dict_set_str(reply, "ERROR", "No MGMT version number specified"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + } + + ret = gf_compare_client_version(req, fop_version, mgmt_version); + if (ret != 0) { + ret = gf_asprintf(&msg, + "version mismatch: client(%d)" + " - client-mgmt(%d)", + fop_version, mgmt_version); + /* get_supported_version (req)); */ + if (-1 == ret) { + gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_ASPRINTF_FAILED, + "asprintf failed while" + "setting up error msg"); + goto fail; } + ret = dict_set_dynstr(reply, "ERROR", msg); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); - ret = dict_get_int32 (params, "mgmt-version", &mgmt_version); - if (ret < 0) { - ret = dict_set_str (reply, "ERROR", - "No MGMT version number specified"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); - } + op_ret = -1; + op_errno = EINVAL; + goto fail; + } - ret = gf_compare_client_version (req, fop_version, mgmt_version); - if (ret != 0) { - ret = gf_asprintf (&msg, "version mismatch: client(%d)" - " - client-mgmt(%d)", - fop_version, mgmt_version); - /* get_supported_version (req)); */ - if (-1 == ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - PS_MSG_ASPRINTF_FAILED, "asprintf failed while" - "setting up error msg"); - goto fail; - } - ret = dict_set_dynstr (reply, "ERROR", msg); + if (conf->verify_volfile) { + ret = dict_get_uint32(params, "volfile-checksum", &checksum); + if (ret == 0) { + ret = dict_get_str(params, "volfile-key", &volfile_key); + if (ret) + gf_msg_debug(this->name, 0, + "failed to get " + "'volfile-key'"); + + ret = _validate_volfile_checksum(this, volfile_key, checksum); + if (-1 == ret) { + ret = dict_set_str(reply, "ERROR", + "volume-file checksum " + "varies from earlier " + "access"); if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); + gf_msg_debug(this->name, 0, + "failed " + "to set error msg"); op_ret = -1; - op_errno = EINVAL; + op_errno = ESTALE; goto fail; + } } + } - if (conf->verify_volfile) { - ret = dict_get_uint32 (params, "volfile-checksum", &checksum); - if (ret == 0) { - ret = dict_get_str (params, "volfile-key", - &volfile_key); - if (ret) - gf_msg_debug (this->name, 0, "failed to get " - "'volfile-key'"); - - ret = _validate_volfile_checksum (this, volfile_key, - checksum); - if (-1 == ret) { - ret = dict_set_str (reply, "ERROR", - "volume-file checksum " - "varies from earlier " - "access"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed " - "to set error msg"); - - op_ret = -1; - op_errno = ESTALE; - goto fail; - } - } - } - - - peerinfo = &req->trans->peerinfo; - if (peerinfo) { - ret = dict_set_static_ptr (params, "peer-info", peerinfo); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set " - "peer-info"); - } - - ret = dict_get_uint32 (params, "opversion", &opversion); - if (ret) { - gf_msg (this->name, GF_LOG_INFO, 0, - PS_MSG_CLIENT_OPVERSION_GET_FAILED, - "Failed to get client opversion"); - } - client->opversion = opversion; - /* Assign op-version value to the client */ - pthread_mutex_lock (&conf->mutex); - list_for_each_entry (xprt, &conf->xprt_list, list) { - if (strcmp (peerinfo->identifier, xprt->peerinfo.identifier)) - continue; - xprt->peerinfo.max_op_version = opversion; - } - pthread_mutex_unlock (&conf->mutex); - - if (conf->auth_modules == NULL) { - gf_msg (this->name, GF_LOG_ERROR, 0, PS_MSG_AUTH_INIT_FAILED, - "Authentication module not initialized"); + peerinfo = &req->trans->peerinfo; + if (peerinfo) { + ret = dict_set_static_ptr(params, "peer-info", peerinfo); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set " + "peer-info"); + } + + ret = dict_get_uint32(params, "opversion", &opversion); + if (ret) { + gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_OPVERSION_GET_FAILED, + "Failed to get client opversion"); + } + client->opversion = opversion; + /* Assign op-version value to the client */ + pthread_mutex_lock(&conf->mutex); + list_for_each_entry(xprt, &conf->xprt_list, list) + { + if (strcmp(peerinfo->identifier, xprt->peerinfo.identifier)) + continue; + xprt->peerinfo.max_op_version = opversion; + } + pthread_mutex_unlock(&conf->mutex); + + if (conf->auth_modules == NULL) { + gf_msg(this->name, GF_LOG_ERROR, 0, PS_MSG_AUTH_INIT_FAILED, + "Authentication module not initialized"); + } + + ret = dict_get_str(params, "client-version", &clnt_version); + if (ret) + gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_VERSION_NOT_SET, + "client-version not set, may be of older version"); + + ret = gf_authenticate(params, config_params, conf->auth_modules); + + if (ret == AUTH_ACCEPT) { + /* Store options received from client side */ + req->trans->clnt_options = dict_ref(params); + + gf_msg(this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_ACCEPTED, + "accepted client from %s (version: %s)", client->client_uid, + (clnt_version) ? clnt_version : "old"); + + gf_event(EVENT_CLIENT_CONNECT, + "client_uid=%s;" + "client_identifier=%s;server_identifier=%s;" + "brick_path=%s;subdir_mount=%s", + client->client_uid, req->trans->peerinfo.identifier, + req->trans->myinfo.identifier, name, subdir_mount); + + op_ret = 0; + client->bound_xl = xl; + + /* Don't be confused by the below line (like how ERROR can + be Success), key checked on client is 'ERROR' and hence + we send 'Success' in this key */ + ret = dict_set_str(reply, "ERROR", "Success"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + } else { + gf_event(EVENT_CLIENT_AUTH_REJECT, + "client_uid=%s;" + "client_identifier=%s;server_identifier=%s;" + "brick_path=%s", + client->client_uid, req->trans->peerinfo.identifier, + req->trans->myinfo.identifier, name); + gf_msg(this->name, GF_LOG_ERROR, EACCES, PS_MSG_AUTHENTICATE_ERROR, + "Cannot authenticate client" + " from %s %s", + client->client_uid, (clnt_version) ? clnt_version : "old"); + + op_ret = -1; + op_errno = EACCES; + ret = dict_set_str(reply, "ERROR", "Authentication failed"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + goto fail; + } + + if (client->bound_xl == NULL) { + ret = dict_set_str(reply, "ERROR", + "Check volfile and handshake " + "options in protocol/client"); + if (ret < 0) + gf_msg_debug(this->name, 0, + "failed to set error " + "msg"); + + op_ret = -1; + op_errno = EACCES; + goto fail; + } + + LOCK(&conf->itable_lock); + { + if (client->bound_xl->itable == NULL) { + /* create inode table for this bound_xl, if one doesn't + already exist */ + + gf_msg_trace(this->name, 0, + "creating inode table with" + " lru_limit=%" PRId32 ", xlator=%s", + conf->inode_lru_limit, client->bound_xl->name); + + /* TODO: what is this ? */ + client->bound_xl->itable = inode_table_new(conf->inode_lru_limit, + client->bound_xl); } + } + UNLOCK(&conf->itable_lock); + + ret = dict_set_str(reply, "process-uuid", this->ctx->process_uuid); + if (ret) + gf_msg_debug(this->name, 0, "failed to set 'process-uuid'"); + + /* Insert a dummy key value pair to avoid failure at client side for + * clnt-lk-version with older clients. + */ + ret = dict_set_uint32(reply, "clnt-lk-version", 0); + if (ret) { + gf_msg(this->name, GF_LOG_WARNING, 0, PS_MSG_CLIENT_LK_VERSION_ERROR, + "failed to set " + "'clnt-lk-version'"); + } + + ret = dict_set_uint64(reply, "transport-ptr", ((uint64_t)(long)req->trans)); + if (ret) + gf_msg_debug(this->name, 0, "failed to set 'transport-ptr'"); - ret = dict_get_str (params, "client-version", &clnt_version); - if (ret) - gf_msg (this->name, GF_LOG_INFO, 0, - PS_MSG_CLIENT_VERSION_NOT_SET, - "client-version not set, may be of older version"); - - ret = gf_authenticate (params, config_params, - conf->auth_modules); - - if (ret == AUTH_ACCEPT) { - /* Store options received from client side */ - req->trans->clnt_options = dict_ref(params); - - gf_msg (this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_ACCEPTED, - "accepted client from %s (version: %s)", - client->client_uid, - (clnt_version) ? clnt_version : "old"); - - gf_event (EVENT_CLIENT_CONNECT, "client_uid=%s;" - "client_identifier=%s;server_identifier=%s;" - "brick_path=%s;subdir_mount=%s", - client->client_uid, - req->trans->peerinfo.identifier, - req->trans->myinfo.identifier, - name, subdir_mount); - - op_ret = 0; - client->bound_xl = xl; - - /* Don't be confused by the below line (like how ERROR can - be Success), key checked on client is 'ERROR' and hence - we send 'Success' in this key */ - ret = dict_set_str (reply, "ERROR", "Success"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); +fail: + /* It is important to validate the lookup on '/' as part of handshake, + because if lookup itself can't succeed, we should communicate this + to client. Very important in case of subdirectory mounts, where if + client is trying to mount a non-existing directory */ + if (op_ret >= 0 && client->bound_xl->itable) { + if (client->bound_xl->cleanup_starting) { + op_ret = -1; + op_errno = EAGAIN; + ret = dict_set_str(reply, "ERROR", + "cleanup flag is set for xlator " + "before call first_lookup Try again later"); } else { - gf_event (EVENT_CLIENT_AUTH_REJECT, "client_uid=%s;" - "client_identifier=%s;server_identifier=%s;" - "brick_path=%s", - client->client_uid, - req->trans->peerinfo.identifier, - req->trans->myinfo.identifier, - name); - gf_msg (this->name, GF_LOG_ERROR, EACCES, - PS_MSG_AUTHENTICATE_ERROR, "Cannot authenticate client" - " from %s %s", client->client_uid, - (clnt_version) ? clnt_version : "old"); - - op_ret = -1; - op_errno = EACCES; - ret = dict_set_str (reply, "ERROR", "Authentication failed"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); - goto fail; + op_ret = server_first_lookup(this, client, reply); + if (op_ret == -1) + op_errno = ENOENT; } - - if (client->bound_xl == NULL) { - ret = dict_set_str (reply, "ERROR", - "Check volfile and handshake " - "options in protocol/client"); - if (ret < 0) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); - + } + + rsp = GF_CALLOC(1, sizeof(gf_setvolume_rsp), gf_server_mt_setvolume_rsp_t); + GF_ASSERT(rsp); + + rsp->op_ret = 0; + rsp->dict.dict_len = dict_serialized_length(reply); + if (rsp->dict.dict_len) { + rsp->dict.dict_val = GF_CALLOC(1, rsp->dict.dict_len, + gf_server_mt_rsp_buf_t); + if (rsp->dict.dict_val) { + ret = dict_serialize(reply, rsp->dict.dict_val); + if (ret < 0) { + gf_msg_debug("server-handshake", 0, + "failed " + "to serialize reply dict"); op_ret = -1; - op_errno = EACCES; - goto fail; - } - - LOCK (&conf->itable_lock); - { - if (client->bound_xl->itable == NULL) { - /* create inode table for this bound_xl, if one doesn't - already exist */ - - gf_msg_trace (this->name, 0, "creating inode table with" - " lru_limit=%"PRId32", xlator=%s", - conf->inode_lru_limit, - client->bound_xl->name); - - /* TODO: what is this ? */ - client->bound_xl->itable = - inode_table_new (conf->inode_lru_limit, - client->bound_xl); - } + op_errno = -ret; + } } - UNLOCK (&conf->itable_lock); - - ret = dict_set_str (reply, "process-uuid", - this->ctx->process_uuid); - if (ret) - gf_msg_debug (this->name, 0, "failed to set 'process-uuid'"); - - /* Insert a dummy key value pair to avoid failure at client side for - * clnt-lk-version with older clients. + } + rsp->op_ret = op_ret; + rsp->op_errno = gf_errno_to_error(op_errno); + + /* if bound_xl is NULL or something fails, then put the connection + * back. Otherwise the connection would have been added to the + * list of connections the server is maintaining and might segfault + * during statedump when bound_xl of the connection is accessed. + */ + if (op_ret && !xl && (client != NULL)) { + /* We would have set the xl_private of the transport to the + * @conn. But if we have put the connection i.e shutting down + * the connection, then we should set xl_private to NULL as it + * would be pointing to a freed memory and would segfault when + * accessed upon getting DISCONNECT. */ - ret = dict_set_uint32 (reply, "clnt-lk-version", 0); - if (ret) { - gf_msg (this->name, GF_LOG_WARNING, 0, - PS_MSG_CLIENT_LK_VERSION_ERROR, "failed to set " - "'clnt-lk-version'"); - } - - ret = dict_set_uint64 (reply, "transport-ptr", - ((uint64_t) (long) req->trans)); - if (ret) - gf_msg_debug (this->name, 0, "failed to set 'transport-ptr'"); + gf_client_put(client, NULL); + req->trans->xl_private = NULL; + } -fail: - /* It is important to validate the lookup on '/' as part of handshake, - because if lookup itself can't succeed, we should communicate this - to client. Very important in case of subdirectory mounts, where if - client is trying to mount a non-existing directory */ - if (op_ret >= 0 && client->bound_xl->itable) { - if (client->bound_xl->cleanup_starting) { - op_ret = -1; - op_errno = EAGAIN; - ret = dict_set_str (reply, "ERROR", - "cleanup flag is set for xlator " - "before call first_lookup Try again later"); - } else { - op_ret = server_first_lookup (this, client, reply); - if (op_ret == -1) - op_errno = ENOENT; - } - } + /* Send the response properly */ + server_first_lookup_done(req, rsp); - rsp = GF_CALLOC (1, sizeof (gf_setvolume_rsp), - gf_server_mt_setvolume_rsp_t); - GF_ASSERT (rsp); - - rsp->op_ret = 0; - rsp->dict.dict_len = dict_serialized_length (reply); - if (rsp->dict.dict_len) { - rsp->dict.dict_val = GF_CALLOC (1, rsp->dict.dict_len, - gf_server_mt_rsp_buf_t); - if (rsp->dict.dict_val) { - ret = dict_serialize (reply, rsp->dict.dict_val); - if (ret < 0) { - gf_msg_debug ("server-handshake", 0, "failed " - "to serialize reply dict"); - op_ret = -1; - op_errno = -ret; - } - } - } - rsp->op_ret = op_ret; - rsp->op_errno = gf_errno_to_error (op_errno); + free(args.dict.dict_val); - /* if bound_xl is NULL or something fails, then put the connection - * back. Otherwise the connection would have been added to the - * list of connections the server is maintaining and might segfault - * during statedump when bound_xl of the connection is accessed. + dict_unref(params); + dict_unref(reply); + if (config_params) { + /* + * This might be null if we couldn't even find the translator + * (brick) to copy it from. */ - if (op_ret && !xl && (client != NULL)) { - /* We would have set the xl_private of the transport to the - * @conn. But if we have put the connection i.e shutting down - * the connection, then we should set xl_private to NULL as it - * would be pointing to a freed memory and would segfault when - * accessed upon getting DISCONNECT. - */ - gf_client_put (client, NULL); - req->trans->xl_private = NULL; - } + dict_unref(config_params); + } - /* Send the response properly */ - server_first_lookup_done (req, rsp); + GF_FREE(buf); - free (args.dict.dict_val); - - dict_unref (params); - dict_unref (reply); - if (config_params) { - /* - * This might be null if we couldn't even find the translator - * (brick) to copy it from. - */ - dict_unref (config_params); - } - - GF_FREE (buf); - - return 0; + return 0; } - int -server_ping (rpcsvc_request_t *req) +server_ping(rpcsvc_request_t *req) { - gf_common_rsp rsp = {0,}; + gf_common_rsp rsp = { + 0, + }; - /* Accepted */ - rsp.op_ret = 0; + /* Accepted */ + rsp.op_ret = 0; - server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, - (xdrproc_t)xdr_gf_common_rsp); + server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, + (xdrproc_t)xdr_gf_common_rsp); - return 0; + return 0; } int -server_set_lk_version (rpcsvc_request_t *req) +server_set_lk_version(rpcsvc_request_t *req) { - int ret = -1; - gf_set_lk_ver_req args = {0,}; - gf_set_lk_ver_rsp rsp = {0,}; - - ret = xdr_to_generic (req->msg[0], &args, - (xdrproc_t)xdr_gf_set_lk_ver_req); - if (ret < 0) { - /* failed to decode msg */ - req->rpc_err = GARBAGE_ARGS; - goto fail; - } - - rsp.lk_ver = args.lk_ver; + int ret = -1; + gf_set_lk_ver_req args = { + 0, + }; + gf_set_lk_ver_rsp rsp = { + 0, + }; + + ret = xdr_to_generic(req->msg[0], &args, (xdrproc_t)xdr_gf_set_lk_ver_req); + if (ret < 0) { + /* failed to decode msg */ + req->rpc_err = GARBAGE_ARGS; + goto fail; + } + + rsp.lk_ver = args.lk_ver; fail: - server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, - (xdrproc_t)xdr_gf_set_lk_ver_rsp); + server_submit_reply(NULL, req, &rsp, NULL, 0, NULL, + (xdrproc_t)xdr_gf_set_lk_ver_rsp); - free (args.uid); + free(args.uid); - return 0; + return 0; } rpcsvc_actor_t gluster_handshake_actors[GF_HNDSK_MAXVALUE] = { - [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, 0, DRC_NA}, - [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, 0, DRC_NA}, - [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA}, - [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, 0, DRC_NA}, - [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, server_set_lk_version, NULL, 0, DRC_NA}, + [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, 0, DRC_NA}, + [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, + NULL, 0, DRC_NA}, + [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, + DRC_NA}, + [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, 0, DRC_NA}, + [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, + server_set_lk_version, NULL, 0, DRC_NA}, }; - struct rpcsvc_program gluster_handshake_prog = { - .progname = "GlusterFS Handshake", - .prognum = GLUSTER_HNDSK_PROGRAM, - .progver = GLUSTER_HNDSK_VERSION, - .actors = gluster_handshake_actors, - .numactors = GF_HNDSK_MAXVALUE, + .progname = "GlusterFS Handshake", + .prognum = GLUSTER_HNDSK_PROGRAM, + .progver = GLUSTER_HNDSK_VERSION, + .actors = gluster_handshake_actors, + .numactors = GF_HNDSK_MAXVALUE, }; |