コード例 #1
0
ファイル: event-poll.c プロジェクト: rajeshjoseph/glusterfs
static struct event_pool *
event_pool_new_poll (int count, int eventthreadcount)
{
        struct event_pool *event_pool = NULL;
        int                ret = -1;

        event_pool = GF_CALLOC (1, sizeof (*event_pool),
                                gf_common_mt_event_pool);

        if (!event_pool)
                return NULL;

        event_pool->count = count;
        event_pool->reg = GF_CALLOC (event_pool->count,
                                     sizeof (*event_pool->reg),
                                     gf_common_mt_reg);

        if (!event_pool->reg) {
                GF_FREE (event_pool);
                return NULL;
        }

        pthread_mutex_init (&event_pool->mutex, NULL);

        ret = pipe (event_pool->breaker);

        if (ret == -1) {
                gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED,
                        "pipe creation failed");
                GF_FREE (event_pool->reg);
                GF_FREE (event_pool);
                return NULL;
        }

        ret = fcntl (event_pool->breaker[0], F_SETFL, O_NONBLOCK);
        if (ret == -1) {
                gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
                        "could not set pipe to non blocking mode");
                close (event_pool->breaker[0]);
                close (event_pool->breaker[1]);
                event_pool->breaker[0] = event_pool->breaker[1] = -1;

                GF_FREE (event_pool->reg);
                GF_FREE (event_pool);
                return NULL;
        }

        ret = fcntl (event_pool->breaker[1], F_SETFL, O_NONBLOCK);
        if (ret == -1) {
                gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
                        "could not set pipe to non blocking mode");

                close (event_pool->breaker[0]);
                close (event_pool->breaker[1]);
                event_pool->breaker[0] = event_pool->breaker[1] = -1;

                GF_FREE (event_pool->reg);
                GF_FREE (event_pool);
                return NULL;
        }

        ret = event_register_poll (event_pool, event_pool->breaker[0],
                                   __flush_fd, NULL, 1, 0);
        if (ret == -1) {
                gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED,
                        "could not register pipe fd with poll event loop");
                close (event_pool->breaker[0]);
                close (event_pool->breaker[1]);
                event_pool->breaker[0] = event_pool->breaker[1] = -1;

                GF_FREE (event_pool->reg);
                GF_FREE (event_pool);
                return NULL;
        }

        if (eventthreadcount > 1) {
                gf_msg ("poll", GF_LOG_INFO, 0,
                        LG_MSG_POLL_IGNORE_MULTIPLE_THREADS, "Currently poll "
                        "does not use multiple event processing threads, "
                        "thread count (%d) ignored", eventthreadcount);
        }

        return event_pool;
}
コード例 #2
0
ファイル: procdiggy.c プロジェクト: amarts/glusterfs
pid_t
pidinfo(pid_t pid, char **name)
{
    char buf[NAME_MAX * 2] = {
        0,
    };
    FILE *f = NULL;
    char path[PATH_MAX] = {
        0,
    };
    char *p = NULL;
    int ret = 0;

    snprintf(path, sizeof path, PROC "/%d/status", pid);

    f = fopen(path, "r");
    if (!f)
        return -1;

    if (name)
        *name = NULL;
    for (;;) {
        size_t len;
        memset(buf, 0, sizeof(buf));
        if (fgets(buf, sizeof(buf), f) == NULL || (len = strlen(buf)) == 0 ||
            buf[len - 1] != '\n') {
            pid = -1;
            goto out;
        }
        buf[len - 1] = '\0';

        if (name && !*name) {
            p = strtail(buf, "Name:");
            if (p) {
                while (isspace(*++p))
                    ;
                *name = gf_strdup(p);
                if (!*name) {
                    pid = -2;
                    goto out;
                }
                continue;
            }
        }

        p = strtail(buf, "PPid:");
        if (p)
            break;
    }

    while (isspace(*++p))
        ;
    ret = gf_string2int(p, &pid);
    if (ret == -1)
        pid = -1;

out:
    fclose(f);
    if (pid == -1 && name && *name)
        GF_FREE(*name);
    if (pid == -2)
        fprintf(stderr, "out of memory\n");
    return pid;
}
コード例 #3
0
static void
readline_destructor (void *ptr)
{
        GF_FREE (ptr);
}
コード例 #4
0
ファイル: addr.c プロジェクト: alexbers/glusterfs_experiments
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          *addr_str       = NULL;
        char          *tmp            = NULL;
        char          *addr_cpy       = NULL;
        char          *service        = NULL;
        uint16_t       peer_port      = 0;
        char           is_inet_sdp    = 0;
        char           negate         = 0;
        char           match          = 0;
        char           peer_addr[UNIX_PATH_MAX];
        char          *type           = NULL;
        gf_boolean_t   allow_insecure = _gf_false;

        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: backword 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;
        }

        peer_info = data_to_ptr (peer_info_data);

        switch (((struct sockaddr *) &peer_info->sockaddr)->sa_family)
        {
        case AF_INET_SDP:
                is_inet_sdp = 1;
                ((struct sockaddr *) &peer_info->sockaddr)->sa_family = AF_INET;

        case AF_INET:
        case AF_INET6:
        {
                strcpy (peer_addr, peer_info->identifier);
                service = strrchr (peer_addr, ':');
                *service = '\0';
                service ++;

                if (is_inet_sdp) {
                        ((struct sockaddr *) &peer_info->sockaddr)->sa_family = AF_INET_SDP;
                }

                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);
                        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) {
                addr_cpy = gf_strdup (reject_addr->data);
                if (!addr_cpy)
                        goto out;

                addr_str = strtok_r (addr_cpy, ADDR_DELIMITER, &tmp);

                while (addr_str) {
                        gf_log (name,  GF_LOG_DEBUG,
                                "rejected = \"%s\", received addr = \"%s\"",
                                addr_str, peer_addr);
                        if (addr_str[0] == '!') {
                                negate = 1;
                                addr_str++;
                        }

                        match = fnmatch (addr_str, peer_addr, 0);
                        if (negate ? match : !match) {
                                result = AUTH_REJECT;
                                goto out;
                        }
                        addr_str = strtok_r (NULL, ADDR_DELIMITER, &tmp);
                }
                GF_FREE (addr_cpy);
        }

        if (allow_addr) {
                addr_cpy = gf_strdup (allow_addr->data);
                if (!addr_cpy)
                        goto out;

                addr_str = strtok_r (addr_cpy, ADDR_DELIMITER, &tmp);

                while (addr_str) {
                        gf_log (name,  GF_LOG_DEBUG,
                                "allowed = \"%s\", received addr = \"%s\"",
                                addr_str, peer_addr);
                        if (addr_str[0] == '!') {
                                negate = 1;
                                addr_str++;
                        }

                        match = fnmatch (addr_str, peer_addr, 0);
                        if (negate ? match : !match) {
                                result = AUTH_ACCEPT;
                                goto out;
                        }
                        addr_str = strtok_r (NULL, ADDR_DELIMITER, &tmp);
                }
        }

