Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #10
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;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #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_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;
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
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;
}
Пример #20
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);
}
Пример #21
0
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);
}
Пример #22
0
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 (&current, 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;
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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;
}
Пример #26
0
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);
}
Пример #27
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) {
                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;
}
Пример #28
0
/**
 * __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;
}
Пример #29
0
/**
 * _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;
}
Пример #30
0
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;
}