Exemplo n.º 1
0
/**
 * 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, &timestamp, &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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;

}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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;

}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
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);

        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;

}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
/**
 * __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;
}
Exemplo n.º 14
0
/**
 * __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;
}
Exemplo n.º 15
0
/**
 * __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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
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;
}