out:
        if (addr_cpy)
                GF_FREE (addr_cpy);

        return result;
}
コード例 #5
0
ファイル: common-utils.c プロジェクト: syoyo/glusterfs
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;
}
コード例 #6
0
transport_t *
transport_load (dict_t *options,
		xlator_t *xl)
{
	struct transport *trans = NULL, *return_trans = NULL;
	char *name = NULL;
	void *handle = NULL;
	char *type = NULL;
	char str[] = "ERROR";
	int32_t ret = -1;
	int8_t is_tcp = 0, is_unix = 0, is_ibsdp = 0;
	volume_opt_list_t *vol_opt = NULL;

	GF_VALIDATE_OR_GOTO("transport", options, fail);
	GF_VALIDATE_OR_GOTO("transport", xl, fail);
  
	trans = GF_CALLOC (1, sizeof (struct transport),
                           gf_common_mt_transport);
	GF_VALIDATE_OR_GOTO("transport", trans, fail);

	trans->xl = xl;
	type = str;

	/* Backward compatibility */
	ret = dict_get_str (options, "transport-type", &type);
	if (ret < 0) {
		ret = dict_set_str (options, "transport-type", "socket");
		if (ret < 0)
			gf_log ("dict", GF_LOG_DEBUG,
				"setting transport-type failed");
		gf_log ("transport", GF_LOG_WARNING,
			"missing 'option transport-type'. defaulting to "
			"\"socket\"");
	} else {
		{
			/* Backword compatibility to handle * /client,
			 * * /server. 
			 */
			char *tmp = strchr (type, '/');
			if (tmp)
				*tmp = '\0';
		}
		
		is_tcp = strcmp (type, "tcp");
		is_unix = strcmp (type, "unix");
		is_ibsdp = strcmp (type, "ib-sdp");
		if ((is_tcp == 0) ||
		    (is_unix == 0) ||
		    (is_ibsdp == 0)) {
			if (is_unix == 0)
				ret = dict_set_str (options, 
						    "transport.address-family",
						    "unix");
			if (is_ibsdp == 0)
				ret = dict_set_str (options, 
						    "transport.address-family",
						    "inet-sdp");

			if (ret < 0)
				gf_log ("dict", GF_LOG_DEBUG,
					"setting address-family failed");

			ret = dict_set_str (options, 
					    "transport-type", "socket");
			if (ret < 0)
				gf_log ("dict", GF_LOG_DEBUG,
					"setting transport-type failed");
		}
	}

	ret = dict_get_str (options, "transport-type", &type);
	if (ret < 0) {
		GF_FREE (trans);
		gf_log ("transport", GF_LOG_ERROR,
			"'option transport-type <xx>' missing in volume '%s'",
			xl->name);
		goto fail;
	}

	ret = gf_asprintf (&name, "%s/%s.so", TRANSPORTDIR, type);
        if (-1 == ret) {
                gf_log ("transport", GF_LOG_ERROR, "asprintf failed");
                goto fail;
        }
	gf_log ("transport", GF_LOG_DEBUG,
		"attempt to load file %s", name);

	handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
	if (handle == NULL) {
		gf_log ("transport", GF_LOG_ERROR, "%s", dlerror ());
		gf_log ("transport", GF_LOG_ERROR,
			"volume '%s': transport-type '%s' is not valid or "
			"not found on this machine", 
			xl->name, type);
		GF_FREE (name);
		GF_FREE (trans);
		goto fail;
	}
	GF_FREE (name);
	
	trans->ops = dlsym (handle, "tops");
	if (trans->ops == NULL) {
		gf_log ("transport", GF_LOG_ERROR,
			"dlsym (transport_ops) on %s", dlerror ());
		GF_FREE (trans);
		goto fail;
	}

	trans->init = dlsym (handle, "init");
	if (trans->init == NULL) {
		gf_log ("transport", GF_LOG_ERROR,
			"dlsym (gf_transport_init) on %s", dlerror ());
		GF_FREE (trans);
		goto fail;
	}

	trans->fini = dlsym (handle, "fini");
	if (trans->fini == NULL) {
		gf_log ("transport", GF_LOG_ERROR,
			"dlsym (gf_transport_fini) on %s", dlerror ());
		GF_FREE (trans);
		goto fail;
	}
	
	vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
                             gf_common_mt_volume_opt_list_t);
	vol_opt->given_opt = dlsym (handle, "options");
	if (vol_opt->given_opt == NULL) {
		gf_log ("transport", GF_LOG_DEBUG,
			"volume option validation not specified");
	} else {
		list_add_tail (&vol_opt->list, &xl->volume_options);
		if (-1 == 
		    validate_xlator_volume_options (xl, 
						    vol_opt->given_opt)) {
			gf_log ("transport", GF_LOG_ERROR,
				"volume option validation failed");
			GF_FREE (trans);
			goto fail;
		}
	}
	
	ret = trans->init (trans);
	if (ret != 0) {
		gf_log ("transport", GF_LOG_ERROR,
			"'%s' initialization failed", type);
		GF_FREE (trans);
		goto fail;
	}

	pthread_mutex_init (&trans->lock, NULL);
	return_trans = trans;
fail:
	return return_trans;
}
コード例 #7
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;
        glusterd_peerinfo_t    *peerinfo        = 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_friend_find_by_uuid (lock_req.uuid, &peerinfo)) {
                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;
        }

        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);
                /* The above function does not take ownership of ctx.
                 * Therefore we need to free the ctx explicitly. */
                free_ctx = _gf_true;
        }
        else {
                ret = glusterd_op_state_machine_mgmt_v3_unlock (req, &lock_req,
                                                                ctx);
        }

