/** * cache_nfs_fh -- Places the nfs file handle in the underlying dict as we are * using as our cache. The key is "exportid:gfid:host_addr", the * value is an entry struct containing the export item that * was authorized for the operation and the file handle that was * authorized. * * @cache: The cache to place fh's in * @fh : The fh to cache * @host_addr: The address of the host * @export_item: The export item that was authorized * */ int cache_nfs_fh (struct auth_cache *cache, struct nfs3_fh *fh, const char *host_addr, struct export_item *export_item) { int ret = -EINVAL; char *hashkey = NULL; data_t *entry_data = NULL; time_t timestamp = 0; gf_boolean_t can_write = _gf_false; struct auth_cache_entry *entry = NULL; GF_VALIDATE_OR_GOTO (GF_NFS, host_addr, out); GF_VALIDATE_OR_GOTO (GF_NFS, cache, out); GF_VALIDATE_OR_GOTO (GF_NFS, fh, out); /* If we could already find it in the cache, just return */ ret = auth_cache_lookup (cache, fh, host_addr, ×tamp, &can_write); if (ret == 0) { gf_msg_trace (GF_NFS, 0, "found cached auth/fh for host " "%s", host_addr); goto out; } hashkey = make_hashkey (fh, host_addr); if (!hashkey) { ret = -ENOMEM; goto out; } entry = auth_cache_entry_init (); if (!entry) { ret = -ENOMEM; goto out; } entry->timestamp = time (NULL); entry->item = export_item; /* The cache entry will simply be the time that the entry * was cached. */ entry_data = bin_to_data (entry, sizeof (*entry)); if (!entry_data) { GF_FREE (entry); goto out; } ret = dict_set (cache->cache_dict, hashkey, entry_data); if (ret == -1) { GF_FREE (entry); goto out; } gf_msg_trace (GF_NFS, 0, "Caching file-handle (%s)", host_addr); ret = 0; out: GF_FREE (hashkey); return ret; }
int nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc, int how) { int ret = -EFAULT; inode_t *inode = NULL; if (!loc) return ret; inode = inode_find (itable, gfid); if (!inode) { gf_msg_trace (GF_NFS, 0, "Inode not found in itable, will " "try to create one."); if (how == NFS_RESOLVE_CREATE) { gf_msg_trace (GF_NFS, 0, "Inode needs to be created."); inode = inode_new (itable); if (!inode) { gf_msg (GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, "Failed to " "allocate memory"); ret = -ENOMEM; goto err; } } else { gf_msg (GF_NFS, GF_LOG_ERROR, ENOENT, NFS_MSG_INODE_NOT_FOUND, "Inode not found in " "itable and no creation was requested."); ret = -ENOENT; goto err; } } else { gf_msg_trace (GF_NFS, 0, "Inode was found in the itable."); } gf_uuid_copy (loc->gfid, gfid); ret = nfs_inode_loc_fill (inode, loc, how); if (ret < 0) { gf_msg (GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_INODE_LOC_FILL_ERROR, "Inode loc filling failed.: %s", strerror (-ret)); goto err; } err: if (inode) inode_unref (inode); return ret; }
xlator_t * nfs_mntpath_to_xlator (xlator_list_t *cl, char *path) { char *volname = NULL; char *volptr = NULL; size_t pathlen; xlator_t *targetxl = NULL; if ((!cl) || (!path)) return NULL; volname = strdupa (path); pathlen = strlen (volname); gf_msg_trace (GF_NFS, 0, "Subvolume search: %s", path); if (volname[0] == '/') volptr = &volname[1]; else volptr = &volname[0]; if (pathlen && volname[pathlen - 1] == '/') volname[pathlen - 1] = '\0'; while (cl) { if (strcmp (volptr, cl->xlator->name) == 0) { targetxl = cl->xlator; break; } cl = cl->next; } return targetxl; }
static int glusterd_op_state_machine_mgmt_v3_unlock (rpcsvc_request_t *req, gd1_mgmt_v3_unlock_req *lock_req, glusterd_op_lock_ctx_t *ctx) { int32_t ret = -1; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); ret = glusterd_op_sm_inject_event (GD_OP_EVENT_UNLOCK, &lock_req->txn_id, ctx); if (ret) gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_OP_EVENT_UNLOCK_FAIL, "Failed to inject event GD_OP_EVENT_UNLOCK"); glusterd_friend_sm (); glusterd_op_sm (); gf_msg_trace (this->name, 0, "Returning %d", ret); return ret; }
static int glusterd_syctasked_mgmt_v3_unlock (rpcsvc_request_t *req, gd1_mgmt_v3_unlock_req *unlock_req, glusterd_op_lock_ctx_t *ctx) { int32_t ret = -1; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (ctx); /* Trying to release multiple mgmt_v3 locks */ ret = glusterd_multiple_mgmt_v3_unlock (ctx->dict, ctx->uuid); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release mgmt_v3 locks for %s", uuid_utoa(ctx->uuid)); } ret = glusterd_mgmt_v3_unlock_send_resp (req, ret); gf_msg_trace (this->name, 0, "Returning %d", ret); return ret; }
int client_cbk_cache_invalidation (struct rpc_clnt *rpc, void *mydata, void *data) { int ret = -1; struct iovec *iov = NULL; struct gf_upcall upcall_data = {0,}; uuid_t gfid; struct gf_upcall_cache_invalidation ca_data = {0,}; gfs3_cbk_cache_invalidation_req ca_req = {0,}; gf_msg_trace (THIS->name, 0, "Upcall callback is called"); if (!rpc || !mydata || !data) goto out; iov = (struct iovec *)data; ret = xdr_to_generic (*iov, &ca_req, (xdrproc_t)xdr_gfs3_cbk_cache_invalidation_req); if (ret < 0) { gf_msg (THIS->name, GF_LOG_WARNING, -ret, PC_MSG_CACHE_INVALIDATION_FAIL, "XDR decode of cache_invalidation failed."); goto out; } upcall_data.data = &ca_data; gf_proto_cache_invalidation_to_upcall (&ca_req, &upcall_data); gf_msg_trace (THIS->name, 0, "Upcall gfid = %s, ret = %d", ca_req.gfid, ret); default_notify (THIS, GF_EVENT_UPCALL, &upcall_data); out: if (ca_req.gfid) free (ca_req.gfid); if (ca_req.xdata.xdata_val) free (ca_req.xdata.xdata_val); return 0; }
int xlator_volopt_dynload (char *xlator_type, void **dl_handle, volume_opt_list_t *opt_list) { int ret = -1; char *name = NULL; void *handle = NULL; GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out); /* socket.so doesn't fall under the default xlator directory, hence we * need this check */ if (!strstr(xlator_type, "rpc-transport")) ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type); else ret = gf_asprintf (&name, "%s/%s.so", XLATORPARENTDIR, xlator_type); if (-1 == ret) { goto out; } ret = -1; gf_msg_trace ("xlator", 0, "attempt to load file %s", name); handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); if (!handle) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "%s", dlerror ()); goto out; } if (!(opt_list->given_opt = dlsym (handle, "options"))) { dlerror (); gf_msg ("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, "Failed to load xlator opt table"); goto out; } *dl_handle = handle; handle = NULL; ret = 0; out: GF_FREE (name); if (handle) dlclose (handle); gf_msg_debug ("xlator", 0, "Returning %d", ret); return ret; }
static int xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value, volume_option_t *opt, char **op_errstr) { size_t size = 0; int ret = 0; char errstr[256]; /* Check the range */ if (gf_string2bytesize_size (value, &size) != 0) { snprintf (errstr, 256, "invalid number format \"%s\" in option \"%s\"", value, key); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); ret = -1; goto out; } if ((opt->min == 0) && (opt->max == 0)) { gf_msg_trace (xl->name, 0, "no range check required for " "'option %s %s'", key, value); goto out; } if ((size < opt->min) || (size > opt->max)) { if ((strncmp (key, "cache-size", 10) == 0) && (size > opt->max)) { snprintf (errstr, 256, "Cache size %" GF_PRI_SIZET " is out of " "range [%.0f - %.0f]", size, opt->min, opt->max); gf_msg (xl->name, GF_LOG_WARNING, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); } else { snprintf (errstr, 256, "'%" GF_PRI_SIZET "' in 'option %s %s' " "is out of range [%.0f - %.0f]", size, key, value, opt->min, opt->max); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); ret = -1; } } out: if (ret && op_errstr) *op_errstr = gf_strdup (errstr); return ret; }
int xlator_volopt_dynload (char *xlator_type, void **dl_handle, volume_opt_list_t *opt_list) { int ret = -1; char *name = NULL; void *handle = NULL; GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out); ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type); if (-1 == ret) { goto out; } ret = -1; gf_msg_trace ("xlator", 0, "attempt to load file %s", name); handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); if (!handle) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "%s", dlerror ()); goto out; } if (!(opt_list->given_opt = dlsym (handle, "options"))) { dlerror (); gf_msg ("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, "Failed to load xlator opt table"); goto out; } *dl_handle = handle; handle = NULL; ret = 0; out: GF_FREE (name); if (handle) dlclose (handle); gf_msg_debug ("xlator", 0, "Returning %d", ret); return ret; }
static int xlator_option_validate_time (xlator_t *xl, const char *key, const char *value, volume_option_t *opt, char **op_errstr) { int ret = -1; char errstr[256]; uint32_t input_time = 0; /* Check if the value is valid time */ if (gf_string2time (value, &input_time) != 0) { snprintf (errstr, 256, "invalid time format \"%s\" in " "\"option %s\"", value, key); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); goto out; } if ((opt->min == 0) && (opt->max == 0)) { gf_msg_trace (xl->name, 0, "no range check required for " "'option %s %s'", key, value); ret = 0; goto out; } if ((input_time < opt->min) || (input_time > opt->max)) { snprintf (errstr, 256, "'%"PRIu32"' in 'option %s %s' is " "out of range [%.0f - %.0f]", input_time, key, value, opt->min, opt->max); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); goto out; } ret = 0; out: if (ret && op_errstr) *op_errstr = gf_strdup (errstr); return ret; }
static int glusterd_op_state_machine_mgmt_v3_lock (rpcsvc_request_t *req, gd1_mgmt_v3_lock_req *lock_req, glusterd_op_lock_ctx_t *ctx) { int32_t ret = -1; xlator_t *this = NULL; glusterd_op_info_t txn_op_info = {{0},}; this = THIS; GF_ASSERT (this); GF_ASSERT (req); glusterd_txn_opinfo_init (&txn_op_info, NULL, &lock_req->op, ctx->dict, req); ret = glusterd_set_txn_opinfo (&lock_req->txn_id, &txn_op_info); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_OPINFO_SET_FAIL, "Unable to set transaction's opinfo"); goto out; } ret = glusterd_op_sm_inject_event (GD_OP_EVENT_LOCK, &lock_req->txn_id, ctx); if (ret) gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_OP_EVENT_LOCK_FAIL, "Failed to inject event GD_OP_EVENT_LOCK"); out: glusterd_friend_sm (); glusterd_op_sm (); gf_msg_trace (this->name, 0, "Returning %d", ret); return ret; }
static int xlator_option_validate_int (xlator_t *xl, const char *key, const char *value, volume_option_t *opt, char **op_errstr) { long long inputll = 0; unsigned long long uinputll = 0; int ret = -1; char errstr[256]; /* Check the range */ if (gf_string2longlong (value, &inputll) != 0) { snprintf (errstr, 256, "invalid number format \"%s\" in option \"%s\"", value, key); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); goto out; } /* Handle '-0' */ if ((inputll == 0) && (gf_string2ulonglong (value, &uinputll) != 0)) { snprintf (errstr, 256, "invalid number format \"%s\" in option \"%s\"", value, key); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); goto out; } if ((opt->min == 0) && (opt->max == 0) && (opt->validate == GF_OPT_VALIDATE_BOTH)) { gf_msg_trace (xl->name, 0, "no range check required for " "'option %s %s'", key, value); ret = 0; goto out; } if (opt->validate == GF_OPT_VALIDATE_MIN) { if (inputll < opt->min) { snprintf (errstr, 256, "'%lld' in 'option %s %s' is smaller than " "minimum value '%.0f'", inputll, key, value, opt->min); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); goto out; } } else if (opt->validate == GF_OPT_VALIDATE_MAX) { if (inputll > opt->max) { snprintf (errstr, 256, "'%lld' in 'option %s %s' is greater than " "maximum value '%.0f'", inputll, key, value, opt->max); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); goto out; } } else if ((inputll < opt->min) || (inputll > opt->max)) { snprintf (errstr, 256, "'%lld' in 'option %s %s' is out of range " "[%.0f - %.0f]", inputll, key, value, opt->min, opt->max); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); goto out; } ret = 0; out: if (ret && op_errstr) *op_errstr = gf_strdup (errstr); return ret; }
/** * __exp_line_host_parse -- Extract the hosts in the line * and call helper functions to parse * the string. * * The call chain goes like this: * * 1) __exp_line_host_parse ("/test hostip(sec=sys,rw,anonuid=0)") * 2) __exp_line_ng_host_str_parse ("hostip(sec=sys,rw,anonuid=0)"); * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)"); * * * @line : The line to parse * @ng_dict : Double pointer to the dict we want to * insert hosts into. * * Allocates the dict, extracts host strings from the line, * parses them into a struct export_item structure and inserts * them in the dict. * * @return: success: GF_EXP_PARSE_SUCCESS * failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure, * GF_EXP_PARSE_ITEM_NOT_FOUND if the host was not found, * -EINVAL on bad args, -ENOMEM on allocation errors. * * Not for external use. */ static int __exp_line_host_parse(const char *line, dict_t **host_dict) { dict_t *hosts = NULL; char *strmatch = NULL; int ret = -EINVAL; struct export_item *exp_host = NULL; data_t *hostdata = NULL; GF_VALIDATE_OR_GOTO(GF_EXP, line, out); GF_VALIDATE_OR_GOTO(GF_EXP, host_dict, out); *host_dict = NULL; /* Initialize a parser with the line to parse and the regex used to * parse it. */ ret = parser_set_string(hostname_parser, line); if (ret < 0) { goto out; } gf_msg_trace(GF_EXP, 0, "parsing line: %s", line); while ((strmatch = parser_get_next_match(hostname_parser))) { if (!hosts) { /* Allocate a new dictto store the netgroups. */ hosts = dict_new(); GF_CHECK_ALLOC(hosts, ret, free_and_out); } gf_msg_trace(GF_EXP, 0, "parsing hostname: %s", strmatch); ret = __exp_line_ng_host_str_parse(strmatch, &exp_host); if (ret != 0) { /* Parsing or other critical error, free allocated * memory and exit. The caller will handle the errors. */ _exp_dict_destroy(hosts); goto free_and_out; } /* Insert export item structure into the hosts dict. */ hostdata = bin_to_data(exp_host, sizeof(*exp_host)); dict_set(hosts, exp_host->name, hostdata); /* Free this matched string and continue parsing.*/ GF_FREE(strmatch); } /* If the hosts dict was not allocated, then we know that * no matches were found. */ if (!exp_host) { ret = GF_EXP_PARSE_ITEM_NOT_FOUND; parser_unset_string(hostname_parser); goto out; } ret = GF_EXP_PARSE_SUCCESS; *host_dict = hosts; free_and_out: parser_unset_string(hostname_parser); GF_FREE(strmatch); out: return ret; }
/** * __exp_line_ng_parse -- Extract the netgroups in the line * and call helper functions to parse * the string. * * The call chain goes like this: * * 1) __exp_line_ng_parse ("/test @test(sec=sys,rw,anonuid=0)") * 2) __exp_line_ng_str_parse ("@test(sec=sys,rw,anonuid=0)"); * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)"); * * * @line : The line to parse * @ng_dict : Double pointer to the dict we want to * insert netgroups into. * * Allocates the dict, extracts netgroup strings from the line, * parses them into a struct export_item structure and inserts * them in the dict. * * @return: success: GF_EXP_PARSE_SUCCESS * failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure, * GF_EXP_PARSE_ITEM_NOT_FOUND if the netgroup was not found * -EINVAL on bad args, -ENOMEM on allocation errors. * * Not for external use. */ static int __exp_line_ng_parse(const char *line, dict_t **ng_dict) { dict_t *netgroups = NULL; char *strmatch = NULL; int ret = -EINVAL; struct export_item *exp_ng = NULL; data_t *ngdata = NULL; GF_VALIDATE_OR_GOTO(GF_EXP, line, out); GF_VALIDATE_OR_GOTO(GF_EXP, ng_dict, out); *ng_dict = NULL; /* Will be set if parse is successful */ /* Initialize a parser with the line to parse * and the regex used to parse it. */ ret = parser_set_string(netgroup_parser, line); if (ret < 0) { goto out; } gf_msg_trace(GF_EXP, 0, "parsing line: %s", line); while ((strmatch = parser_get_next_match(netgroup_parser))) { if (!netgroups) { /* Allocate a new dict to store the netgroups. */ netgroups = dict_new(); if (!netgroups) { ret = -ENOMEM; goto free_and_out; } } gf_msg_trace(GF_EXP, 0, "parsing netgroup: %s", strmatch); ret = __exp_line_ng_host_str_parse(strmatch, &exp_ng); if (ret != 0) { /* Parsing or other critical errors. * caller will handle return value. */ _exp_dict_destroy(netgroups); goto free_and_out; } ngdata = bin_to_data(exp_ng, sizeof(*exp_ng)); dict_set(netgroups, exp_ng->name, ngdata); /* Free this matched string and continue parsing. */ GF_FREE(strmatch); } /* If the netgroups dict was not allocated, then we know that * no matches were found. */ if (!netgroups) { ret = GF_EXP_PARSE_ITEM_NOT_FOUND; parser_unset_string(netgroup_parser); goto out; } ret = GF_EXP_PARSE_SUCCESS; *ng_dict = netgroups; free_and_out: parser_unset_string(netgroup_parser); GF_FREE(strmatch); out: return ret; }
/** * __exp_line_ng_host_str_parse -- Parse the netgroup or host string * * e.g. @mygroup(<options>), parsing @mygroup and (<options>) * or myhost001.dom(<options>), parsing myhost001.dom and (<options>) * * @line : The line to parse * @exp_item : Double pointer to a struct export_item * * @return: success: GF_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_ng_host_str_parse(char *str, struct export_item **exp_item) { struct export_item *item = NULL; int ret = -EINVAL; char *parens = NULL; char *optstr = NULL; struct export_options *exp_opts = NULL; char *item_name = NULL; GF_VALIDATE_OR_GOTO(GF_EXP, str, out); GF_VALIDATE_OR_GOTO(GF_EXP, exp_item, out); /* A netgroup/host string looks like this: * @test(sec=sys,rw,anonuid=0) or host(sec=sys,rw,anonuid=0) * We want to extract the name, 'test' or 'host' * Again, we could setup a regex and use it here, * but its simpler to find the '(' and copy until * there. */ parens = strchr(str, '('); if (!parens) { /* Parse error if there are no parens. */ ret = GF_EXP_PARSE_ITEM_FAILURE; goto out; } *parens = '\0'; /* Temporarily terminate it so we can do a copy */ if (strlen(str) > FQDN_MAX_LEN) { ret = GF_EXP_PARSE_ITEM_FAILURE; goto out; } /* Strip leading whitespaces */ while (*str == ' ' || *str == '\t') str++; item_name = gf_strdup(str); GF_CHECK_ALLOC(item_name, ret, out); gf_msg_trace(GF_EXP, 0, "found hostname/netgroup: %s", item_name); /* Initialize an export item for this */ item = _export_item_init(); GF_CHECK_ALLOC(item, ret, free_and_out); item->name = item_name; *parens = '('; /* Restore the string */ /* Options start at the parentheses */ optstr = parens; ret = __exp_line_opt_parse(optstr, &exp_opts); if (ret != 0) { /* Bubble up the error to the caller */ GF_REF_PUT(item); goto out; } item->opts = exp_opts; *exp_item = item; ret = GF_EXP_PARSE_SUCCESS; goto out; free_and_out: GF_FREE(item_name); out: return ret; }
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_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode unlock " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } gf_msg_debug (this->name, 0, "Received volume unlock req " "from uuid: %s", uuid_utoa (lock_req.uuid)); if (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL) { gf_msg (this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%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_msg (this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, "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_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "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_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "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_msg_trace (this->name, 0, "Returning %d", ret); return ret; }
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) { goto out; } ret = -1; gf_msg_trace ("xlator", 0, "attempt to load file %s", name); handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); if (!handle) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "%s", dlerror ()); goto out; } xl->dlhandle = handle; if (!(xl->fops = dlsym (handle, "fops"))) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, "dlsym(fops) on %s", dlerror ()); goto out; } if (!(xl->cbks = dlsym (handle, "cbks"))) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, "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_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, "dlsym(init) on %s", dlerror ()); goto out; } if (!(*VOID(&(xl->fini)) = dlsym (handle, "fini"))) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, "dlsym(fini) on %s", dlerror ()); goto out; } if (!(*VOID(&(xl->reconfigure)) = dlsym (handle, "reconfigure"))) { gf_msg_trace ("xlator", 0, "dlsym(reconfigure) on %s " "-- neglecting", dlerror()); } if (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) { gf_msg_trace ("xlator", 0, "dlsym(notify) on %s -- " "neglecting", dlerror ()); } } if (!(xl->dumpops = dlsym (handle, "dumpops"))) { gf_msg_trace ("xlator", 0, "dlsym(dumpops) on %s -- " "neglecting", dlerror ()); } if (!(*VOID(&(xl->mem_acct_init)) = dlsym (handle, "mem_acct_init"))) { gf_msg_trace (xl->name, 0, "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_msg_trace (xl->name, 0, "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; }
static int xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key, const char *value, volume_option_t *opt, char **op_errstr) { int ret = -1; char errstr[256]; double size = 0; gf_boolean_t is_percent = _gf_false; if (gf_string2percent_or_bytesize (value, &size, &is_percent) == 0) { if (is_percent) { if ((size < 0.0) || (size > 100.0)) { snprintf (errstr, sizeof (errstr), "'%lf' in 'option %s %s' is out" " of range [0 - 100]", size, key, value); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); goto out; } ret = 0; goto out; } /*Input value of size(in byte) should not be fractional*/ ret = xlator_option_validate_fractional_value (value); if (ret) { snprintf (errstr, sizeof (errstr), "'%lf' in 'option %s" " %s' should not be fractional value. Use " "valid unsigned integer value.", size, key, value); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); goto out; } /* Check the range */ if ((opt->min == 0) && (opt->max == 0)) { gf_msg_trace (xl->name, 0, "no range check required " "for 'option %s %s'", key, value); ret = 0; goto out; } if ((size < opt->min) || (size > opt->max)) { snprintf (errstr, 256, "'%lf' in 'option %s %s'" " is out of range [%.0f - %.0f]", size, key, value, opt->min, opt->max); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr); goto out; } ret = 0; goto out; } /* If control reaches here, invalid argument */ snprintf (errstr, 256, "invalid number format \"%s\" in \"option %s\"", value, key); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); out: if (ret && op_errstr) *op_errstr = gf_strdup (errstr); return ret; }