int32_t cli_cmd_volume_top_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; char *value = NULL; char *key = NULL; int ret = -1; gf1_cli_stats_op op = GF_CLI_STATS_NONE; gf1_cli_top_op top_op = GF_CLI_TOP_NONE; int32_t list_cnt = -1; int index = 0; int perf = 0; int32_t blk_size = 0; int32_t count = 0; char *delimiter = NULL; GF_ASSERT (words); GF_ASSERT (options); GF_ASSERT ((strcmp (words[0], "volume")) == 0); GF_ASSERT ((strcmp (words[1], "top")) == 0); dict = dict_new (); if (!dict) goto out; if (wordcount < 4) goto out; volname = (char *)words[2]; ret = dict_set_str (dict, "volname", volname); if (ret) goto out; op = GF_CLI_STATS_TOP; ret = dict_set_int32 (dict, "op", (int32_t)op); if (ret) goto out; if (strcmp (words[3], "open") == 0) { top_op = GF_CLI_TOP_OPEN; } else if (strcmp (words[3], "read") == 0) { top_op = GF_CLI_TOP_READ; } else if (strcmp (words[3], "write") == 0) { top_op = GF_CLI_TOP_WRITE; } else if (strcmp (words[3], "opendir") == 0) { top_op = GF_CLI_TOP_OPENDIR; } else if (strcmp (words[3], "readdir") == 0) { top_op = GF_CLI_TOP_READDIR; } else if (strcmp (words[3], "read-perf") == 0) { top_op = GF_CLI_TOP_READ_PERF; perf = 1; } else if (strcmp (words[3], "write-perf") == 0) { top_op = GF_CLI_TOP_WRITE_PERF; perf = 1; } else { ret = -1; goto out; } ret = dict_set_int32 (dict, "top-op", (int32_t)top_op); if (ret) goto out; for (index = 4; index < wordcount; index+=2) { key = (char *) words[index]; value = (char *) words[index+1]; if ( key && !value ) { ret = -1; goto out; } if (!strcmp (key, "brick")) { delimiter = strchr (value, ':'); if (!delimiter || delimiter == value || *(delimiter+1) != '/') { cli_out ("wrong brick type: %s, use <HOSTNAME>:" "<export-dir-abs-path>", value); ret = -1; goto out; } else { cli_path_strip_trailing_slashes (delimiter + 1); } ret = dict_set_str (dict, "brick", value); } else if (!strcmp (key, "list-cnt")) { ret = gf_is_str_int (value); if (!ret) list_cnt = atoi (value); if (ret || (list_cnt < 0) || (list_cnt > 100)) { cli_out ("list-cnt should be between 0 to 100"); ret = -1; goto out; } } else if (perf && !strcmp (key, "bs")) { ret = gf_is_str_int (value); if (!ret) blk_size = atoi (value); if (ret || (blk_size < 0)) { cli_out ("block size should be an integer " "greater than zero"); ret = -1; goto out; } ret = dict_set_int32 (dict, "blk-size", blk_size); } else if (perf && !strcmp (key, "count")) { ret = gf_is_str_int (value); if (!ret) count = atoi(value); if (ret || (count < 0)) { cli_out ("count should be an integer greater " "zero"); ret = -1; goto out; } ret = dict_set_int32 (dict, "blk-cnt", count); } else { ret = -1; goto out; } if (ret) { gf_log ("", GF_LOG_WARNING, "Dict set failed for " "key %s", key); goto out; } } if (list_cnt == -1) list_cnt = 100; ret = dict_set_int32 (dict, "list-cnt", list_cnt); if (ret) { gf_log ("", GF_LOG_WARNING, "Dict set failed for list_cnt"); goto out; } *options = dict; out: if (ret && dict) dict_destroy (dict); return ret; }
int cli_cmd_sys_exec_cbk (struct cli_state *state, struct cli_cmd_word *word, const char **words, int wordcount) { char cmd_arg_name[PATH_MAX] = ""; char *command = NULL; char *saveptr = NULL; char *tmp = NULL; int ret = -1; int i = -1; int cmd_args_count = 0; int in_cmd_args_count = 0; rpc_clnt_procedure_t *proc = NULL; call_frame_t *frame = NULL; dict_t *dict = NULL; cli_local_t *local = NULL; if (wordcount < 3) { cli_usage_out (word->pattern); goto out; } dict = dict_new (); if (!dict) goto out; command = strtok_r ((char *)words[2], " ", &saveptr); do { tmp = strtok_r (NULL, " ", &saveptr); if (tmp) { in_cmd_args_count++; memset (cmd_arg_name, '\0', sizeof(cmd_arg_name)); snprintf (cmd_arg_name, sizeof(cmd_arg_name), "cmd_arg_%d", in_cmd_args_count); ret = dict_set_str (dict, cmd_arg_name, tmp); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to set " "%s in dict", cmd_arg_name); goto out; } } } while (tmp); cmd_args_count = wordcount - 3; ret = dict_set_str (dict, "command", command); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to set command in dict"); goto out; } for (i=1; i <= cmd_args_count; i++) { in_cmd_args_count++; memset (cmd_arg_name, '\0', sizeof(cmd_arg_name)); snprintf (cmd_arg_name, sizeof(cmd_arg_name), "cmd_arg_%d", in_cmd_args_count); ret = dict_set_str (dict, cmd_arg_name, (char *)words[2+i]); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to set %s in dict", cmd_arg_name); goto out; } } ret = dict_set_int32 (dict, "cmd_args_count", in_cmd_args_count); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to set cmd_args_count in dict"); goto out; } ret = dict_set_str (dict, "volname", "N/A"); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to set volname in dict"); goto out; } proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SYS_EXEC]; if (proc && proc->fn) { frame = create_frame (THIS, THIS->ctx->pool); if (!frame) goto out; CLI_LOCAL_INIT (local, words, frame, dict); ret = proc->fn (frame, THIS, (void*)dict); } out: return ret; }
rbthash_table_t * rbthash_table_init (int buckets, rbt_hasher_t hfunc, rbt_data_destroyer_t dfunc, unsigned long expected_entries, struct mem_pool *entrypool) { rbthash_table_t *newtab = NULL; int ret = -1; if (!hfunc) { gf_log (GF_RBTHASH, GF_LOG_ERROR, "Hash function not given"); return NULL; } if (!entrypool && !expected_entries) { gf_log (GF_RBTHASH, GF_LOG_ERROR, "Both mem-pool and expected entries not provided"); return NULL; } if (entrypool && expected_entries) { gf_log (GF_RBTHASH, GF_LOG_ERROR, "Both mem-pool and expected entries are provided"); return NULL; } newtab = GF_CALLOC (1, sizeof (*newtab), gf_common_mt_rbthash_table_t); if (!newtab) return NULL; newtab->buckets = GF_CALLOC (buckets, sizeof (struct rbthash_bucket), gf_common_mt_rbthash_bucket); if (!newtab->buckets) { goto free_newtab; } if (expected_entries) { newtab->entrypool = mem_pool_new (rbthash_entry_t, expected_entries); if (!newtab->entrypool) { gf_log (GF_RBTHASH, GF_LOG_ERROR, "Failed to allocate mem-pool"); goto free_buckets; } newtab->pool_alloced = _gf_true; } else { newtab->entrypool = entrypool; } LOCK_INIT (&newtab->tablelock); newtab->numbuckets = buckets; ret = __rbthash_init_buckets (newtab, buckets); if (ret == -1) { gf_log (GF_RBTHASH, GF_LOG_ERROR, "Failed to init buckets"); if (newtab->pool_alloced) mem_pool_destroy (newtab->entrypool); } else { gf_log (GF_RBTHASH, GF_LOG_TRACE, "Inited hash table: buckets:" " %d", buckets); } newtab->hashfunc = hfunc; newtab->dfunc = dfunc; free_buckets: if (ret == -1) GF_FREE (newtab->buckets); free_newtab: if (ret == -1) { GF_FREE (newtab); newtab = NULL; } return newtab; }
int rpc_clnt_mgmt_pmap_signout (glusterfs_ctx_t *ctx, char *brickname) { int ret = 0; pmap_signout_req req = {0, }; call_frame_t *frame = NULL; cmd_args_t *cmd_args = NULL; char brick_name[PATH_MAX] = {0,}; struct iovec iov = {0, }; struct iobuf *iobuf = NULL; struct iobref *iobref = NULL; ssize_t xdr_size = 0; frame = create_frame (THIS, ctx->pool); cmd_args = &ctx->cmd_args; if (!cmd_args->brick_port && (!cmd_args->brick_name || !brickname)) { gf_log ("fsd-mgmt", GF_LOG_DEBUG, "portmapper signout arguments not given"); goto out; } if (cmd_args->volfile_server_transport && !strcmp(cmd_args->volfile_server_transport, "rdma")) { snprintf (brick_name, sizeof(brick_name), "%s.rdma", cmd_args->brick_name); req.brick = brick_name; } else { if (brickname) req.brick = brickname; else req.brick = cmd_args->brick_name; } req.port = cmd_args->brick_port; req.rdma_port = cmd_args->brick_port2; /* mgmt_submit_request is not available in libglusterfs. * Need to serialize and submit manually. */ iobref = iobref_new (); if (!iobref) { goto out; } xdr_size = xdr_sizeof ((xdrproc_t)xdr_pmap_signout_req, &req); iobuf = iobuf_get2 (ctx->iobuf_pool, xdr_size); if (!iobuf) { goto out; }; iobref_add (iobref, iobuf); iov.iov_base = iobuf->ptr; iov.iov_len = iobuf_pagesize (iobuf); /* Create the xdr payload */ ret = xdr_serialize_generic (iov, &req, (xdrproc_t)xdr_pmap_signout_req); if (ret == -1) { gf_log (THIS->name, GF_LOG_WARNING, "failed to create XDR payload"); goto out; } iov.iov_len = ret; ret = rpc_clnt_submit (ctx->mgmt, &clnt_pmap_signout_prog, GF_PMAP_SIGNOUT, mgmt_pmap_signout_cbk, &iov, 1, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); out: if (iobref) iobref_unref (iobref); if (iobuf) iobuf_unref (iobuf); return ret; }
int32_t gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value) { int32_t ret = -1; char *scan_str = NULL; char *iter_key = NULL; char *iter_val = NULL; char *free_str = NULL; struct stat st = {0,}; gf_store_op_errno_t store_errno = GD_STORE_SUCCESS; GF_ASSERT (handle); if (handle->locked == F_ULOCK) /* no locking is used handle->fd gets closed() after usage */ handle->fd = open (handle->path, O_RDWR); else /* handle->fd is valid already, kept open for lockf() */ lseek (handle->fd, 0, SEEK_SET); if (handle->fd == -1) { gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s", handle->path, strerror (errno)); goto out; } if (!handle->read) handle->read = fdopen (dup(handle->fd), "r"); else fseek (handle->read, 0, SEEK_SET); if (!handle->read) { gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s", handle->path, strerror (errno)); goto out; } ret = fstat (handle->fd, &st); if (ret < 0) { gf_log ("", GF_LOG_WARNING, "stat on file %s failed", handle->path); ret = -1; store_errno = GD_STORE_STAT_FAILED; goto out; } scan_str = GF_CALLOC (1, st.st_size, gf_common_mt_char); if (scan_str == NULL) { ret = -1; store_errno = GD_STORE_ENOMEM; goto out; } free_str = scan_str; do { ret = gf_store_read_and_tokenize (handle->read, scan_str, &iter_key, &iter_val, &store_errno); if (ret < 0) { gf_log ("", GF_LOG_TRACE, "error while reading key " "'%s': %s", key, gf_store_strerror (store_errno)); goto out; } gf_log ("", GF_LOG_TRACE, "key %s read", iter_key); if (!strcmp (key, iter_key)) { gf_log ("", GF_LOG_DEBUG, "key %s found", key); ret = 0; if (iter_val) *value = gf_strdup (iter_val); goto out; } } while (1); out: if (handle->read) { fclose (handle->read); handle->read = NULL; } if (handle->fd > 0 && handle->locked == F_ULOCK) { /* only invalidate handle->fd if not locked */ close (handle->fd); } GF_FREE (free_str); return ret; }
int32_t gf_resolve_ip6 (const char *hostname, uint16_t port, int family, void **dnscache, struct addrinfo **addr_info) { int32_t ret = 0; struct addrinfo hints; struct dnscache6 *cache = NULL; char service[NI_MAXSERV], host[NI_MAXHOST]; if (!hostname) { gf_log_callingfn ("resolver", GF_LOG_WARNING, "hostname is NULL"); return -1; } if (!*dnscache) { *dnscache = GF_CALLOC (1, sizeof (struct dnscache6), gf_common_mt_dnscache6); if (!*dnscache) return -1; } cache = *dnscache; if (cache->first && !cache->next) { freeaddrinfo(cache->first); cache->first = cache->next = NULL; gf_log ("resolver", GF_LOG_TRACE, "flushing DNS cache"); } if (!cache->first) { char *port_str = NULL; gf_log ("resolver", GF_LOG_TRACE, "DNS cache not present, freshly probing hostname: %s", hostname); memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; ret = gf_asprintf (&port_str, "%d", port); if (-1 == ret) { gf_log ("resolver", GF_LOG_ERROR, "asprintf failed"); return -1; } if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) { gf_log ("resolver", GF_LOG_ERROR, "getaddrinfo failed (%s)", gai_strerror (ret)); GF_FREE (*dnscache); *dnscache = NULL; GF_FREE (port_str); return -1; } GF_FREE (port_str); cache->next = cache->first; } if (cache->next) { ret = getnameinfo((struct sockaddr *)cache->next->ai_addr, cache->next->ai_addrlen, host, sizeof (host), service, sizeof (service), NI_NUMERICHOST); if (ret != 0) { gf_log ("resolver", GF_LOG_ERROR, "getnameinfo failed (%s)", gai_strerror (ret)); goto err; } gf_log ("resolver", GF_LOG_DEBUG, "returning ip-%s (port-%s) for hostname: %s and port: %d", host, service, hostname, port); *addr_info = cache->next; } if (cache->next) cache->next = cache->next->ai_next; if (cache->next) { ret = getnameinfo((struct sockaddr *)cache->next->ai_addr, cache->next->ai_addrlen, host, sizeof (host), service, sizeof (service), NI_NUMERICHOST); if (ret != 0) { gf_log ("resolver", GF_LOG_ERROR, "getnameinfo failed (%s)", gai_strerror (ret)); goto err; } gf_log ("resolver", GF_LOG_DEBUG, "next DNS query will return: ip-%s port-%s", host, service); } return 0; err: freeaddrinfo (cache->first); cache->first = cache->next = NULL; GF_FREE (cache); *dnscache = NULL; return -1; }
auth_result_t gf_auth (dict_t *input_params, dict_t *config_params) { auth_result_t result = AUTH_DONT_CARE; int ret = 0; char *name = NULL; char *searchstr = NULL; peer_info_t *peer_info = NULL; data_t *peer_info_data = NULL; data_t *allow_addr = NULL; data_t *reject_addr = NULL; char *service = NULL; uint16_t peer_port = 0; char peer_addr[UNIX_PATH_MAX] = {0,}; char *type = NULL; gf_boolean_t allow_insecure = _gf_false; char *subdir = NULL; name = data_to_str (dict_get (input_params, "remote-subvolume")); if (!name) { gf_log ("authenticate/addr", GF_LOG_DEBUG, "remote-subvolume not specified"); goto out; } ret = gf_asprintf (&searchstr, "auth.addr.%s.allow", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_DEBUG, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); ret = gf_asprintf (&searchstr, "auth.addr.%s.reject", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } reject_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); if (!allow_addr) { /* TODO: backward compatibility */ ret = gf_asprintf (&searchstr, "auth.ip.%s.allow", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); } if (!(allow_addr || reject_addr)) { gf_log ("auth/addr", GF_LOG_DEBUG, "none of the options auth.addr.%s.allow or " "auth.addr.%s.reject specified, returning auth_dont_care", name, name); goto out; } peer_info_data = dict_get (input_params, "peer-info"); if (!peer_info_data) { gf_log ("auth/addr", GF_LOG_ERROR, "peer-info not present"); goto out; } ret = dict_get_str (input_params, "subdir-mount", &subdir); if (ret) { subdir = "/"; } peer_info = data_to_ptr (peer_info_data); switch (((struct sockaddr *) &peer_info->sockaddr)->sa_family) { case AF_INET_SDP: case AF_INET: case AF_INET6: strcpy (peer_addr, peer_info->identifier); service = strrchr (peer_addr, ':'); *service = '\0'; service++; ret = dict_get_str (config_params, "rpc-auth-allow-insecure", &type); if (ret == 0) { ret = gf_string2boolean (type, &allow_insecure); if (ret < 0) { gf_log ("auth/addr", GF_LOG_WARNING, "rpc-auth-allow-insecure option %s " "is not a valid bool option", type); goto out; } } peer_port = atoi (service); if (peer_port >= PRIVILEGED_PORT_CEILING && !allow_insecure) { gf_log ("auth/addr", GF_LOG_ERROR, "client is bound to port %d which is not privileged", peer_port); result = AUTH_REJECT; goto out; } break; case AF_UNIX: strcpy (peer_addr, peer_info->identifier); break; default: gf_log ("authenticate/addr", GF_LOG_ERROR, "unknown address family %d", ((struct sockaddr *) &peer_info->sockaddr)->sa_family); goto out; } if (reject_addr) { parse_entries_and_compare (reject_addr->data, peer_addr, name, subdir, &result, AUTH_REJECT); if (result == AUTH_REJECT) goto out; } if (allow_addr) { parse_entries_and_compare (allow_addr->data, peer_addr, name, subdir, &result, AUTH_ACCEPT); } out: return result; }
int32_t cli_cmd_volume_replace_brick_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; char *op = NULL; int op_index = 0; char *delimiter = NULL; gf1_cli_replace_op replace_op = GF_REPLACE_OP_NONE; GF_ASSERT (words); GF_ASSERT (options); GF_ASSERT ((strcmp (words[0], "volume")) == 0); GF_ASSERT ((strcmp (words[1], "replace-brick")) == 0); dict = dict_new (); if (!dict) goto out; if (wordcount < 3) goto out; volname = (char *)words[2]; GF_ASSERT (volname); ret = dict_set_str (dict, "volname", volname); if (ret) goto out; if (wordcount < 4) { ret = -1; goto out; } delimiter = strchr ((char *)words[3], ':'); if (!delimiter || delimiter == words[3] || *(delimiter+1) != '/') { cli_out ("wrong brick type: %s, use " "<HOSTNAME>:<export-dir-abs-path>", words[3]); ret = -1; goto out; } else { cli_path_strip_trailing_slashes (delimiter + 1); } ret = dict_set_str (dict, "src-brick", (char *)words[3]); if (ret) goto out; if (wordcount < 5) { ret = -1; goto out; } delimiter = strchr ((char *)words[4], ':'); if (!delimiter || delimiter == words[4] || *(delimiter+1) != '/') { cli_out ("wrong brick type: %s, use " "<HOSTNAME>:<export-dir-abs-path>", words[4]); ret = -1; goto out; } else { cli_path_strip_trailing_slashes (delimiter + 1); } ret = dict_set_str (dict, "dst-brick", (char *)words[4]); if (ret) goto out; op_index = 5; if ((wordcount < (op_index + 1))) { ret = -1; goto out; } op = (char *) words[op_index]; if (!strcasecmp ("start", op)) { replace_op = GF_REPLACE_OP_START; } else if (!strcasecmp ("commit", op)) { replace_op = GF_REPLACE_OP_COMMIT; } else if (!strcasecmp ("pause", op)) { replace_op = GF_REPLACE_OP_PAUSE; } else if (!strcasecmp ("abort", op)) { replace_op = GF_REPLACE_OP_ABORT; } else if (!strcasecmp ("status", op)) { replace_op = GF_REPLACE_OP_STATUS; } /* commit force option */ op_index = 6; if (wordcount > (op_index + 1)) { ret = -1; goto out; } if (wordcount == (op_index + 1)) { op = (char *) words[op_index]; if (!strcasecmp ("force", op)) { replace_op = GF_REPLACE_OP_COMMIT_FORCE; } } if (replace_op == GF_REPLACE_OP_NONE) { ret = -1; goto out; } ret = dict_set_int32 (dict, "operation", (int32_t) replace_op); if (ret) goto out; *options = dict; out: if (ret) { gf_log ("cli", GF_LOG_ERROR, "Unable to parse remove-brick CLI"); if (dict) dict_destroy (dict); } return ret; }
static int glusterd_handle_post_validate_fn (rpcsvc_request_t *req) { int32_t ret = -1; gd1_mgmt_v3_post_val_req op_req = {{0},}; xlator_t *this = NULL; char *op_errstr = NULL; dict_t *dict = NULL; dict_t *rsp_dict = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); ret = xdr_to_generic (req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_v3_post_val_req); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "Failed to decode post validation " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) { gf_log (this->name, GF_LOG_WARNING, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (op_req.uuid)); ret = -1; goto out; } dict = dict_new (); if (!dict) goto out; ret = dict_unserialize (op_req.dict.dict_val, op_req.dict.dict_len, &dict); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to unserialize the dictionary"); goto out; } rsp_dict = dict_new (); if (!rsp_dict) { gf_log (this->name, GF_LOG_ERROR, "Failed to get new dictionary"); return -1; } ret = gd_mgmt_v3_post_validate_fn (op_req.op, op_req.op_ret, dict, &op_errstr, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Post Validation failed on operation %s", gd_op_list[op_req.op]); } ret = glusterd_mgmt_v3_post_validate_send_resp (req, op_req.op, ret, op_errstr, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to send Post Validation " "response for operation %s", gd_op_list[op_req.op]); goto out; } out: if (op_errstr && (strcmp (op_errstr, ""))) GF_FREE (op_errstr); free (op_req.dict.dict_val); if (dict) dict_unref (dict); if (rsp_dict) dict_unref (rsp_dict); /* Return 0 from handler to avoid double deletion of req obj */ return 0; }
int32_t cli_cmd_volume_add_brick_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; int brick_count = 0, brick_index = 0; char *bricks = NULL; GF_ASSERT (words); GF_ASSERT (options); GF_ASSERT ((strcmp (words[0], "volume")) == 0); GF_ASSERT ((strcmp (words[1], "add-brick")) == 0); dict = dict_new (); if (!dict) goto out; if (wordcount < 3) goto out; volname = (char *)words[2]; GF_ASSERT (volname); ret = dict_set_str (dict, "volname", volname); if (ret) goto out; if (wordcount < 4) { ret = -1; goto out; } brick_index = 3; ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks, &brick_count); if (ret) goto out; ret = dict_set_dynstr (dict, "bricks", bricks); if (ret) goto out; ret = dict_set_int32 (dict, "count", brick_count); if (ret) goto out; *options = dict; out: if (ret) { gf_log ("cli", GF_LOG_ERROR, "Unable to parse add-brick CLI"); if (dict) dict_destroy (dict); } return ret; }
int32_t cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; char *delimiter = NULL; int ret = -1; char key[50]; int brick_count = 0, brick_index = 0; int32_t tmp_index = 0; int32_t j = 0; char *tmp_brick = NULL; char *tmp_brick1 = NULL; GF_ASSERT (words); GF_ASSERT (options); GF_ASSERT ((strcmp (words[0], "volume")) == 0); GF_ASSERT ((strcmp (words[1], "remove-brick")) == 0); dict = dict_new (); if (!dict) goto out; if (wordcount < 3) goto out; volname = (char *)words[2]; GF_ASSERT (volname); ret = dict_set_str (dict, "volname", volname); if (ret) goto out; if (wordcount < 4) { ret = -1; goto out; } brick_index = 3; if (ret) goto out; tmp_index = brick_index; tmp_brick = GF_MALLOC(2048 * sizeof(*tmp_brick), gf_common_mt_char); if (!tmp_brick) { gf_log ("",GF_LOG_ERROR,"cli_cmd_volume_remove_brick_parse: " "Unable to get memory"); ret = -1; goto out; } tmp_brick1 = GF_MALLOC(2048 * sizeof(*tmp_brick1), gf_common_mt_char); if (!tmp_brick1) { gf_log ("",GF_LOG_ERROR,"cli_cmd_volume_remove_brick_parse: " "Unable to get memory"); ret = -1; goto out; } while (brick_index < wordcount) { delimiter = strchr(words[brick_index], ':'); if (!delimiter || delimiter == words[brick_index] || *(delimiter+1) != '/') { cli_out ("wrong brick type: %s, use <HOSTNAME>:" "<export-dir-abs-path>", words[brick_index]); ret = -1; goto out; } else { cli_path_strip_trailing_slashes (delimiter + 1); } j = tmp_index; strcpy(tmp_brick, words[brick_index]); while ( j < brick_index) { strcpy(tmp_brick1, words[j]); if (!(strcmp (tmp_brick, tmp_brick1))) { gf_log("",GF_LOG_ERROR, "Duplicate bricks" " found %s", words[brick_index]); cli_out("Duplicate bricks found %s", words[brick_index]); ret = -1; goto out; } j++; } snprintf (key, 50, "brick%d", ++brick_count); ret = dict_set_str (dict, key, (char *)words[brick_index++]); if (ret) goto out; } ret = dict_set_int32 (dict, "count", brick_count); if (ret) goto out; *options = dict; out: if (ret) { gf_log ("cli", GF_LOG_ERROR, "Unable to parse remove-brick CLI"); if (dict) dict_destroy (dict); } if (tmp_brick) GF_FREE (tmp_brick); if (tmp_brick1) GF_FREE (tmp_brick1); return ret; }
int32_t cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index, char **bricks, int *brick_count) { int ret = 0; char *tmp_list = NULL; char brick_list[120000] = {0,}; char *space = " "; char *delimiter = NULL; char *host_name = NULL; char *tmp = NULL; char *free_list_ptr = NULL; char *tmpptr = NULL; int j = 0; int brick_list_len = 0; GF_ASSERT (words); GF_ASSERT (wordcount); GF_ASSERT (bricks); GF_ASSERT (brick_index > 0); GF_ASSERT (brick_index < wordcount); strncpy (brick_list, space, strlen (space)); brick_list_len++; while (brick_index < wordcount) { delimiter = strchr (words[brick_index], ':'); if (!delimiter || delimiter == words[brick_index] || *(delimiter+1) != '/') { cli_out ("wrong brick type: %s, use <HOSTNAME>:" "<export-dir-abs-path>", words[brick_index]); ret = -1; goto out; } else { cli_path_strip_trailing_slashes (delimiter + 1); } if ((brick_list_len + strlen (words[brick_index]) + 1) > sizeof (brick_list)) { gf_log ("cli", GF_LOG_ERROR, "total brick list is larger than a request " "can take (brick_count %d)", *brick_count); ret = -1; goto out; } host_name = gf_strdup (words[brick_index]); if (!host_name) { ret = -1; gf_log("cli",GF_LOG_ERROR, "Unable to allocate " "memory"); goto out; } strtok_r (host_name, ":", &tmp); if (!(strcmp (host_name, "localhost") && strcmp (host_name, "127.0.0.1"))) { cli_out ("Please provide a valid hostname/ip other " "than localhost or 127.0.0.1"); ret = -1; GF_FREE (host_name); goto out; } if (!valid_host_name(host_name, strlen(host_name))) { cli_out ("internet address '%s' does not comform to " "standards", host_name); } GF_FREE (host_name); tmp_list = gf_strdup (brick_list + 1); if (free_list_ptr) { GF_FREE (free_list_ptr); free_list_ptr = NULL; } free_list_ptr = tmp_list; j = 0; while(j < *brick_count) { strtok_r (tmp_list, " ", &tmpptr); if (!(strcmp (tmp_list, words[brick_index]))) { ret = -1; cli_out ("Found duplicate" " exports %s",words[brick_index]); goto out; } tmp_list = tmpptr; j++; } strcat (brick_list, words[brick_index]); strcat (brick_list, " "); brick_list_len += (strlen (words[brick_index]) + 1); ++(*brick_count); ++brick_index; } *bricks = gf_strdup (brick_list); if (!*bricks) ret = -1; out: if (free_list_ptr) GF_FREE (free_list_ptr); return ret; }
int32_t cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; int i = 0; char key[20] = {0, }; gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE; GF_ASSERT (words); GF_ASSERT (options); GF_ASSERT ((strcmp (words[0], "volume")) == 0); GF_ASSERT ((strcmp (words[1], "quota")) == 0); dict = dict_new (); if (!dict) goto out; if (wordcount < 4) goto out; volname = (char *)words[2]; if (!volname) { ret = -1; goto out; } /* Validate the volume name here itself */ { if (volname[0] == '-') goto out; if (!strcmp (volname, "all")) { cli_out ("\"all\" cannot be the name of a volume."); goto out; } if (strchr (volname, '/')) goto out; if (strlen (volname) > 512) goto out; for (i = 0; i < strlen (volname); i++) if (!isalnum (volname[i]) && (volname[i] != '_') && (volname[i] != '-')) goto out; } ret = dict_set_str (dict, "volname", volname); if (ret) goto out; if ((strcasecmp (words[3], "enable")) == 0) { type = GF_QUOTA_OPTION_TYPE_ENABLE; goto set_type; } if (strcasecmp (words[3], "disable") == 0) { type = GF_QUOTA_OPTION_TYPE_DISABLE; goto set_type; } if (strcasecmp (words[3], "limit-usage") == 0) { if (wordcount != 6) { ret = -1; goto out; } type = GF_QUOTA_OPTION_TYPE_LIMIT_USAGE; if (words[4][0] != '/') { cli_out ("Please enter absolute path"); return -2; } ret = dict_set_str (dict, "path", (char *) words[4]); if (ret) goto out; if (!words[5]) { gf_log ("cli", GF_LOG_ERROR, "Please enter the limit value " "to be set"); return -2; } ret = dict_set_str (dict, "limit", (char *) words[5]); if (ret) goto out; goto set_type; } if (strcasecmp (words[3], "remove") == 0) { if (wordcount != 5) { ret = -1; goto out; } type = GF_QUOTA_OPTION_TYPE_REMOVE; if (words[4][0] != '/') { cli_out ("Please enter absolute path"); return -2; } ret = dict_set_str (dict, "path", (char *) words[4]); if (ret) goto out; goto set_type; } if (strcasecmp (words[3], "list") == 0) { if (wordcount < 4) { ret = -1; goto out; } type = GF_QUOTA_OPTION_TYPE_LIST; i = 4; while (i < wordcount) { snprintf (key, 20, "path%d", i-4); ret = dict_set_str (dict, key, (char *) words [i++]); if (ret < 0) goto out; } ret = dict_set_int32 (dict, "count", i - 4); if (ret < 0) goto out; goto set_type; } if (strcasecmp (words[3], "version") == 0) { type = GF_QUOTA_OPTION_TYPE_VERSION; } else { ret = -1; goto out; } set_type: ret = dict_set_int32 (dict, "type", type); if (ret) goto out; *options = dict; out: if (ret) { if (dict) dict_destroy (dict); } return ret; }
int32_t cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; gf1_cluster_type type = GF_CLUSTER_TYPE_NONE; int count = 1; int brick_index = 0; int i = 0; char *trans_type = NULL; int32_t index = 0; char *bricks = NULL; int32_t brick_count = 0; GF_ASSERT (words); GF_ASSERT (options); GF_ASSERT ((strcmp (words[0], "volume")) == 0); GF_ASSERT ((strcmp (words[1], "create")) == 0); dict = dict_new (); if (!dict) goto out; if (wordcount < 3) goto out; volname = (char *)words[2]; GF_ASSERT (volname); /* Validate the volume name here itself */ { if (volname[0] == '-') goto out; if (!strcmp (volname, "all")) { cli_out ("\"all\" cannot be the name of a volume."); goto out; } if (strchr (volname, '/')) goto out; if (strlen (volname) > 512) goto out; for (i = 0; i < strlen (volname); i++) if (!isalnum (volname[i]) && (volname[i] != '_') && (volname[i] != '-')) goto out; } ret = dict_set_str (dict, "volname", volname); if (ret) goto out; if (wordcount < 4) { ret = -1; goto out; } if ((strcasecmp (words[3], "replica")) == 0) { type = GF_CLUSTER_TYPE_REPLICATE; if (wordcount < 5) { ret = -1; goto out; } count = strtol (words[4], NULL, 0); if (!count || (count < 2)) { cli_out ("replica count should be greater than 1"); ret = -1; goto out; } ret = dict_set_int32 (dict, "replica-count", count); if (ret) goto out; brick_index = 5; } else if ((strcasecmp (words[3], "stripe")) == 0) { type = GF_CLUSTER_TYPE_STRIPE; if (wordcount < 5) { ret = -1; goto out; } count = strtol (words[4], NULL, 0); if (!count || (count < 2)) { cli_out ("stripe count should be greater than 1"); ret = -1; goto out; } ret = dict_set_int32 (dict, "stripe-count", count); if (ret) goto out; brick_index = 5; } else { type = GF_CLUSTER_TYPE_NONE; brick_index = 3; } ret = dict_set_int32 (dict, "type", type); if (ret) goto out; if (type) index = 5; else index = 3; if (wordcount < (index + 1)) { ret = -1; goto out; } if (strcasecmp(words[index], "transport") == 0) { brick_index = index+2; if (wordcount < (index + 2)) { ret = -1; goto out; } if ((strcasecmp (words[index+1], "tcp") == 0)) { trans_type = gf_strdup ("tcp"); } else if ((strcasecmp (words[index+1], "rdma") == 0)) { trans_type = gf_strdup ("rdma"); } else if ((strcasecmp (words[index+1], "tcp,rdma") == 0) || (strcasecmp (words[index+1], "rdma,tcp") == 0)) { trans_type = gf_strdup ("tcp,rdma"); } else { gf_log ("", GF_LOG_ERROR, "incorrect transport" " protocol specified"); ret = -1; goto out; } } else { trans_type = gf_strdup ("tcp"); } ret = dict_set_dynstr (dict, "transport", trans_type); if (ret) goto out; ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks, &brick_count); if (ret) goto out; /* If brick-count is not valid when replica or stripe is given, exit here */ if (!brick_count) { cli_out ("No bricks specified"); ret = -1; goto out; } if (brick_count % count) { if (type == GF_CLUSTER_TYPE_STRIPE) cli_out ("number of bricks is not a multiple of " "stripe count"); else if (type == GF_CLUSTER_TYPE_REPLICATE) cli_out ("number of bricks is not a multiple of " "replica count"); ret = -1; goto out; } ret = dict_set_dynstr (dict, "bricks", bricks); if (ret) goto out; ret = dict_set_int32 (dict, "count", brick_count); if (ret) goto out; *options = dict; out: if (ret) { gf_log ("cli", GF_LOG_ERROR, "Unable to parse create volume CLI"); if (dict) dict_destroy (dict); } return ret; }
int gf_fuse_mount (const char *mountpoint, char *fsname, unsigned long mountflags, char *mnt_param, pid_t *mnt_pid, int status_fd) /* Not used on OS X */ /* int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param, pid_t *mtab_pid) */ { int fd, pid; int result; char *fdnam, *dev; const char *mountprog = OSXFUSE_MOUNT_PROG; sig_t chldf; /* mount_fusefs should not try to spawn the daemon */ setenv("MOUNT_FUSEFS_SAFE", "1", 1); /* to notify mount_fusefs it's called from lib */ setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1); if (!mountpoint) { fprintf(stderr, "missing or invalid mount point\n"); return -1; } if (fuse_running_under_rosetta()) { fprintf(stderr, "MacFUSE does not work under Rosetta\n"); return -1; } chldf = signal(SIGCHLD, SIG_DFL); /* So that we can wait4() below. */ result = loadkmod(); if (result == EINVAL) GFFUSE_LOGERR("OS X >= 10.5 (at least Leopard) required"); else if (result == 0 || result == ENOENT || result == EBUSY) { /* Module loaded, but now need to check for user<->kernel match. */ char version[MAXHOSTNAMELEN + 1] = { 0 }; size_t version_len = MAXHOSTNAMELEN; size_t version_len_desired = 0; result = sysctlbyname(SYSCTL_OSXFUSE_VERSION_NUMBER , version, &version_len, NULL, (size_t)0); if (result == 0) { /* sysctlbyname() includes the trailing '\0' in version_len */ version_len_desired = strlen("2.x.y") + 1; if (version_len != version_len_desired) result = -1; } else strcpy(version, "?.?.?"); if (result == 0) { char *ep; char vstr[4]; unsigned vval; int i; for (i = 0; i < 3; i++) vstr[i] = version[2*i]; vstr[3] = '\0'; vval = strtoul(vstr, &ep, 10); if (*ep || vval < 203 || vval > 217) result = -1; else gf_log("glusterfs-fuse", GF_LOG_INFO, "MacFUSE kext version %s", version); } // TODO Bypass version check result = 0; if (result != 0) GFFUSE_LOGERR("MacFUSE version %s is not supported", version); } else GFFUSE_LOGERR("cannot load MacFUSE kext"); if (result != 0) return -1; fdnam = getenv("FUSE_DEV_FD"); if (fdnam) { char *ep; fd = strtol(fdnam, &ep, 10); if (*ep != '\0' || fd < 0) { GFFUSE_LOGERR("invalid value given in FUSE_DEV_FD"); return -1; } goto mount; } dev = getenv("FUSE_DEV_NAME"); if (dev) { if ((fd = open(dev, O_RDWR)) < 0) { GFFUSE_LOGERR("failed to open device (%s)", strerror(errno)); return -1; } } else { int r, devidx = -1; char devpath[MAXPATHLEN]; for (r = 0; r < OSXFUSE_NDEVICES; r++) { snprintf(devpath, MAXPATHLEN - 1, _PATH_DEV OSXFUSE_DEVICE_BASENAME "%d", r); fd = open(devpath, O_RDWR); if (fd >= 0) { dev = devpath; devidx = r; break; } } if (devidx == -1) { GFFUSE_LOGERR("failed to open device (%s)", strerror(errno)); return -1; } } mount: if (getenv("FUSE_NO_MOUNT") || ! mountpoint) goto out; signal(SIGCHLD, chldf); pid = fork(); if (pid == -1) { GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); close(fd); return -1; } if (pid == 0) { pid = fork(); if (pid == -1) { GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); close(fd); exit(1); } if (pid == 0) { const char *argv[32]; int a = 0; char *opts = NULL; if (asprintf(&opts, "%s,fssubtype=glusterfs", mnt_param) == -1) { GFFUSE_LOGERR("Out of memory"); exit(1); } if (! fdnam) asprintf(&fdnam, "%d", fd); argv[a++] = mountprog; if (opts) { argv[a++] = "-o"; argv[a++] = opts; } argv[a++] = fdnam; argv[a++] = mountpoint; argv[a++] = NULL; { char title[MAXPATHLEN + 1] = { 0 }; u_int32_t len = MAXPATHLEN; int ret = proc_pidpath(getpid(), title, len); if (ret) { setenv("MOUNT_FUSEFS_DAEMON_PATH", title, 1); } } execvp(mountprog, (char **) argv); GFFUSE_LOGERR("MacFUSE: failed to exec mount program (%s)", strerror(errno)); exit(1); } _exit(0); } out: return fd; }
static int glusterd_handle_mgmt_v3_unlock_fn (rpcsvc_request_t *req) { gd1_mgmt_v3_unlock_req lock_req = {{0},}; int32_t ret = -1; glusterd_op_lock_ctx_t *ctx = NULL; xlator_t *this = NULL; gf_boolean_t is_synctasked = _gf_false; gf_boolean_t free_ctx = _gf_false; this = THIS; GF_ASSERT (this); GF_ASSERT (req); ret = xdr_to_generic (req->msg[0], &lock_req, (xdrproc_t)xdr_gd1_mgmt_v3_unlock_req); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "Failed to decode unlock " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } gf_log (this->name, GF_LOG_DEBUG, "Received volume unlock req " "from uuid: %s", uuid_utoa (lock_req.uuid)); if (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL) { gf_log (this->name, GF_LOG_WARNING, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (lock_req.uuid)); ret = -1; goto out; } ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_lock_ctx_t); if (!ctx) { ret = -1; goto out; } gf_uuid_copy (ctx->uuid, lock_req.uuid); ctx->req = req; ctx->dict = dict_new (); if (!ctx->dict) { ret = -1; goto out; } ret = dict_unserialize (lock_req.dict.dict_val, lock_req.dict.dict_len, &ctx->dict); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to unserialize the dictionary"); goto out; } is_synctasked = dict_get_str_boolean (ctx->dict, "is_synctasked", _gf_false); if (is_synctasked) { ret = glusterd_syctasked_mgmt_v3_unlock (req, &lock_req, ctx); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to release mgmt_v3_locks"); /* Ignore the return code, as it shouldn't be propagated * from the handler function so as to avoid double * deletion of the req */ ret = 0; } /* The above function does not take ownership of ctx. * Therefore we need to free the ctx explicitly. */ free_ctx = _gf_true; } else { /* Shouldn't ignore the return code here, and it should * be propagated from the handler function as in failure * case it doesn't delete the req object */ ret = glusterd_op_state_machine_mgmt_v3_unlock (req, &lock_req, ctx); if (ret) gf_log (this->name, GF_LOG_ERROR, "Failed to release mgmt_v3_locks"); } out: if (ctx && (ret || free_ctx)) { if (ctx->dict) dict_unref (ctx->dict); GF_FREE (ctx); } free (lock_req.dict.dict_val); gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); return ret; }
struct glfs_object * glfs_h_create_from_handle (struct glfs *fs, unsigned char *handle, int len, struct stat *stat) { loc_t loc = {0, }; int ret = -1; struct iatt iatt = {0, }; inode_t *newinode = NULL; xlator_t *subvol = NULL; struct glfs_object *object = NULL; /* validate in args */ if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) { errno = EINVAL; return NULL; } __glfs_entry_fs (fs); /* get the active volume */ subvol = glfs_active_subvol (fs); if (!subvol) { errno = EIO; goto out; } memcpy (loc.gfid, handle, GFAPI_HANDLE_LENGTH); newinode = inode_find (subvol->itable, loc.gfid); if (newinode) loc.inode = newinode; else { loc.inode = inode_new (subvol->itable); if (!loc.inode) { errno = ENOMEM; goto out; } } ret = syncop_lookup (subvol, &loc, 0, &iatt, 0, 0); DECODE_SYNCOP_ERR (ret); if (ret) { gf_log (subvol->name, GF_LOG_WARNING, "inode refresh of %s failed: %s", uuid_utoa (loc.gfid), strerror (errno)); goto out; } newinode = inode_link (loc.inode, 0, 0, &iatt); if (newinode) inode_lookup (newinode); else { gf_log (subvol->name, GF_LOG_WARNING, "inode linking of %s failed: %s", uuid_utoa (loc.gfid), strerror (errno)); errno = EINVAL; goto out; } /* populate stat */ if (stat) glfs_iatt_to_stat (fs, &iatt, stat); object = GF_CALLOC (1, sizeof(struct glfs_object), glfs_mt_glfs_object_t); if (object == NULL) { errno = ENOMEM; ret = -1; goto out; } /* populate the return object */ object->inode = newinode; uuid_copy (object->gfid, object->inode->gfid); out: /* TODO: Check where the inode ref is being held? */ loc_wipe (&loc); glfs_subvol_done (fs, subvol); return object; }
int rpc_clnt_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { struct rpc_clnt *rpc = NULL; xlator_t *this = NULL; rpc_clnt_connection_t *conn = NULL; call_frame_t *frame = NULL; struct timespec timeout = {0, }; if (!myframe) { gf_log (THIS->name, GF_LOG_WARNING, "frame with the request is NULL"); goto out; } frame = myframe; this = frame->this; rpc = frame->local; frame->local = NULL; /* Prevent STACK_DESTROY from segfaulting */ conn = &rpc->conn; pthread_mutex_lock (&conn->lock); { if (req->rpc_status == -1) { if (conn->ping_timer != NULL) { gf_log (this->name, GF_LOG_WARNING, "socket or ib related error"); gf_timer_call_cancel (rpc->ctx, conn->ping_timer); conn->ping_timer = NULL; rpc_clnt_unref (rpc); } else { /* timer expired and transport bailed out */ gf_log (this->name, GF_LOG_WARNING, "socket disconnected"); } conn->ping_started = 0; goto unlock; } /*This allows other RPCs to be able to start the ping timer * if they come by before the following start ping routine * is executed by the timer thread.*/ conn->ping_started = 0; gf_timer_call_cancel (this->ctx, conn->ping_timer); timeout.tv_sec = conn->ping_timeout; timeout.tv_nsec = 0; rpc_clnt_ref (rpc); conn->ping_timer = gf_timer_call_after (this->ctx, timeout, rpc_clnt_start_ping, (void *)rpc); if (conn->ping_timer == NULL) { gf_log (this->name, GF_LOG_WARNING, "failed to set the ping timer"); rpc_clnt_unref (rpc); } } unlock: pthread_mutex_unlock (&conn->lock); out: if (frame) STACK_DESTROY (frame->root); return 0; }
int bd_aio_readv_complete (struct bd_aio_cb *paiocb, int res, int res2) { call_frame_t *frame = NULL; xlator_t *this = NULL; struct iobuf *iobuf = NULL; struct iatt postbuf = {0,}; int op_ret = -1; int op_errno = 0; struct iovec iov; struct iobref *iobref = NULL; off_t offset = 0; bd_attr_t *bdatt = NULL; frame = paiocb->frame; this = frame->this; iobuf = paiocb->iobuf; offset = paiocb->offset; if (res < 0) { op_ret = -1; op_errno = -res; gf_log (this->name, GF_LOG_ERROR, "readv(async) failed fd=%p,size=%lu,offset=%llu (%d/%s)", paiocb->fd, paiocb->iocb.u.c.nbytes, (unsigned long long) paiocb->offset, res, strerror (op_errno)); goto out; } bd_inode_ctx_get (paiocb->fd->inode, this, &bdatt); memcpy (&postbuf, &bdatt->iatt, sizeof (struct iatt)); op_ret = res; op_errno = 0; iobref = iobref_new (); if (!iobref) { op_ret = -1; op_errno = ENOMEM; goto out; } iobref_add (iobref, iobuf); iov.iov_base = iobuf_ptr (iobuf); iov.iov_len = op_ret; /* Hack to notify higher layers of EOF. */ if (!postbuf.ia_size || (offset + iov.iov_len) >= postbuf.ia_size) op_errno = ENOENT; out: STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, &iov, 1, &postbuf, iobref, NULL); if (iobuf) iobuf_unref (iobuf); if (iobref) iobref_unref (iobref); GF_FREE (paiocb); return 0; }
void rpc_clnt_start_ping (void *rpc_ptr) { struct rpc_clnt *rpc = NULL; rpc_clnt_connection_t *conn = NULL; struct timespec timeout = {0, }; int frame_count = 0; rpc = (struct rpc_clnt*) rpc_ptr; conn = &rpc->conn; if (conn->ping_timeout == 0) { gf_log (THIS->name, GF_LOG_DEBUG, "ping timeout is 0," " returning"); return; } pthread_mutex_lock (&conn->lock); { if (conn->ping_started) { pthread_mutex_unlock (&conn->lock); return; } if (conn->ping_timer) { gf_timer_call_cancel (rpc->ctx, conn->ping_timer); conn->ping_timer = NULL; rpc_clnt_unref (rpc); } if (conn->saved_frames) { GF_ASSERT (conn->saved_frames->count >= 0); /* treat the case where conn->saved_frames is NULL as no pending frames */ frame_count = conn->saved_frames->count; } if ((frame_count == 0) || !conn->connected) { gf_log (THIS->name, GF_LOG_DEBUG, "returning as transport is already disconnected" " OR there are no frames (%d || %d)", !conn->connected, frame_count); pthread_mutex_unlock (&conn->lock); return; } timeout.tv_sec = conn->ping_timeout; timeout.tv_nsec = 0; rpc_clnt_ref (rpc); conn->ping_timer = gf_timer_call_after (rpc->ctx, timeout, rpc_clnt_ping_timer_expired, (void *) rpc); if (conn->ping_timer == NULL) { gf_log (THIS->name, GF_LOG_WARNING, "unable to setup ping timer"); rpc_clnt_unref (rpc); pthread_mutex_unlock (&conn->lock); return; } else { conn->ping_started = 1; } } pthread_mutex_unlock (&conn->lock); rpc_clnt_ping(rpc); }
void parse_entries_and_compare (char *option_str, char *peer_addr, char *subvol, char *subdir, auth_result_t *result, auth_result_t status) { char *entry = NULL; char *entry_cpy = NULL; char *directory = NULL; char *entries = NULL; char *addr_str = NULL; char *addr = NULL; char *tmp = NULL; char *tmpdir = NULL; int ret = 0; if (!subdir) { gf_log (subvol, GF_LOG_WARNING, "subdir entry not present, not performing any operation."); goto out; } entries = gf_strdup (option_str); if (!entries) goto out; if (entries[0] != '/' && !strchr (entries, '(')) { /* Backward compatible option */ ret = compare_addr_and_update (entries, peer_addr, subvol, ",", result, status); goto out; } entry = strtok_r (entries, ENTRY_DELIMITER, &tmp); while (entry) { entry_cpy = gf_strdup (entry); if (!entry_cpy) { goto out; } directory = strtok_r (entry_cpy, "(", &tmpdir); if (directory[0] != '/') goto out; /* send second portion, after ' =' if directory matches */ if (strcmp (subdir, directory)) goto next_entry; addr_str = strtok_r (NULL, ")", &tmpdir); if (!addr_str) goto out; addr = gf_strdup (addr_str); if (!addr) goto out; gf_log (subvol, GF_LOG_INFO, "Found an entry for dir %s (%s)," " performing validation", subdir, addr); ret = compare_addr_and_update (addr, peer_addr, subvol, ADDR_DELIMITER, result, status); if (ret == 0) { break; } GF_FREE (addr); addr = NULL; next_entry: entry = strtok_r (NULL, ENTRY_DELIMITER, &tmp); GF_FREE (entry_cpy); entry_cpy = NULL; } out: GF_FREE (entries); GF_FREE (entry_cpy); GF_FREE (addr); }
void rpc_clnt_ping_timer_expired (void *rpc_ptr) { struct rpc_clnt *rpc = NULL; rpc_transport_t *trans = NULL; rpc_clnt_connection_t *conn = NULL; int disconnect = 0; int transport_activity = 0; struct timespec timeout = {0, }; struct timeval current = {0, }; rpc = (struct rpc_clnt*) rpc_ptr; conn = &rpc->conn; trans = conn->trans; if (!trans) { gf_log ("ping-timer", GF_LOG_WARNING, "transport not initialized"); goto out; } pthread_mutex_lock (&conn->lock); { if (conn->ping_timer) { gf_timer_call_cancel (rpc->ctx, conn->ping_timer); conn->ping_timer = NULL; rpc_clnt_unref (rpc); } gettimeofday (¤t, NULL); if (((current.tv_sec - conn->last_received.tv_sec) < conn->ping_timeout) || ((current.tv_sec - conn->last_sent.tv_sec) < conn->ping_timeout)) { transport_activity = 1; } if (transport_activity) { gf_log (trans->name, GF_LOG_TRACE, "ping timer expired but transport activity " "detected - not bailing transport"); timeout.tv_sec = conn->ping_timeout; timeout.tv_nsec = 0; rpc_clnt_ref (rpc); conn->ping_timer = gf_timer_call_after (rpc->ctx, timeout, rpc_clnt_ping_timer_expired, (void *) rpc); if (conn->ping_timer == NULL) { gf_log (trans->name, GF_LOG_WARNING, "unable to setup ping timer"); rpc_clnt_unref (rpc); } } else { conn->ping_started = 0; disconnect = 1; } } pthread_mutex_unlock (&conn->lock); if (disconnect) { gf_log (trans->name, GF_LOG_CRITICAL, "server %s has not responded in the last %d " "seconds, disconnecting.", trans->peerinfo.identifier, conn->ping_timeout); rpc_transport_disconnect (conn->trans); } out: return; }
int32_t gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value) { int32_t ret = -1; char *scan_str = NULL; char *iter_key = NULL; char *iter_val = NULL; char *free_str = NULL; struct stat st = {0,}; gf_store_op_errno_t store_errno = GD_STORE_SUCCESS; GF_ASSERT (handle); handle->fd = open (handle->path, O_RDWR); if (handle->fd == -1) { gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s", handle->path, strerror (errno)); goto out; } if (!handle->read) handle->read = fdopen (handle->fd, "r"); if (!handle->read) { gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s", handle->path, strerror (errno)); goto out; } ret = fstat (handle->fd, &st); if (ret < 0) { gf_log ("", GF_LOG_WARNING, "stat on file %s failed", handle->path); ret = -1; store_errno = GD_STORE_STAT_FAILED; goto out; } scan_str = GF_CALLOC (1, st.st_size, gf_common_mt_char); if (scan_str == NULL) { ret = -1; store_errno = GD_STORE_ENOMEM; goto out; } free_str = scan_str; do { ret = gf_store_read_and_tokenize (handle->read, scan_str, &iter_key, &iter_val, &store_errno); if (ret < 0) { gf_log ("", GF_LOG_TRACE, "error while reading key " "'%s': %s", key, gf_store_strerror (store_errno)); goto out; } gf_log ("", GF_LOG_TRACE, "key %s read", iter_key); if (!strcmp (key, iter_key)) { gf_log ("", GF_LOG_DEBUG, "key %s found", key); ret = 0; if (iter_val) *value = gf_strdup (iter_val); goto out; } } while (1); out: if (handle->fd > 0) { close (handle->fd); handle->read = NULL; } GF_FREE (free_str); return ret; }
int booster_fdtable_expand (booster_fdtable_t *fdtable, uint nr) { fd_t **oldfds = NULL, **tmp = NULL; uint oldmax_fds = -1; uint cpy = 0; int32_t ret = -1, bytes = 0; booster_fd_set_t *oldclose_on_exec = NULL; if (fdtable == NULL || nr < 0) { gf_log ("booster-fd", GF_LOG_ERROR, "Invalid argument"); errno = EINVAL; ret = -1; goto out; } nr /= (1024 / sizeof (fd_t *)); nr = gf_roundup_power_of_two (nr + 1); nr *= (1024 / sizeof (fd_t *)); oldfds = fdtable->fds; oldmax_fds = fdtable->max_fds; oldclose_on_exec = fdtable->close_on_exec; fdtable->fds = CALLOC (nr, sizeof (fd_t *)); if (fdtable->fds == NULL) { gf_log ("booster-fd", GF_LOG_ERROR, "Memory allocation failed"); fdtable->fds = oldfds; oldfds = NULL; ret = -1; goto out; } fdtable->max_fds = nr; if (oldfds) { cpy = oldmax_fds * sizeof (fd_t *); memcpy (fdtable->fds, oldfds, cpy); } /* nr will be either less than 8 or a multiple of 8 */ bytes = nr/8; bytes = bytes ? bytes : 1; fdtable->close_on_exec = CALLOC (bytes, 1); if (fdtable->close_on_exec == NULL) { gf_log ("booster-fd", GF_LOG_ERROR, "Memory allocation " "failed"); tmp = fdtable->fds; fdtable->fds = oldfds; oldfds = tmp; ret = -1; goto out; } if (oldclose_on_exec != NULL) { bytes = oldmax_fds/8; cpy = bytes ? bytes : 1; memcpy (fdtable->close_on_exec, oldclose_on_exec, cpy); } gf_log ("booster-fd", GF_LOG_TRACE, "FD-table expanded: Old: %d,New: %d" , oldmax_fds, nr); ret = 0; out: FREE (oldfds); FREE (oldclose_on_exec); return ret; }
int32_t gf_store_iter_get_next (gf_store_iter_t *iter, char **key, char **value, gf_store_op_errno_t *op_errno) { int32_t ret = -1; char *scan_str = NULL; char *iter_key = NULL; char *iter_val = NULL; struct stat st = {0,}; gf_store_op_errno_t store_errno = GD_STORE_SUCCESS; GF_ASSERT (iter); GF_ASSERT (key); GF_ASSERT (value); ret = stat (iter->filepath, &st); if (ret < 0) { gf_log ("", GF_LOG_WARNING, "stat on file failed"); ret = -1; store_errno = GD_STORE_STAT_FAILED; goto out; } scan_str = GF_CALLOC (1, st.st_size, gf_common_mt_char); if (!scan_str) { ret = -1; store_errno = GD_STORE_ENOMEM; goto out; } ret = gf_store_read_and_tokenize (iter->file, scan_str, &iter_key, &iter_val, &store_errno); if (ret < 0) { goto out; } ret = gf_store_validate_key_value (iter->filepath, iter_key, iter_val, &store_errno); if (ret) goto out; *key = gf_strdup (iter_key); if (!*key) { ret = -1; store_errno = GD_STORE_ENOMEM; goto out; } *value = gf_strdup (iter_val); if (!*value) { ret = -1; store_errno = GD_STORE_ENOMEM; goto out; } ret = 0; out: GF_FREE (scan_str); if (ret) { GF_FREE (*key); GF_FREE (*value); *key = NULL; *value = NULL; } if (op_errno) *op_errno = store_errno; gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); return ret; }
static int32_t create_format_v1(unsigned char *wire, loc_t *loc, struct crypt_inode_info *info, struct master_cipher_info *master) { int32_t ret; struct mtd_format_v1 *fmt; unsigned char mtd_key[16]; AES_KEY EMTD_KEY; unsigned char nmtd_link_key[16]; uint32_t ad; GCM128_CONTEXT *gctx; fmt = (struct mtd_format_v1 *)wire; fmt->minor_id = info->nr_minor; fmt->alg_id = AES_CIPHER_ALG; fmt->dkey_factor = master->m_dkey_size >> KEY_FACTOR_BITS; fmt->block_bits = master->m_block_bits; fmt->mode_id = master->m_mode; /* * retrieve keys for the parts of metadata */ ret = get_emtd_file_key(info, master, mtd_key); if (ret) return ret; ret = get_nmtd_link_key(loc, master, nmtd_link_key); if (ret) return ret; AES_set_encrypt_key(mtd_key, sizeof(mtd_key)*8, &EMTD_KEY); gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt); /* TBD: Check return values */ CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t)); ad = htole32(MTD_LOADER_V1); ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad)); if (ret) { gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed"); CRYPTO_gcm128_release(gctx); return ret; } ret = CRYPTO_gcm128_encrypt(gctx, get_EMTD_V1(fmt), get_EMTD_V1(fmt), SIZE_OF_EMTD_V1); if (ret) { gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_encrypt failed"); CRYPTO_gcm128_release(gctx); return ret; } /* * set MAC of encrypted part of metadata */ CRYPTO_gcm128_tag(gctx, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC); CRYPTO_gcm128_release(gctx); /* * set the first MAC of non-encrypted part of metadata */ return create_link_mac_v1(fmt, 0, loc, info, master); }
int xlator_dynload (xlator_t *xl) { int ret = -1; char *name = NULL; void *handle = NULL; volume_opt_list_t *vol_opt = NULL; class_methods_t *vtbl = NULL; GF_VALIDATE_OR_GOTO ("xlator", xl, out); INIT_LIST_HEAD (&xl->volume_options); ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type); if (-1 == ret) { gf_log ("xlator", GF_LOG_ERROR, "asprintf failed"); goto out; } ret = -1; gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name); handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); if (!handle) { gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ()); goto out; } xl->dlhandle = handle; if (!(xl->fops = dlsym (handle, "fops"))) { gf_log ("xlator", GF_LOG_WARNING, "dlsym(fops) on %s", dlerror ()); goto out; } if (!(xl->cbks = dlsym (handle, "cbks"))) { gf_log ("xlator", GF_LOG_WARNING, "dlsym(cbks) on %s", dlerror ()); goto out; } /* * If class_methods exists, its contents override any definitions of * init or fini for that translator. Otherwise, we fall back to the * older method of looking for init and fini directly. */ vtbl = dlsym(handle,"class_methods"); if (vtbl) { xl->init = vtbl->init; xl->fini = vtbl->fini; xl->reconfigure = vtbl->reconfigure; xl->notify = vtbl->notify; } else { if (!(*VOID(&xl->init) = dlsym (handle, "init"))) { gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s", dlerror ()); goto out; } if (!(*VOID(&(xl->fini)) = dlsym (handle, "fini"))) { gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s", dlerror ()); goto out; } if (!(*VOID(&(xl->reconfigure)) = dlsym (handle, "reconfigure"))) { gf_log ("xlator", GF_LOG_TRACE, "dlsym(reconfigure) on %s -- neglecting", dlerror()); } if (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) { gf_log ("xlator", GF_LOG_TRACE, "dlsym(notify) on %s -- neglecting", dlerror ()); } } if (!(xl->dumpops = dlsym (handle, "dumpops"))) { gf_log ("xlator", GF_LOG_TRACE, "dlsym(dumpops) on %s -- neglecting", dlerror ()); } if (!(*VOID(&(xl->mem_acct_init)) = dlsym (handle, "mem_acct_init"))) { gf_log (xl->name, GF_LOG_TRACE, "dlsym(mem_acct_init) on %s -- neglecting", dlerror ()); } vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), gf_common_mt_volume_opt_list_t); if (!vol_opt) { goto out; } if (!(vol_opt->given_opt = dlsym (handle, "options"))) { dlerror (); gf_log (xl->name, GF_LOG_TRACE, "Strict option validation not enforced -- neglecting"); } INIT_LIST_HEAD (&vol_opt->list); list_add_tail (&vol_opt->list, &xl->volume_options); fill_defaults (xl); ret = 0; out: GF_FREE (name); return ret; }
/** * __exp_line_opt_parse -- Parse the options part of an * exports or netgroups string. * * @opt_str : The option string to parse * @exp_opts : Double pointer to the options we are going * to allocate and setup. * * * @return: success: GF_EXP_PARSE_SUCCESS * failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure, * -EINVAL on bad args, -ENOMEM on allocation errors. * * Not for external use. */ static int __exp_line_opt_parse (const char *opt_str, struct export_options **exp_opts) { struct export_options *opts = NULL; char *strmatch = NULL; int ret = -EINVAL; char *equals = NULL; ret = parser_set_string (options_parser, opt_str); if (ret < 0) goto out; while ((strmatch = parser_get_next_match (options_parser))) { if (!opts) { /* If the options have not been allocated, * allocate it. */ opts = _export_options_init (); if (!opts) { ret = -ENOMEM; parser_unset_string (options_parser); goto out; } } /* First, check for all the boolean options Second, check for * an '=', and check the available options there. The string * parsing here gets slightly messy, but the concept itself * is pretty simple. */ equals = strchr (strmatch, '='); if (strcmp (strmatch, "root") == 0) opts->root = _gf_true; else if (strcmp (strmatch, "ro") == 0) opts->rw = _gf_false; else if (strcmp (strmatch, "rw") == 0) opts->rw = _gf_true; else if (strcmp (strmatch, "nosuid") == 0) opts->nosuid = _gf_true; else if (equals) { ret = __exp_line_opt_key_value_parse (strmatch, opts); if (ret < 0) { /* This means invalid key value options were * specified, or memory allocation failed. * The ret value gets bubbled up to the caller. */ GF_FREE (strmatch); parser_unset_string (options_parser); _export_options_deinit (opts); goto out; } } else /* Cannot change to gf_msg. * gf_msg not giving output to STDOUT * Bug id : BZ1215017 */ gf_log (GF_EXP, GF_LOG_WARNING, "Could not find any valid options for " "string: %s", strmatch); GF_FREE (strmatch); } if (!opts) { /* If opts is not allocated * that means no matches were found * which is a parse error. Not marking * it as "not found" because it is a parse * error to not have options. */ ret = GF_EXP_PARSE_ITEM_FAILURE; parser_unset_string (options_parser); goto out; } *exp_opts = opts; parser_unset_string (options_parser); ret = GF_EXP_PARSE_SUCCESS; out: return ret; }
/** * _exp_line_parse -- Parse a line in an exports file into a structure * that holds all the parts of the line. An exports * structure has a dict of netgroups and a dict of hosts. * * An export line looks something like this /test @test(sec=sys,rw,anonuid=0) * or /test @test(sec=sys,rw,anonuid=0) hostA(sec=sys,rw,anonuid=0), etc. * * We use regexes to parse the line into three separate pieces: * 1) The directory (exports.h -- DIRECTORY_REGEX_PATTERN) * 2) The netgroup if it exists (exports.h -- NETGROUP_REGEX_PATTERN) * 3) The host if it exists (exports.h -- HOST_REGEX_PATTERN) * * In this case, the netgroup would be @test(sec=sys,rw,anonuid=0) * and the host would be hostA(sec=sys,rw,anonuid=0). * * @line : The line to parse * @dir : Double pointer to the struct we need to parse the line into. * If the parsing failed, the struct will point to NULL, * otherwise it will point to a valid memory region that is * allocated by this function. * @parse_full : This parameter tells us whether we should parse all the lines * in the file, even if they are not present in gluster's config. * The gluster config holds the volumes that it exports so * if parse_full is set to FALSE then we will ensure that * the export file structure holds only those volumes * that gluster has exported. It is important to note that * If gluster exports a volume named '/test', '/test' and all * of its subdirectories that may be in the exports file * are valid exports. * @ms : The mount state that holds the list of volumes that gluster * currently exports. * * @return : success: GF_EXP_PARSE_SUCCESS on success, -EINVAL on bad arguments, * -ENOMEM on memory allocation errors, * GF_EXP_PARSE_LINE_IGNORING if we ignored the line, * GF_EXP_PARSE_ITEM_FAILURE if there was error parsing * failure: NULL * * The caller is responsible for freeing memory allocated by this function * The caller should free this memory using the _exp_dir_deinit () function. * * Not for external use. */ static int _exp_line_parse(const char *line, struct export_dir **dir, gf_boolean_t parse_full, struct mount3_state *ms) { struct export_dir *expdir = NULL; char *dirstr = NULL; dict_t *netgroups = NULL; dict_t *hosts = NULL; int ret = -EINVAL; gf_boolean_t netgroups_failed = _gf_false; GF_VALIDATE_OR_GOTO(GF_EXP, line, out); GF_VALIDATE_OR_GOTO(GF_EXP, dir, out); if (*line == '#' || *line == ' ' || *line == '\t' || *line == '\0' || *line == '\n') { ret = GF_EXP_PARSE_LINE_IGNORING; goto out; } expdir = _export_dir_init(); if (!expdir) { *dir = NULL; ret = -ENOMEM; goto out; } /* Get the directory string from the line */ ret = __exp_line_dir_parse(line, &dirstr, ms); if (ret < 0) { gf_msg(GF_EXP, GF_LOG_ERROR, 0, NFS_MSG_PARSE_DIR_FAIL, "Parsing directory failed: %s", strerror(-ret)); /* If parsing the directory failed, * we should simply fail because there's * nothing else we can extract from the string to make * the data valuable. */ goto free_and_out; } /* Set the dir str */ expdir->dir_name = dirstr; /* Parse the netgroup part of the string */ ret = __exp_line_ng_parse(line, &netgroups); if (ret < 0) { gf_msg(GF_EXP, GF_LOG_ERROR, -ret, NFS_MSG_PARSE_FAIL, "Critical error: %s", strerror(-ret)); /* Return values less than 0 * indicate critical failures (null parameters, * failure to allocate memory, etc). */ goto free_and_out; } if (ret != 0) { if (ret == GF_EXP_PARSE_ITEM_FAILURE) /* Cannot change to gf_msg. * gf_msg not giving output to STDOUT * Bug id : BZ1215017 */ gf_log(GF_EXP, GF_LOG_WARNING, "Error parsing netgroups for: %s", line); /* Even though parsing failed for the netgroups we should let * host parsing proceed. */ netgroups_failed = _gf_true; } /* Parse the host part of the string */ ret = __exp_line_host_parse(line, &hosts); if (ret < 0) { gf_msg(GF_EXP, GF_LOG_ERROR, -ret, NFS_MSG_PARSE_FAIL, "Critical error: %s", strerror(-ret)); goto free_and_out; } if (ret != 0) { if (ret == GF_EXP_PARSE_ITEM_FAILURE) gf_msg(GF_EXP, GF_LOG_WARNING, 0, NFS_MSG_PARSE_FAIL, "Error parsing hosts for: %s", line); /* If netgroups parsing failed, AND * host parsing failed, then there's something really * wrong with this line, so we're just going to * log it and fail out. */ if (netgroups_failed) goto free_and_out; } expdir->hosts = hosts; expdir->netgroups = netgroups; *dir = expdir; goto out; free_and_out: _export_dir_deinit(expdir); out: return ret; }
int auth_glusterfs_authenticate (rpcsvc_request_t *req, void *priv) { struct auth_glusterfs_parms au = {0,}; int ret = RPCSVC_AUTH_REJECT; int j = 0; int i = 0; int gidcount = 0; if (!req) return ret; ret = xdr_to_glusterfs_auth (req->cred.authdata, &au); if (ret == -1) { gf_log ("", GF_LOG_WARNING, "failed to decode glusterfs credentials"); ret = RPCSVC_AUTH_REJECT; goto err; } req->pid = au.pid; req->uid = au.uid; req->gid = au.gid; req->lk_owner.len = 8; { for (i = 0; i < req->lk_owner.len; i++, j += 8) req->lk_owner.data[i] = (char)((au.lk_owner >> j) & 0xff); } req->auxgidcount = au.ngrps; if (req->auxgidcount > 16) { gf_log ("", GF_LOG_WARNING, "more than 16 aux gids found, failing authentication"); ret = RPCSVC_AUTH_REJECT; goto err; } if (req->auxgidcount > SMALL_GROUP_COUNT) { req->auxgidlarge = GF_CALLOC(req->auxgidcount, sizeof(req->auxgids[0]), gf_common_mt_auxgids); req->auxgids = req->auxgidlarge; } else { req->auxgids = req->auxgidsmall; } if (!req->auxgids) { gf_log ("auth-glusterfs", GF_LOG_WARNING, "cannot allocate gid list"); ret = RPCSVC_AUTH_REJECT; goto err; } for (gidcount = 0; gidcount < au.ngrps; ++gidcount) req->auxgids[gidcount] = au.groups[gidcount]; gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: pid: %u, uid: %d" ", gid: %d, owner: %s", req->pid, req->uid, req->gid, lkowner_utoa (&req->lk_owner)); ret = RPCSVC_AUTH_ACCEPT; err: return ret; }