out:

        if (ret || free_ctx) {
                if (ctx->dict)
                        dict_unref (ctx->dict);
                if (ctx)
                        GF_FREE (ctx);
        }

        free (lock_req.dict.dict_val);

        gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
        return ret;
}
コード例 #8
0
ファイル: store.c プロジェクト: Anna-Miya-Dan/glusterfs
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;
}
コード例 #9
0
ファイル: store.c プロジェクト: Anna-Miya-Dan/glusterfs
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;
}
コード例 #10
0
ファイル: addr.c プロジェクト: raghavendrabhat/glusterfs
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);
}
コード例 #11
0
ファイル: store.c プロジェクト: sytuxww/glusterfs
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;
}
コード例 #12
0
ファイル: addr.c プロジェクト: raghavendrabhat/glusterfs
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;
}
コード例 #13
0
ファイル: gidcache.c プロジェクト: amarts/glusterfs
/*
 * Add a new list entry to the cache. If an entry for this ID already exists,
 * update it.
 */
int
gid_cache_add(gid_cache_t *cache, gid_list_t *gl)
{
    gid_list_t *agl;
    int bucket;
    int i;
    time_t now;

    if (!gl || !gl->gl_list)
        return -1;

    if (!cache->gc_max_age)
        return 0;

    LOCK(&cache->gc_lock);
    now = time(NULL);

    /*
     * Scan for the first free entry or one that matches this id. The id
     * check is added to address a bug where the cache might contain an
     * expired entry for this id. Since lookup occurs in LRU order and
     * does not reclaim entries, it will always return failure on discovery
     * of an expired entry. This leads to duplicate entries being added,
     * which still do not satisfy lookups until the expired entry (and
     * everything before it) is reclaimed.
     *
     * We address this through reuse of an entry already allocated to this
     * id, whether expired or not, since we have obviously already received
     * more recent data. The entry is repopulated with the new data and a new
     * deadline and is pushed forward to reside as the last populated entry in
     * the bucket.
     */
    bucket = gl->gl_id % cache->gc_nbuckets;
    agl = BUCKET_START(cache->gc_cache, bucket);
    for (i = 0; i < AUX_GID_CACHE_ASSOC; ++i, ++agl) {
        if (agl->gl_id == gl->gl_id)
            break;
        if (!agl->gl_list)
            break;
    }

    /*
     * The way we allocate free entries naturally places the newest
     * ones at the highest indices, so evicting the lowest makes
     * sense, but that also means we can't just replace it with the
     * one that caused the eviction.  That would cause us to thrash
     * the first entry while others remain idle.  Therefore, we
     * need to slide the other entries down and add the new one at
     * the end just as if the *last* slot had been free.
     *
     * Deadline expiration is also handled here, since the oldest
     * expired entry will be in the first position.  This does mean
     * the bucket can stay full of expired entries if we're idle
     * but, if the small amount of extra memory or scan time before
     * we decide to evict someone ever become issues, we could
     * easily add a reaper thread.
     */

    if (i >= AUX_GID_CACHE_ASSOC) {
        /* cache full, evict the first (LRU) entry */
        i = 0;
        agl = BUCKET_START(cache->gc_cache, bucket);
        GF_FREE(agl->gl_list);
    } else if (agl->gl_list) {
        /* evict the old entry we plan to reuse */
        GF_FREE(agl->gl_list);
    }

    /*
     * If we have evicted an entry, slide the subsequent populated entries
     * back and populate the last entry.
     */
    for (; i < AUX_GID_CACHE_ASSOC - 1; i++) {
        if (!agl[1].gl_list)
            break;
        agl[0] = agl[1];
        agl++;
    }

    agl->gl_id = gl->gl_id;
    agl->gl_uid = gl->gl_uid;
    agl->gl_gid = gl->gl_gid;
    agl->gl_count = gl->gl_count;
    agl->gl_list = gl->gl_list;
    agl->gl_deadline = now + cache->gc_max_age;

    UNLOCK(&cache->gc_lock);

    return 1;
}
コード例 #14
0
ファイル: bd-aio.c プロジェクト: 2510/glusterfs
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;
}
コード例 #15
0
ファイル: exports.c プロジェクト: gluster/glusterfs
/**
 * __exp_line_host_parse -- Extract the hosts in the line
 *                          and call helper functions to parse
 *                          the string.
 *
 * The call chain goes like this:
 *
 * 1) __exp_line_host_parse ("/test  hostip(sec=sys,rw,anonuid=0)")
 * 2) __exp_line_ng_host_str_parse ("hostip(sec=sys,rw,anonuid=0)");
 * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)");
 *
 *
 * @line    : The line to parse
 * @ng_dict : Double pointer to the dict we want to
 *            insert hosts into.
 *
 * Allocates the dict, extracts host strings from the line,
 * parses them into a struct export_item structure and inserts
 * them in the dict.
 *
 * @return: success: GF_EXP_PARSE_SUCCESS
 *          failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure,
 *                   GF_EXP_PARSE_ITEM_NOT_FOUND if the host was not found,
 *                   -EINVAL on bad args, -ENOMEM on allocation errors.
 *
 * Not for external use.
 */
static int
__exp_line_host_parse(const char *line, dict_t **host_dict)
{
    dict_t *hosts = NULL;
    char *strmatch = NULL;
    int ret = -EINVAL;
    struct export_item *exp_host = NULL;
    data_t *hostdata = NULL;

    GF_VALIDATE_OR_GOTO(GF_EXP, line, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, host_dict, out);

    *host_dict = NULL;

    /* Initialize a parser with the line to parse and the regex used to
     * parse it.
     */
    ret = parser_set_string(hostname_parser, line);
    if (ret < 0) {
        goto out;
    }

    gf_msg_trace(GF_EXP, 0, "parsing line: %s", line);

    while ((strmatch = parser_get_next_match(hostname_parser))) {
        if (!hosts) {
            /* Allocate a new dictto store the netgroups. */
            hosts = dict_new();
            GF_CHECK_ALLOC(hosts, ret, free_and_out);
        }

        gf_msg_trace(GF_EXP, 0, "parsing hostname: %s", strmatch);

        ret = __exp_line_ng_host_str_parse(strmatch, &exp_host);

        if (ret != 0) {
            /* Parsing or other critical error, free allocated
             * memory and exit. The caller will handle the errors.
             */
            _exp_dict_destroy(hosts);
            goto free_and_out;
        }

        /* Insert export item structure into the hosts dict. */
        hostdata = bin_to_data(exp_host, sizeof(*exp_host));
        dict_set(hosts, exp_host->name, hostdata);

        /* Free this matched string and continue parsing.*/
        GF_FREE(strmatch);
    }

    /* If the hosts dict was not allocated, then we know that
     * no matches were found.
     */
    if (!exp_host) {
        ret = GF_EXP_PARSE_ITEM_NOT_FOUND;
        parser_unset_string(hostname_parser);
        goto out;
    }

    ret = GF_EXP_PARSE_SUCCESS;
    *host_dict = hosts;

free_and_out:
    parser_unset_string(hostname_parser);
    GF_FREE(strmatch);
out:
    return ret;
}
コード例 #16
0
int
gf_sql_delete_unwind (gf_sql_connection_t  *sql_conn,
                          gfdb_db_record_t     *gfdb_db_record)
{
        int ret = -1;
        char *gfid_str = NULL;
        char *pargfid_str = NULL;
        gfdb_time_t *modtime    = NULL;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);

        gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid));
        if (!gfid_str) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
                goto out;
        }

        /*Nuke all the entries for this GFID from DB*/
        if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL_ALL) {
                gf_sql_delete_all(sql_conn, gfid_str);
        }
        /*Remove link entries only*/
        else if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL) {

                pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid));
                if (!pargfid_str) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CREATE_FAILED, "Creating pargfid_str "
                                "string failed.");
                        goto out;
                }

                /* Special performance case:
                 * Updating wind time in unwind for delete. This is done here
                 * as in the wind path we will not know whether its the last
                 * link or not. For a last link there is not use to update any
                 * wind or unwind time!*/
                if (gfdb_db_record->do_record_times) {
                        /*Update the wind write times*/
                        modtime = &gfdb_db_record->gfdb_wind_change_time;
                        ret = gf_update_time (sql_conn, gfid_str, modtime,
                                gfdb_db_record->do_record_counters,
                                _gf_true,
                                isreadfop (gfdb_db_record->gfdb_fop_type));
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_UPDATE_FAILED,
                                        "Failed update wind time in DB");
                                goto out;
                        }
                }

                modtime = &gfdb_db_record->gfdb_unwind_change_time;

                ret = gf_sql_delete_link(sql_conn, gfid_str, pargfid_str,
                                        gfdb_db_record->file_name);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_DELETE_FAILED, "Failed deleting link");
                        goto out;
                }

                if (gfdb_db_record->do_record_times &&
                        gfdb_db_record->do_record_uwind_time) {
                        ret = gf_update_time (sql_conn, gfid_str, modtime,
                                gfdb_db_record->do_record_counters,
                                _gf_false,
                                isreadfop(gfdb_db_record->gfdb_fop_type));
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_UPDATE_FAILED, "Failed update "
                                        "unwind time in DB");
                                goto out;
                        }
                }
        } else {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_INVALID_UPLINK, "Invalid unlink option");
                goto out;
        }
        ret = 0;
out:
        GF_FREE (gfid_str);
        GF_FREE (pargfid_str);
        return ret;
}
コード例 #17
0
ファイル: auth-cache.c プロジェクト: aaronott/glusterfs
/**
 * cache_nfs_fh -- Places the nfs file handle in the underlying dict as we are
 *                 using as our cache. The key is "exportid:gfid:host_addr", the
 *                 value is an entry struct containing the export item that
 *                 was authorized for the operation and the file handle that was
 *                 authorized.
 *
 * @cache: The cache to place fh's in
 * @fh   : The fh to cache
 * @host_addr: The address of the host
 * @export_item: The export item that was authorized
 *
 */
int
cache_nfs_fh (struct auth_cache *cache, struct nfs3_fh *fh,
              const char *host_addr, struct export_item *export_item)
{
        int                      ret        = -EINVAL;
        char                    *hashkey    = NULL;
        data_t                  *entry_data = NULL;
        time_t                   timestamp  = 0;
        gf_boolean_t             can_write  = _gf_false;
        struct auth_cache_entry *entry      = NULL;

        GF_VALIDATE_OR_GOTO (GF_NFS, host_addr, out);
        GF_VALIDATE_OR_GOTO (GF_NFS, cache, out);
        GF_VALIDATE_OR_GOTO (GF_NFS, fh, out);

        /* If a dict has not been allocated already, allocate it. */
        if (!cache->cache_dict) {
                cache->cache_dict = dict_new ();
                if (!cache->cache_dict) {
                        ret = -ENOMEM;
                        goto out;
                }
        }

        /* If we could already find it in the cache, just return */
        ret = auth_cache_lookup (cache, fh, host_addr, &timestamp, &can_write);
        if (ret == 0) {
                gf_msg_trace (GF_NFS, 0, "found cached auth/fh for host "
                              "%s", host_addr);
                goto out;
        }

        make_hashkey (hashkey, fh, host_addr);

        entry = auth_cache_entry_init ();
        if (!entry) {
                ret = -ENOMEM;
                goto out;
        }

        entry->timestamp = time (NULL);
        entry->item = export_item;

        /* The cache entry will simply be the time that the entry
         * was cached.
         */
        entry_data = bin_to_data (entry, sizeof (*entry));
        if (!entry_data) {
                GF_FREE (entry);
                goto out;
        }

        ret = dict_set (cache->cache_dict, hashkey, entry_data);
        if (ret == -1) {
                GF_FREE (entry);
                goto out;
        }
        gf_msg_trace (GF_NFS, 0, "Caching file-handle (%s)", host_addr);
        ret = 0;
out:
        return ret;
}
コード例 #18
0
int
gf_sql_insert_wind (gf_sql_connection_t  *sql_conn,
                   gfdb_db_record_t     *gfdb_db_record)
{
        int ret                 = -1;
        gfdb_time_t *modtime    = NULL;
        char *pargfid_str       = NULL;
        char *gfid_str          = NULL;
        char *old_pargfid_str   = NULL;
        gf_boolean_t its_wind   = _gf_true;/*remains true for this function*/



        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);


        gfid_str = gf_strdup (uuid_utoa (gfdb_db_record->gfid));
        if (!gfid_str) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
                goto out;
        }

        modtime = &gfdb_db_record->gfdb_wind_change_time;

        /* handle all dentry based operations */
        if (isdentryfop (gfdb_db_record->gfdb_fop_type)) {
                /*Parent GFID is always set*/
                pargfid_str = gf_strdup (uuid_utoa (gfdb_db_record->pargfid));
                if (!pargfid_str) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CREATE_FAILED, "Creating gfid string "
                                "failed.");
                        goto out;
                }

                /* handle create, mknod */
                if (isdentrycreatefop (gfdb_db_record->gfdb_fop_type)) {
                        /*insert link*/
                        ret = gf_sql_insert_link(sql_conn,
                                        gfid_str, pargfid_str,
                                        gfdb_db_record->file_name,
                                        gfdb_db_record->file_path,
                                        gfdb_db_record->link_consistency,
                                        gfdb_db_record->ignore_errors);
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_INSERT_FAILED, "Failed "
                                        "inserting link in DB");
                                goto out;
                        }
                        gfdb_db_record->islinkupdate = gfdb_db_record->
                                                        link_consistency;

                        /*
                         * Only for create/mknod insert wind time
                         * for the first time
                         * */
                        ret = gf_sql_insert_write_wind_time (sql_conn, gfid_str,
                                                                modtime);
                        if (ret) {
                                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                        LG_MSG_INSERT_FAILED, "Failed "
                                        "inserting wind time in DB");
                                goto out;
                        }
                        goto out;
                }
                /*handle rename, link */
                else {
                        /*rename*/
                        if (strlen (gfdb_db_record->old_file_name) != 0) {
                                old_pargfid_str = gf_strdup (uuid_utoa (
                                                gfdb_db_record->old_pargfid));
                                if (!old_pargfid_str) {
                                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
                                                0, LG_MSG_CREATE_FAILED,
                                                "Creating gfid string failed.");
                                        goto out;
                                }
                                ret = gf_sql_update_link (sql_conn, gfid_str,
                                                pargfid_str,
                                                gfdb_db_record->file_name,
                                                gfdb_db_record->file_path,
                                                old_pargfid_str,
                                                gfdb_db_record->old_file_name,
                                                gfdb_db_record->
                                                        link_consistency);
                                if (ret) {
                                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
                                                0, LG_MSG_UPDATE_FAILED,
                                                "Failed updating link");
                                        goto out;
                                }
                                gfdb_db_record->islinkupdate = gfdb_db_record->
                                                        link_consistency;
                        }
                        /*link*/
                        else {
                                ret = gf_sql_insert_link (sql_conn,
                                        gfid_str, pargfid_str,
                                        gfdb_db_record->file_name,
                                        gfdb_db_record->file_path,
                                        gfdb_db_record->link_consistency,
                                        gfdb_db_record->ignore_errors);
                                if (ret) {
                                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
                                                0, LG_MSG_INSERT_FAILED,
                                                "Failed inserting link in DB");
                                        goto out;
                                }
                                gfdb_db_record->islinkupdate = gfdb_db_record->
                                                        link_consistency;
                        }
                }
        }

        /* update times only when said!*/
        if (gfdb_db_record->do_record_times) {
                /*All fops update times read or write*/
                ret = gf_update_time (sql_conn, gfid_str, modtime,
                        gfdb_db_record->do_record_counters,
                        its_wind,
                        isreadfop (gfdb_db_record->gfdb_fop_type));
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_UPDATE_FAILED, "Failed update wind time"
                                " in DB");
                        goto out;
                }
        }

        ret = 0;
out:
        GF_FREE (gfid_str);
        GF_FREE (pargfid_str);
        GF_FREE (old_pargfid_str);
        return ret;
}
コード例 #19
0
static int
glusterd_handle_post_validate_fn (rpcsvc_request_t *req)
{
        int32_t                         ret       = -1;
        gd1_mgmt_v3_post_val_req         op_req    = {{0},};
        glusterd_peerinfo_t            *peerinfo  = NULL;
        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_friend_find_by_uuid (op_req.uuid, &peerinfo)) {
                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);

        gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
        return ret;
}
コード例 #20
0
int
gf_sql_insert_unwind (gf_sql_connection_t  *sql_conn,
                     gfdb_db_record_t     *gfdb_db_record)
{

        int ret = -1;
        gfdb_time_t *modtime    = NULL;
        gf_boolean_t its_wind   = _gf_true;/*remains true for this function*/
        char *gfid_str = NULL;
        char *pargfid_str = NULL;

        CHECK_SQL_CONN (sql_conn, out);
        GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);

        gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid));
        if (!gfid_str) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
                goto out;
        }

        /*Only update if recording unwind is set*/
        if (gfdb_db_record->do_record_times &&
                gfdb_db_record->do_record_uwind_time) {
                modtime = &gfdb_db_record->gfdb_unwind_change_time;
                ret = gf_update_time (sql_conn, gfid_str, modtime,
                        gfdb_db_record->do_record_counters,
                        (!its_wind),
                        isreadfop (gfdb_db_record->gfdb_fop_type));
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_UPDATE_FAILED, "Failed update unwind "
                                "time in DB");
                        goto out;
                }
        }

        /*For link creation and changes we use link updated*/
        if (gfdb_db_record->islinkupdate &&
                isdentryfop(gfdb_db_record->gfdb_fop_type)) {

                pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid));
                if (!pargfid_str) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_CREATE_FAILED,
                                "Creating pargfid_str string failed.");
                        goto out;
                }

                ret = gf_sql_update_link_flags (sql_conn, gfid_str, pargfid_str,
                                        gfdb_db_record->file_name, 0, _gf_true);
                if (ret) {
                        gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                                LG_MSG_UPDATE_FAILED, "Failed updating link "
                                "flags in unwind");
                        goto out;
                }
        }

        ret = 0;
out:
        GF_FREE (gfid_str);
        GF_FREE (pargfid_str);
        return ret;
}
コード例 #21
0
ファイル: login.c プロジェクト: gluster/glusterfs
auth_result_t
gf_auth(dict_t *input_params, dict_t *config_params)
{
    auth_result_t result = AUTH_DONT_CARE;
    int ret = 0;
    data_t *allow_user = NULL;
    data_t *username_data = NULL;
    data_t *passwd_data = NULL;
    data_t *password_data = NULL;
    char *username = NULL;
    char *password = NULL;
    char *brick_name = NULL;
    char *searchstr = NULL;
    char *username_str = NULL;
    char *tmp = NULL;
    char *username_cpy = NULL;
    gf_boolean_t using_ssl = _gf_false;
    gf_boolean_t strict_auth = _gf_false;

    username_data = dict_get(input_params, "ssl-name");
    if (username_data) {
        gf_log("auth/login", GF_LOG_INFO, "connecting user name: %s",
               username_data->data);
        using_ssl = _gf_true;
    } else {
        ret = dict_get_str_boolean(config_params, "strict-auth-accept",
                                   _gf_false);
        if (ret == -1)
            strict_auth = _gf_false;
        else
            strict_auth = ret;

        username_data = dict_get(input_params, "username");
        if (!username_data) {
            if (strict_auth) {
                gf_log("auth/login", GF_LOG_DEBUG,
                       "username not found, strict auth"
                       " configured returning REJECT");
                result = AUTH_REJECT;
            } else {
                gf_log("auth/login", GF_LOG_DEBUG,
                       "username not found, returning"
                       " DONT-CARE");
            }
            goto out;
        }
        password_data = dict_get(input_params, "password");
        if (!password_data) {
            if (strict_auth) {
                gf_log("auth/login", GF_LOG_DEBUG,
                       "password not found, strict auth"
                       " configured returning REJECT");
                result = AUTH_REJECT;
            } else {
                gf_log("auth/login", GF_LOG_WARNING,
                       "password not found, returning"
                       " DONT-CARE");
            }
            goto out;
        }
        password = data_to_str(password_data);
    }
    username = data_to_str(username_data);

    brick_name = data_to_str(dict_get(input_params, "remote-subvolume"));
    if (!brick_name) {
        gf_log("auth/login", GF_LOG_ERROR, "remote-subvolume not specified");
        result = AUTH_REJECT;
        goto out;
    }

    ret = gf_asprintf(&searchstr, "auth.login.%s.%s", brick_name,
                      using_ssl ? "ssl-allow" : "allow");
    if (-1 == ret) {
        gf_log("auth/login", GF_LOG_ERROR,
               "asprintf failed while setting search string, "
               "returning REJECT");
        result = AUTH_REJECT;
        goto out;
    }

    allow_user = dict_get(config_params, searchstr);
    GF_FREE(searchstr);

    if (allow_user) {
        gf_log("auth/login", GF_LOG_INFO, "allowed user names: %s",
               allow_user->data);
        /*
         * There's a subtle difference between SSL and non-SSL behavior
         * if we can't match anything in the "while" loop below.
         * Intuitively, we should AUTH_REJECT if there's no match.
         * However, existing code depends on allowing untrusted users
         * to connect with *no credentials at all* by falling through
         * the loop.  They're still distinguished from trusted users
         * who do provide a valid username and password (in fact that's
         * pretty much the only thing we use non-SSL login auth for),
         * but they are allowed to connect.  It's wrong, but it's not
         * worth changing elsewhere.  Therefore, we do the sane thing
         * only for SSL here.
         *
         * For SSL, if there's a list *you must be on it*.  Note that
         * if there's no list we don't care.  In that case (and the
         * ssl-allow=* case as well) authorization is effectively
         * disabled, though authentication and encryption are still
         * active.
         *
         * Read NOTE on strict_auth above.
         */
        if (using_ssl || strict_auth) {
            result = AUTH_REJECT;
        }
        username_cpy = gf_strdup(allow_user->data);
        if (!username_cpy)
            goto out;

        username_str = strtok_r(username_cpy, " ,", &tmp);

        /*
         * We have to match a user's *authenticated* name to one in the
         * list.  If we're using SSL, they're already authenticated.
         * Otherwise, they need a matching password to complete the
         * process.
         */
        while (username_str) {
            if (!fnmatch(username_str, username, 0)) {
                if (using_ssl) {
                    result = AUTH_ACCEPT;
                    break;
                }
                ret = gf_asprintf(&searchstr, "auth.login.%s.password",
                                  username);
                if (-1 == ret) {
                    gf_log("auth/login", GF_LOG_WARNING,
                           "asprintf failed while setting search string");
                    goto out;
                }
                passwd_data = dict_get(config_params, searchstr);
                GF_FREE(searchstr);

                if (!passwd_data) {
                    gf_log("auth/login", GF_LOG_ERROR,
                           "wrong username/password combination");
                    result = AUTH_REJECT;
                    goto out;
                }

                result = !((strcmp(data_to_str(passwd_data), password))
                               ? AUTH_ACCEPT
                               : AUTH_REJECT);
                if (result == AUTH_REJECT)
                    gf_log("auth/login", GF_LOG_ERROR,
                           "wrong password for user %s", username);

                break;
            }
            username_str = strtok_r(NULL, " ,", &tmp);
        }
    }

out:
    GF_FREE(username_cpy);

    return result;
}
コード例 #22
0
ファイル: rbthash.c プロジェクト: mdjunaid/glusterfs
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;
}
コード例 #23
0
ファイル: xlator.c プロジェクト: koordinates/glusterfs
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;
}
コード例 #24
0
ファイル: exports.c プロジェクト: gluster/glusterfs
/**
 * __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;
}
コード例 #25
0
ファイル: mount3udp_svc.c プロジェクト: AsherBond/glusterfs
static void
mountudp_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
{
        union {
                dirpath mountudpproc3_mnt_3_arg;
        } argument;
        char                    *result = NULL;
        xdrproc_t               _xdr_argument = NULL, _xdr_result = NULL;
        char *(*local)(char *, struct svc_req *) = NULL;
        mountres3               *res = NULL;
        struct sockaddr_in      *sin = NULL;

        sin = svc_getcaller (transp);
        inet_ntop (AF_INET, &sin->sin_addr, mnthost, INET_ADDRSTRLEN+1);

        switch (rqstp->rq_proc) {
        case NULLPROC:
                (void) svc_sendreply (transp, (xdrproc_t) xdr_void,
                                      (char *)NULL);
                return;

        case MOUNT3_MNT:
                _xdr_argument = (xdrproc_t) xdr_dirpath;
                _xdr_result = (xdrproc_t) xdr_mountres3;
                local = (char *(*)(char *,
                                   struct svc_req *)) mountudpproc3_mnt_3_svc;
                break;

        case MOUNT3_UMNT:
                _xdr_argument = (xdrproc_t) xdr_dirpath;
                _xdr_result = (xdrproc_t) xdr_mountstat3;
                local = (char *(*)(char *,
                                   struct svc_req *)) mountudpproc3_umnt_3_svc;
                break;

        default:
                svcerr_noproc (transp);
                return;
        }
        memset ((char *)&argument, 0, sizeof (argument));
        if (!svc_getargs (transp, (xdrproc_t) _xdr_argument,
                          (caddr_t) &argument)) {
                svcerr_decode (transp);
                return;
        }
        result = (*local)((char *)&argument, rqstp);
        if (result == NULL) {
                gf_log (GF_MNT, GF_LOG_DEBUG, "PROC returned error");
                svcerr_systemerr (transp);
        }
        if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result,
                                             result)) {
                gf_log (GF_MNT, GF_LOG_ERROR, "svc_sendreply returned error");
                svcerr_systemerr (transp);
        }
        if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument,
                           (caddr_t) &argument)) {
                gf_log (GF_MNT, GF_LOG_ERROR, "unable to free arguments");
        }
        if (result == NULL)
                return;
        /* free the result */
        switch (rqstp->rq_proc) {
        case MOUNT3_MNT:
                res = (mountres3 *) result;
                GF_FREE (res->mountres3_u.mountinfo.fhandle.fhandle3_val);
                GF_FREE (res->mountres3_u.mountinfo.auth_flavors.auth_flavors_val);
                GF_FREE (res);
                break;

        case MOUNT3_UMNT:
                GF_FREE (result);
                break;
        }
        return;
}
コード例 #26
0
ファイル: exports.c プロジェクト: gluster/glusterfs
/**
 * __exp_line_ng_host_str_parse -- Parse the netgroup or host string
 *
 *      e.g. @mygroup(<options>), parsing @mygroup and (<options>)
 *      or   myhost001.dom(<options>), parsing myhost001.dom and (<options>)
 *
 * @line      : The line to parse
 * @exp_item  : Double pointer to a struct export_item
 *
 * @return: success: GF_PARSE_SUCCESS
 *          failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure,
 *                   -EINVAL on bad args, -ENOMEM on allocation errors.
 *
 * Not for external use.
 */
static int
__exp_line_ng_host_str_parse(char *str, struct export_item **exp_item)
{
    struct export_item *item = NULL;
    int ret = -EINVAL;
    char *parens = NULL;
    char *optstr = NULL;
    struct export_options *exp_opts = NULL;
    char *item_name = NULL;

    GF_VALIDATE_OR_GOTO(GF_EXP, str, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, exp_item, out);

    /* A netgroup/host string looks like this:
     * @test(sec=sys,rw,anonuid=0) or host(sec=sys,rw,anonuid=0)
     * We want to extract the name, 'test' or 'host'
     * Again, we could setup a regex and use it here,
     * but its simpler to find the '(' and copy until
     * there.
     */
    parens = strchr(str, '(');
    if (!parens) {
        /* Parse error if there are no parens. */
        ret = GF_EXP_PARSE_ITEM_FAILURE;
        goto out;
    }

    *parens = '\0'; /* Temporarily terminate it so we can do a copy */

    if (strlen(str) > FQDN_MAX_LEN) {
        ret = GF_EXP_PARSE_ITEM_FAILURE;
        goto out;
    }

    /* Strip leading whitespaces */
    while (*str == ' ' || *str == '\t')
        str++;

    item_name = gf_strdup(str);
    GF_CHECK_ALLOC(item_name, ret, out);

    gf_msg_trace(GF_EXP, 0, "found hostname/netgroup: %s", item_name);

    /* Initialize an export item for this */
    item = _export_item_init();
    GF_CHECK_ALLOC(item, ret, free_and_out);
    item->name = item_name;

    *parens = '('; /* Restore the string */

    /* Options start at the parentheses */
    optstr = parens;

    ret = __exp_line_opt_parse(optstr, &exp_opts);
    if (ret != 0) {
        /* Bubble up the error to the caller */
        GF_REF_PUT(item);
        goto out;
    }

    item->opts = exp_opts;

    *exp_item = item;

    ret = GF_EXP_PARSE_SUCCESS;
    goto out;

free_and_out:
    GF_FREE(item_name);
out:
    return ret;
}
コード例 #27
0
ファイル: gsyncd.c プロジェクト: Xarthisius/glusterfs
static int
invoke_rsync (int argc, char **argv)
{
        int i                  = 0;
        char path[PATH_MAX]    = {0,};
        pid_t pid              = -1;
        pid_t ppid             = -1;
        pid_t pida[]           = {-1, -1};
        char *name             = NULL;
        char buf[PATH_MAX + 1] = {0,};
        int ret                = 0;

        assert (argv[argc] == NULL);

        if (argc < 2 || strcmp (argv[1], "--server") != 0)
                goto error;

        for (i = 2; i < argc && argv[i][0] == '-'; i++);

        if (!(i == argc - 2 && strcmp (argv[i], ".") == 0 && argv[i + 1][0] == '/')) {
                fprintf (stderr, "need an rsync invocation without protected args\n");
                goto error;
        }

        /* look up sshd we are spawned from */
        for (pid = getpid () ;; pid = ppid) {
                ppid = pidinfo (pid, &name);
                if (ppid < 0) {
                        fprintf (stderr, "sshd ancestor not found\n");
                        goto error;
                }
                if (strcmp (name, "sshd") == 0) {
                        GF_FREE (name);
                        break;
                }
                GF_FREE (name);
        }
        /* look up "ssh-sibling" gsyncd */
        pida[0] = pid;
        ret = prociter (find_gsyncd, pida);
        if (ret == -1 || pida[1] == -1) {
                fprintf (stderr, "gsyncd sibling not found\n");
                goto error;
        }
        /* check if rsync target matches gsyncd target */
        sprintf (path, PROC"/%d/cwd", pida[1]);
        ret = readlink (path, buf, sizeof (buf));
        if (ret == -1 || ret == sizeof (buf))
                goto error;
        if (strcmp (argv[argc - 1], "/") == 0 /* root dir cannot be a target */ ||
            (strcmp (argv[argc - 1], path) /* match against gluster target */ &&
             strcmp (argv[argc - 1], buf) /* match against file target */) != 0) {
                fprintf (stderr, "rsync target does not match "GEOREP" session\n");
                goto error;
        }

        argv[0] = RSYNC;

        execvp (RSYNC, argv);

        fprintf (stderr, "exec of "RSYNC" failed\n");
        return 127;

 error:
        fprintf (stderr, "disallowed "RSYNC" invocation\n");
        return 1;
}
コード例 #28
0
ファイル: exports.c プロジェクト: gluster/glusterfs
/**
 * __exp_line_ng_parse -- Extract the netgroups in the line
 *                        and call helper functions to parse
 *                        the string.
 *
 * The call chain goes like this:
 *
 * 1) __exp_line_ng_parse ("/test  @test(sec=sys,rw,anonuid=0)")
 * 2) __exp_line_ng_str_parse ("@test(sec=sys,rw,anonuid=0)");
 * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)");
 *
 *
 * @line    : The line to parse
 * @ng_dict : Double pointer to the dict we want to
 *            insert netgroups into.
 *
 * Allocates the dict, extracts netgroup strings from the line,
 * parses them into a struct export_item structure and inserts
 * them in the dict.
 *
 * @return: success: GF_EXP_PARSE_SUCCESS
 *          failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure,
 *                   GF_EXP_PARSE_ITEM_NOT_FOUND if the netgroup was not found
 *                   -EINVAL on bad args, -ENOMEM on allocation errors.
 *
 * Not for external use.
 */
static int
__exp_line_ng_parse(const char *line, dict_t **ng_dict)
{
    dict_t *netgroups = NULL;
    char *strmatch = NULL;
    int ret = -EINVAL;
    struct export_item *exp_ng = NULL;
    data_t *ngdata = NULL;

    GF_VALIDATE_OR_GOTO(GF_EXP, line, out);
    GF_VALIDATE_OR_GOTO(GF_EXP, ng_dict, out);

    *ng_dict = NULL; /* Will be set if parse is successful */

    /* Initialize a parser with the line to parse
     * and the regex used to parse it.
     */
    ret = parser_set_string(netgroup_parser, line);
    if (ret < 0) {
        goto out;
    }

    gf_msg_trace(GF_EXP, 0, "parsing line: %s", line);

    while ((strmatch = parser_get_next_match(netgroup_parser))) {
        if (!netgroups) {
            /* Allocate a new dict to store the netgroups. */
            netgroups = dict_new();
            if (!netgroups) {
                ret = -ENOMEM;
                goto free_and_out;
            }
        }

        gf_msg_trace(GF_EXP, 0, "parsing netgroup: %s", strmatch);

        ret = __exp_line_ng_host_str_parse(strmatch, &exp_ng);

        if (ret != 0) {
            /* Parsing or other critical errors.
             * caller will handle return value.
             */
            _exp_dict_destroy(netgroups);
            goto free_and_out;
        }

        ngdata = bin_to_data(exp_ng, sizeof(*exp_ng));
        dict_set(netgroups, exp_ng->name, ngdata);

        /* Free this matched string and continue parsing. */
        GF_FREE(strmatch);
    }

    /* If the netgroups dict was not allocated, then we know that
     * no matches were found.
     */
    if (!netgroups) {
        ret = GF_EXP_PARSE_ITEM_NOT_FOUND;
        parser_unset_string(netgroup_parser);
        goto out;
    }

    ret = GF_EXP_PARSE_SUCCESS;
    *ng_dict = netgroups;

free_and_out:
    parser_unset_string(netgroup_parser);
    GF_FREE(strmatch);
out:
    return ret;
}
コード例 #29
0
ファイル: common-utils.c プロジェクト: aravindhramu/glusterfs
int
gf_strsplit (const char *str, const char *delim,
             char ***tokens, int *token_count)
{
        char *_running = NULL;
        char *running = NULL;
        char *token = NULL;
        char **token_list = NULL;
        int count = 0;
        int i = 0;
        int j = 0;

        if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL) {
                gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
                return -1;
        }

        _running = gf_strdup (str);
        if (_running == NULL)
                return -1;

        running = _running;

        while ((token = strsep (&running, delim)) != NULL) {
                if (token[0] != '\0')
                        count++;
        }
        GF_FREE (_running);

        _running = gf_strdup (str);
        if (_running == NULL)
                return -1;

        running = _running;

        if ((token_list = GF_CALLOC (count, sizeof (char *),
                                     gf_common_mt_char)) == NULL) {
                GF_FREE (_running);
                return -1;
        }

        while ((token = strsep (&running, delim)) != NULL) {
                if (token[0] == '\0')
                        continue;

                token_list[i] = gf_strdup (token);
                if (token_list[i] == NULL)
                        goto free_exit;
                i++;
        }

        GF_FREE (_running);

        *tokens = token_list;
        *token_count = count;
        return 0;

free_exit:
        GF_FREE (_running);
        for (j = 0; j < i; j++)
                GF_FREE (token_list[j]);

        GF_FREE (token_list);
        return -1;
}
コード例 #30
0
ファイル: compat.c プロジェクト: rambhatm/glusterfs
int
solaris_listxattr(const char *path, char *list, size_t size)
{
    int attrdirfd = -1;
    ssize_t len = 0;
    DIR *dirptr = NULL;
    struct dirent *dent = NULL;
    int newfd = -1;
    char *mapped_path = NULL;
    int ret = -1;

    ret = solaris_xattr_resolve_path (path, &mapped_path);
    if (!ret) {
        attrdirfd = attropen (mapped_path, ".", O_RDONLY, 0);
    } else {
        attrdirfd = attropen (path, ".", O_RDONLY, 0);
    }
    if (attrdirfd >= 0) {
        newfd = dup(attrdirfd);
        dirptr = fdopendir(newfd);
        if (dirptr) {
            while ((dent = readdir(dirptr))) {
                size_t listlen = strlen(dent->d_name);
                if (!strcmp(dent->d_name, ".") ||
                        !strcmp(dent->d_name, "..")) {
                    /* we don't want "." and ".." here */
                    continue;
                }
                if (size == 0) {
                    /* return the current size of the list
                       of extended attribute names*/
                    len += listlen + 1;
                } else {
                    /* check size and copy entry + null
                       into list. */
                    if ((len + listlen + 1) > size) {
                        errno = ERANGE;
                        len = -1;
                        break;
                    } else {
                        strncpy(list + len, dent->d_name, listlen);
                        len += listlen;
                        list[len] = '\0';
                        ++len;
                    }
                }
            }

            if (closedir(dirptr) == -1) {
                close (attrdirfd);
                len = -1;
                goto out;
            }
        } else {
            close (attrdirfd);
            len = -1;
            goto out;
        }
        close (attrdirfd);
    }
out:
    if (mapped_path)
        GF_FREE (mapped_path);
    return len;
}