summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/mount3.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/nfs/server/src/mount3.c')
-rw-r--r--xlators/nfs/server/src/mount3.c6426
1 files changed, 3190 insertions, 3236 deletions
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
index f3d7def64d0..f0d8aff999f 100644
--- a/xlators/nfs/server/src/mount3.c
+++ b/xlators/nfs/server/src/mount3.c
@@ -36,119 +36,121 @@
#include <sys/socket.h>
#include <sys/uio.h>
-
/* This macro will assist in freeing up entire link list
* of host_auth_spec structure.
*/
-#define FREE_HOSTSPEC(exp) do { \
- struct host_auth_spec *host= exp->hostspec; \
- while (NULL != host){ \
- struct host_auth_spec* temp = host; \
- host = host->next; \
- if (NULL != temp->host_addr) { \
- GF_FREE (temp->host_addr); \
- } \
- GF_FREE (temp); \
- } \
- exp->hostspec = NULL; \
- } while (0)
+#define FREE_HOSTSPEC(exp) \
+ do { \
+ struct host_auth_spec *host = exp->hostspec; \
+ while (NULL != host) { \
+ struct host_auth_spec *temp = host; \
+ host = host->next; \
+ if (NULL != temp->host_addr) { \
+ GF_FREE(temp->host_addr); \
+ } \
+ GF_FREE(temp); \
+ } \
+ exp->hostspec = NULL; \
+ } while (0)
/* Paths for export and netgroup files */
-const char *exports_file_path = GLUSTERD_DEFAULT_WORKDIR "/nfs/exports";
+const char *exports_file_path = GLUSTERD_DEFAULT_WORKDIR "/nfs/exports";
const char *netgroups_file_path = GLUSTERD_DEFAULT_WORKDIR "/nfs/netgroups";
-typedef ssize_t (*mnt3_serializer) (struct iovec outmsg, void *args);
+typedef ssize_t (*mnt3_serializer)(struct iovec outmsg, void *args);
extern void *
-mount3udp_thread (void *argv);
+mount3udp_thread(void *argv);
static void
-mnt3_export_free (struct mnt3_export *exp)
+mnt3_export_free(struct mnt3_export *exp)
{
- if (!exp)
- return;
-
- if (exp->exptype == MNT3_EXPTYPE_DIR)
- FREE_HOSTSPEC (exp);
- GF_FREE (exp->expname);
- GF_FREE (exp->fullpath);
- GF_FREE (exp);
+ if (!exp)
+ return;
+
+ if (exp->exptype == MNT3_EXPTYPE_DIR)
+ FREE_HOSTSPEC(exp);
+ GF_FREE(exp->expname);
+ GF_FREE(exp->fullpath);
+ GF_FREE(exp);
}
/* Generic reply function for MOUNTv3 specific replies. */
int
-mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc)
+mnt3svc_submit_reply(rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc)
{
- struct iovec outmsg = {0, };
- struct iobuf *iob = NULL;
- struct mount3_state *ms = NULL;
- int ret = -1;
- ssize_t msglen = 0;
- struct iobref *iobref = NULL;
-
- if (!req)
- return -1;
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_NOT_FOUND, "mount state not found");
- goto ret;
- }
-
- /* First, get the io buffer into which the reply in arg will
- * be serialized.
- */
- /* TODO: use 'xdrproc_t' instead of 'sfunc' to get the xdr-size */
- iob = iobuf_get (ms->iobpool);
- if (!iob) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Failed to get iobuf");
- goto ret;
- }
-
- iobuf_to_iovec (iob, &outmsg);
- /* Use the given serializer to translate the give C structure in arg
- * to XDR format which will be written into the buffer in outmsg.
- */
- msglen = sfunc (outmsg, arg);
- if (msglen < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ENCODE_MSG_FAIL,
- "Failed to encode message");
- goto ret;
- }
- outmsg.iov_len = msglen;
-
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Failed to get iobref");
- goto ret;
- }
-
- ret = iobref_add (iobref, iob);
- if (ret) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Failed to add iob to iobref");
- goto ret;
- }
-
- /* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
- if (ret == -1) {
- gf_msg (GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_REP_SUBMIT_FAIL,
- "Reply submission failed");
- goto ret;
- }
+ struct iovec outmsg = {
+ 0,
+ };
+ struct iobuf *iob = NULL;
+ struct mount3_state *ms = NULL;
+ int ret = -1;
+ ssize_t msglen = 0;
+ struct iobref *iobref = NULL;
+
+ if (!req)
+ return -1;
- ret = 0;
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_NOT_FOUND,
+ "mount state not found");
+ goto ret;
+ }
+
+ /* First, get the io buffer into which the reply in arg will
+ * be serialized.
+ */
+ /* TODO: use 'xdrproc_t' instead of 'sfunc' to get the xdr-size */
+ iob = iobuf_get(ms->iobpool);
+ if (!iob) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Failed to get iobuf");
+ goto ret;
+ }
+
+ iobuf_to_iovec(iob, &outmsg);
+ /* Use the given serializer to translate the give C structure in arg
+ * to XDR format which will be written into the buffer in outmsg.
+ */
+ msglen = sfunc(outmsg, arg);
+ if (msglen < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ENCODE_MSG_FAIL,
+ "Failed to encode message");
+ goto ret;
+ }
+ outmsg.iov_len = msglen;
+
+ iobref = iobref_new();
+ if (iobref == NULL) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Failed to get iobref");
+ goto ret;
+ }
+
+ ret = iobref_add(iobref, iob);
+ if (ret) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Failed to add iob to iobref");
+ goto ret;
+ }
+
+ /* Then, submit the message for transmission. */
+ ret = rpcsvc_submit_message(req, &outmsg, 1, NULL, 0, iobref);
+ if (ret == -1) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_REP_SUBMIT_FAIL,
+ "Reply submission failed");
+ goto ret;
+ }
+
+ ret = 0;
ret:
- if (NULL != iob)
- iobuf_unref (iob);
- if (NULL != iobref)
- iobref_unref (iobref);
+ if (NULL != iob)
+ iobuf_unref(iob);
+ if (NULL != iobref)
+ iobref_unref(iobref);
- return ret;
+ return ret;
}
/**
* __mountdict_insert -- Insert a mount entry into the mount state
@@ -159,39 +161,38 @@ ret:
* Not for external use.
*/
void
-__mountdict_insert (struct mount3_state *ms, struct mountentry *me)
+__mountdict_insert(struct mount3_state *ms, struct mountentry *me)
{
- char *exname = NULL;
- char *fpath = NULL;
- data_t *medata = NULL;
-
- GF_VALIDATE_OR_GOTO (GF_MNT, ms, out);
- GF_VALIDATE_OR_GOTO (GF_MNT, me, out);
-
- /* We don't want export names with leading slashes */
- exname = me->exname;
- while (exname[0] == '/')
- exname++;
-
- /* Get the fullpath for the export */
- fpath = me->fullpath;
- if (me->has_full_path) {
- while (fpath[0] == '/')
- fpath++;
-
- /* Export names can either be just volumes or paths inside that
- * volume. */
- exname = fpath;
- }
-
- snprintf (me->hashkey, sizeof (me->hashkey), "%s:%s", exname,
- me->hostname);
-
- medata = bin_to_data (me, sizeof (*me));
- dict_set (ms->mountdict, me->hashkey, medata);
- gf_msg_trace (GF_MNT, 0, "Inserted into mountdict: %s", me->hashkey);
+ char *exname = NULL;
+ char *fpath = NULL;
+ data_t *medata = NULL;
+
+ GF_VALIDATE_OR_GOTO(GF_MNT, ms, out);
+ GF_VALIDATE_OR_GOTO(GF_MNT, me, out);
+
+ /* We don't want export names with leading slashes */
+ exname = me->exname;
+ while (exname[0] == '/')
+ exname++;
+
+ /* Get the fullpath for the export */
+ fpath = me->fullpath;
+ if (me->has_full_path) {
+ while (fpath[0] == '/')
+ fpath++;
+
+ /* Export names can either be just volumes or paths inside that
+ * volume. */
+ exname = fpath;
+ }
+
+ snprintf(me->hashkey, sizeof(me->hashkey), "%s:%s", exname, me->hostname);
+
+ medata = bin_to_data(me, sizeof(*me));
+ dict_set(ms->mountdict, me->hashkey, medata);
+ gf_msg_trace(GF_MNT, 0, "Inserted into mountdict: %s", me->hashkey);
out:
- return;
+ return;
}
/**
@@ -203,91 +204,90 @@ out:
* Not for external use.
*/
void
-__mountdict_remove (struct mount3_state *ms, struct mountentry *me)
+__mountdict_remove(struct mount3_state *ms, struct mountentry *me)
{
- dict_del (ms->mountdict, me->hashkey);
+ dict_del(ms->mountdict, me->hashkey);
}
/* Generic error reply function, just pass the err status
* and it will do the rest, including transmission.
*/
int
-mnt3svc_mnt_error_reply (rpcsvc_request_t *req, int mntstat)
+mnt3svc_mnt_error_reply(rpcsvc_request_t *req, int mntstat)
{
- mountres3 res;
+ mountres3 res;
- if (!req)
- return -1;
+ if (!req)
+ return -1;
- res.fhs_status = mntstat;
- mnt3svc_submit_reply (req, (void *)&res,
- (mnt3_serializer)xdr_serialize_mountres3);
+ res.fhs_status = mntstat;
+ mnt3svc_submit_reply(req, (void *)&res,
+ (mnt3_serializer)xdr_serialize_mountres3);
- return 0;
+ return 0;
}
-
mountstat3
-mnt3svc_errno_to_mnterr (int32_t errnum)
+mnt3svc_errno_to_mnterr(int32_t errnum)
{
- mountstat3 stat;
-
- switch (errnum) {
-
- case 0:
- stat = MNT3_OK;
- break;
- case ENOENT:
- stat = MNT3ERR_NOENT;
- break;
- case EPERM:
- stat = MNT3ERR_PERM;
- break;
- case EIO:
- stat = MNT3ERR_IO;
- break;
- case EACCES:
- stat = MNT3ERR_ACCES;
- break;
- case ENOTDIR:
- stat = MNT3ERR_NOTDIR;
- break;
- case EINVAL:
- stat = MNT3ERR_INVAL;
- break;
- case ENOSYS:
- stat = MNT3ERR_NOTSUPP;
- break;
- case ENOMEM:
- stat = MNT3ERR_SERVERFAULT;
- break;
- default:
- stat = MNT3ERR_SERVERFAULT;
- break;
- }
+ mountstat3 stat;
+
+ switch (errnum) {
+ case 0:
+ stat = MNT3_OK;
+ break;
+ case ENOENT:
+ stat = MNT3ERR_NOENT;
+ break;
+ case EPERM:
+ stat = MNT3ERR_PERM;
+ break;
+ case EIO:
+ stat = MNT3ERR_IO;
+ break;
+ case EACCES:
+ stat = MNT3ERR_ACCES;
+ break;
+ case ENOTDIR:
+ stat = MNT3ERR_NOTDIR;
+ break;
+ case EINVAL:
+ stat = MNT3ERR_INVAL;
+ break;
+ case ENOSYS:
+ stat = MNT3ERR_NOTSUPP;
+ break;
+ case ENOMEM:
+ stat = MNT3ERR_SERVERFAULT;
+ break;
+ default:
+ stat = MNT3ERR_SERVERFAULT;
+ break;
+ }
- return stat;
+ return stat;
}
-
mountres3
-mnt3svc_set_mountres3 (mountstat3 stat, struct nfs3_fh *fh, int *authflavor,
- u_int aflen)
+mnt3svc_set_mountres3(mountstat3 stat, struct nfs3_fh *fh, int *authflavor,
+ u_int aflen)
{
- mountres3 res = {0, };
- uint32_t fhlen = 0;
+ mountres3 res = {
+ 0,
+ };
+ uint32_t fhlen = 0;
- res.fhs_status = stat;
+ res.fhs_status = stat;
- if (fh)
- fhlen = nfs3_fh_compute_size ();
+ if (fh)
+ fhlen = nfs3_fh_compute_size();
- res.mountres3_u.mountinfo.fhandle.fhandle3_len = fhlen;
- res.mountres3_u.mountinfo.fhandle.fhandle3_val = (char *)fh;
- res.mountres3_u.mountinfo.auth_flavors.auth_flavors_val = authflavor;
- res.mountres3_u.mountinfo.auth_flavors.auth_flavors_len = aflen;
+ res.mountres3_u.mountinfo.fhandle.fhandle3_len = fhlen;
+ res.mountres3_u.mountinfo.fhandle.fhandle3_val = (char *)fh;
+ res.mountres3_u.mountinfo.auth_flavors.auth_flavors_val = authflavor;
+ res.mountres3_u.mountinfo.auth_flavors.auth_flavors_len = aflen;
- return res;
+ return res;
}
/* Read the rmtab from the store_handle and append (or not) the entries to the
@@ -296,81 +296,82 @@ mnt3svc_set_mountres3 (mountstat3 stat, struct nfs3_fh *fh, int *authflavor,
* Requires the store_handle to be locked.
*/
static int
-__mount_read_rmtab (gf_store_handle_t *sh, struct list_head *mountlist,
- gf_boolean_t append)
+__mount_read_rmtab(gf_store_handle_t *sh, struct list_head *mountlist,
+ gf_boolean_t append)
{
- int ret = 0;
- unsigned int idx = 0;
- struct mountentry *me = NULL, *tmp = NULL;
- /* me->hostname is a char[MNTPATHLEN] */
- char key[MNTPATHLEN + 11];
-
- GF_ASSERT (sh && mountlist);
-
- if (!gf_store_locked_local (sh)) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_READ_LOCKED,
- "Not reading unlocked %s", sh->path);
- return -1;
- }
+ int ret = 0;
+ unsigned int idx = 0;
+ struct mountentry *me = NULL, *tmp = NULL;
+ /* me->hostname is a char[MNTPATHLEN] */
+ char key[MNTPATHLEN + 11];
- if (!append) {
- list_for_each_entry_safe (me, tmp, mountlist, mlist) {
- list_del (&me->mlist);
- GF_FREE (me);
- }
- me = NULL;
- }
+ GF_ASSERT(sh && mountlist);
- for (;;) {
- char *value = NULL;
-
- if (me && append) {
- /* do not add duplicates */
- list_for_each_entry (tmp, mountlist, mlist) {
- if (!strcmp(tmp->hostname, me->hostname) &&
- !strcmp(tmp->exname, me->exname)) {
- GF_FREE (me);
- goto dont_add;
- }
- }
- list_add_tail (&me->mlist, mountlist);
- } else if (me) {
- list_add_tail (&me->mlist, mountlist);
- }
+ if (!gf_store_locked_local(sh)) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_READ_LOCKED,
+ "Not reading unlocked %s", sh->path);
+ return -1;
+ }
-dont_add:
- me = GF_CALLOC (1, sizeof (*me), gf_nfs_mt_mountentry);
- if (!me) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Out of memory");
- ret = -1;
- goto out;
+ if (!append) {
+ list_for_each_entry_safe(me, tmp, mountlist, mlist)
+ {
+ list_del(&me->mlist);
+ GF_FREE(me);
+ }
+ me = NULL;
+ }
+
+ for (;;) {
+ char *value = NULL;
+
+ if (me && append) {
+ /* do not add duplicates */
+ list_for_each_entry(tmp, mountlist, mlist)
+ {
+ if (!strcmp(tmp->hostname, me->hostname) &&
+ !strcmp(tmp->exname, me->exname)) {
+ GF_FREE(me);
+ goto dont_add;
}
-
- INIT_LIST_HEAD (&me->mlist);
-
- snprintf (key, 9 + MNTPATHLEN, "hostname-%d", idx);
- ret = gf_store_retrieve_value (sh, key, &value);
- if (ret)
- break;
- snprintf (me->hostname, MNTPATHLEN, "%s", value);
- GF_FREE (value);
-
- snprintf (key, 11 + MNTPATHLEN, "mountpoint-%d", idx);
- ret = gf_store_retrieve_value (sh, key, &value);
- if (ret)
- break;
- snprintf (me->exname, MNTPATHLEN, "%s", value);
- GF_FREE (value);
-
- idx++;
- gf_msg_trace (GF_MNT, 0, "Read entries %s:%s",
- me->hostname, me->exname);
- }
- gf_msg_debug (GF_MNT, 0, "Read %d entries from '%s'", idx, sh->path);
- GF_FREE (me);
+ }
+ list_add_tail(&me->mlist, mountlist);
+ } else if (me) {
+ list_add_tail(&me->mlist, mountlist);
+ }
+
+ dont_add:
+ me = GF_CALLOC(1, sizeof(*me), gf_nfs_mt_mountentry);
+ if (!me) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Out of memory");
+ ret = -1;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&me->mlist);
+
+ snprintf(key, 9 + MNTPATHLEN, "hostname-%d", idx);
+ ret = gf_store_retrieve_value(sh, key, &value);
+ if (ret)
+ break;
+ snprintf(me->hostname, MNTPATHLEN, "%s", value);
+ GF_FREE(value);
+
+ snprintf(key, 11 + MNTPATHLEN, "mountpoint-%d", idx);
+ ret = gf_store_retrieve_value(sh, key, &value);
+ if (ret)
+ break;
+ snprintf(me->exname, MNTPATHLEN, "%s", value);
+ GF_FREE(value);
+
+ idx++;
+ gf_msg_trace(GF_MNT, 0, "Read entries %s:%s", me->hostname, me->exname);
+ }
+ gf_msg_debug(GF_MNT, 0, "Read %d entries from '%s'", idx, sh->path);
+ GF_FREE(me);
out:
- return ret;
+ return ret;
}
/* Overwrite the contents of the rwtab with the in-memory client list.
@@ -379,98 +380,97 @@ out:
static void
__mount_rewrite_rmtab(struct mount3_state *ms, gf_store_handle_t *sh)
{
- struct mountentry *me = NULL;
- char key[16];
- int fd, ret;
- unsigned int idx = 0;
-
- if (!gf_store_locked_local (sh)) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_MODIFY_LOCKED,
- "Not modifying unlocked %s", sh->path);
- return;
- }
+ struct mountentry *me = NULL;
+ char key[16];
+ int fd, ret;
+ unsigned int idx = 0;
+
+ if (!gf_store_locked_local(sh)) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_MODIFY_LOCKED,
+ "Not modifying unlocked %s", sh->path);
+ return;
+ }
- fd = gf_store_mkstemp (sh);
- if (fd == -1) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
- "Failed to open %s", sh->path);
- return;
- }
+ fd = gf_store_mkstemp(sh);
+ if (fd == -1) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
+ "Failed to open %s", sh->path);
+ return;
+ }
- list_for_each_entry (me, &ms->mountlist, mlist) {
- snprintf (key, 16, "hostname-%d", idx);
- ret = gf_store_save_value (fd, key, me->hostname);
- if (ret)
- goto fail;
+ list_for_each_entry(me, &ms->mountlist, mlist)
+ {
+ snprintf(key, 16, "hostname-%d", idx);
+ ret = gf_store_save_value(fd, key, me->hostname);
+ if (ret)
+ goto fail;
- snprintf (key, 16, "mountpoint-%d", idx);
- ret = gf_store_save_value (fd, key, me->exname);
- if (ret)
- goto fail;
+ snprintf(key, 16, "mountpoint-%d", idx);
+ ret = gf_store_save_value(fd, key, me->exname);
+ if (ret)
+ goto fail;
- idx++;
- }
+ idx++;
+ }
- gf_msg_debug (GF_MNT, 0, "Updated rmtab with %d entries", idx);
+ gf_msg_debug(GF_MNT, 0, "Updated rmtab with %d entries", idx);
- if (gf_store_rename_tmppath (sh))
- gf_msg (GF_MNT, GF_LOG_ERROR, errno,
- NFS_MSG_RWTAB_OVERWRITE_FAIL,
- "Failed to overwrite rwtab %s", sh->path);
+ if (gf_store_rename_tmppath(sh))
+ gf_msg(GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_RWTAB_OVERWRITE_FAIL,
+ "Failed to overwrite rwtab %s", sh->path);
- return;
+ return;
fail:
- gf_msg (GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_UPDATE_FAIL,
- "Failed to update %s", sh->path);
- gf_store_unlink_tmppath (sh);
+ gf_msg(GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_UPDATE_FAIL,
+ "Failed to update %s", sh->path);
+ gf_store_unlink_tmppath(sh);
}
static gf_boolean_t
-mount_open_rmtab (const char *rmtab, gf_store_handle_t **sh)
+mount_open_rmtab(const char *rmtab, gf_store_handle_t **sh)
{
- int ret = -1;
+ int ret = -1;
- /* updating the rmtab is disabled, use in-memory only */
- if (!rmtab || rmtab[0] == '\0')
- return _gf_false;
+ /* updating the rmtab is disabled, use in-memory only */
+ if (!rmtab || rmtab[0] == '\0')
+ return _gf_false;
- ret = gf_store_handle_new (rmtab, sh);
- if (ret) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Failed to open '%s'", rmtab);
- return _gf_false;
- }
+ ret = gf_store_handle_new(rmtab, sh);
+ if (ret) {
+ gf_log(GF_MNT, GF_LOG_WARNING, "Failed to open '%s'", rmtab);
+ return _gf_false;
+ }
- return _gf_true;
+ return _gf_true;
}
-
/* Read the rmtab into a clean ms->mountlist.
*/
static void
-mount_read_rmtab (struct mount3_state *ms)
+mount_read_rmtab(struct mount3_state *ms)
{
- gf_store_handle_t *sh = NULL;
- struct nfs_state *nfs = NULL;
- gf_boolean_t read_rmtab = _gf_false;
+ gf_store_handle_t *sh = NULL;
+ struct nfs_state *nfs = NULL;
+ gf_boolean_t read_rmtab = _gf_false;
- nfs = (struct nfs_state *)ms->nfsx->private;
+ nfs = (struct nfs_state *)ms->nfsx->private;
- read_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
- if (!read_rmtab)
- return;
+ read_rmtab = mount_open_rmtab(nfs->rmtab, &sh);
+ if (!read_rmtab)
+ return;
- if (gf_store_lock (sh)) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_LOCK_FAIL,
- "Failed to lock '%s'", nfs->rmtab);
- goto out;
- }
+ if (gf_store_lock(sh)) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_LOCK_FAIL,
+ "Failed to lock '%s'", nfs->rmtab);
+ goto out;
+ }
- __mount_read_rmtab (sh, &ms->mountlist, _gf_false);
- gf_store_unlock (sh);
+ __mount_read_rmtab(sh, &ms->mountlist, _gf_false);
+ gf_store_unlock(sh);
out:
- gf_store_handle_destroy (sh);
+ gf_store_handle_destroy(sh);
}
/* Write the ms->mountlist to the rmtab.
@@ -491,77 +491,75 @@ out:
* 9. releases the store_handle lock of the old rmtab
*/
void
-mount_rewrite_rmtab (struct mount3_state *ms, char *new_rmtab)
+mount_rewrite_rmtab(struct mount3_state *ms, char *new_rmtab)
{
- gf_store_handle_t *sh = NULL, *nsh = NULL;
- struct nfs_state *nfs = NULL;
- int ret;
- char *rmtab = NULL;
- gf_boolean_t got_old_rmtab = _gf_false;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
-
- got_old_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
- if (!got_old_rmtab && !new_rmtab)
- return;
-
- if (got_old_rmtab && gf_store_lock (sh)) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_REWRITE_ERROR,
- "Not rewriting '%s'", nfs->rmtab);
- goto free_sh;
- }
+ gf_store_handle_t *sh = NULL, *nsh = NULL;
+ struct nfs_state *nfs = NULL;
+ int ret;
+ char *rmtab = NULL;
+ gf_boolean_t got_old_rmtab = _gf_false;
- if (new_rmtab) {
- ret = gf_store_handle_new (new_rmtab, &nsh);
- if (ret) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_OPEN_FAIL,
- "Failed to open '%s'", new_rmtab);
- goto unlock_sh;
- }
+ nfs = (struct nfs_state *)ms->nfsx->private;
- if (gf_store_lock (nsh)) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0,
- NFS_MSG_REWRITE_ERROR,
- "Not rewriting '%s'", new_rmtab);
- goto free_nsh;
- }
+ got_old_rmtab = mount_open_rmtab(nfs->rmtab, &sh);
+ if (!got_old_rmtab && !new_rmtab)
+ return;
+
+ if (got_old_rmtab && gf_store_lock(sh)) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_REWRITE_ERROR,
+ "Not rewriting '%s'", nfs->rmtab);
+ goto free_sh;
+ }
+
+ if (new_rmtab) {
+ ret = gf_store_handle_new(new_rmtab, &nsh);
+ if (ret) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_OPEN_FAIL,
+ "Failed to open '%s'", new_rmtab);
+ goto unlock_sh;
}
- /* always read the currently used rmtab */
- if (got_old_rmtab)
- __mount_read_rmtab (sh, &ms->mountlist, _gf_true);
-
- if (new_rmtab) {
- /* read the new rmtab and write changes to the new location */
- __mount_read_rmtab (nsh, &ms->mountlist, _gf_true);
- __mount_rewrite_rmtab (ms, nsh);
-
- /* replace the nfs->rmtab reference to the new rmtab */
- rmtab = gf_strdup(new_rmtab);
- if (rmtab == NULL) {
- gf_msg (GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_NO_MEMORY,
- "Out of memory, keeping %s as rmtab",
- nfs->rmtab);
- } else {
- GF_FREE (nfs->rmtab);
- nfs->rmtab = rmtab;
- }
+ if (gf_store_lock(nsh)) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_REWRITE_ERROR,
+ "Not rewriting '%s'", new_rmtab);
+ goto free_nsh;
+ }
+ }
+
+ /* always read the currently used rmtab */
+ if (got_old_rmtab)
+ __mount_read_rmtab(sh, &ms->mountlist, _gf_true);
+
+ if (new_rmtab) {
+ /* read the new rmtab and write changes to the new location */
+ __mount_read_rmtab(nsh, &ms->mountlist, _gf_true);
+ __mount_rewrite_rmtab(ms, nsh);
- gf_store_unlock (nsh);
+ /* replace the nfs->rmtab reference to the new rmtab */
+ rmtab = gf_strdup(new_rmtab);
+ if (rmtab == NULL) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_NO_MEMORY,
+ "Out of memory, keeping %s as rmtab", nfs->rmtab);
} else {
- /* rewrite the current (unchanged location) rmtab */
- __mount_rewrite_rmtab (ms, sh);
+ GF_FREE(nfs->rmtab);
+ nfs->rmtab = rmtab;
}
+ gf_store_unlock(nsh);
+ } else {
+ /* rewrite the current (unchanged location) rmtab */
+ __mount_rewrite_rmtab(ms, sh);
+ }
+
free_nsh:
- if (new_rmtab)
- gf_store_handle_destroy (nsh);
+ if (new_rmtab)
+ gf_store_handle_destroy(nsh);
unlock_sh:
- if (got_old_rmtab)
- gf_store_unlock (sh);
+ if (got_old_rmtab)
+ gf_store_unlock(sh);
free_sh:
- if (got_old_rmtab)
- gf_store_handle_destroy (sh);
+ if (got_old_rmtab)
+ gf_store_handle_destroy(sh);
}
/* Add a new NFS-client to the ms->mountlist and update the rmtab if we can.
@@ -576,374 +574,375 @@ free_sh:
* common issue for all(?) NFS-servers.
*/
int
-mnt3svc_update_mountlist (struct mount3_state *ms, rpcsvc_request_t *req,
- const char *expname, const char *fullpath)
+mnt3svc_update_mountlist(struct mount3_state *ms, rpcsvc_request_t *req,
+ const char *expname, const char *fullpath)
{
- struct mountentry *me = NULL;
- struct mountentry *cur = NULL;
- int ret = -1;
- char *colon = NULL;
- struct nfs_state *nfs = NULL;
- gf_store_handle_t *sh = NULL;
- gf_boolean_t update_rmtab = _gf_false;
-
- if ((!ms) || (!req) || (!expname))
- return -1;
-
- me = (struct mountentry *)GF_CALLOC (1, sizeof (*me),
- gf_nfs_mt_mountentry);
- if (!me)
- return -1;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
-
- update_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
+ struct mountentry *me = NULL;
+ struct mountentry *cur = NULL;
+ int ret = -1;
+ char *colon = NULL;
+ struct nfs_state *nfs = NULL;
+ gf_store_handle_t *sh = NULL;
+ gf_boolean_t update_rmtab = _gf_false;
+
+ if ((!ms) || (!req) || (!expname))
+ return -1;
- snprintf (me->exname, MNTPATHLEN, "%s", expname);
- /* Sometimes we don't care about the full path
- * so a NULL value for fullpath is valid.
- */
- if (fullpath) {
- if (strlen (fullpath) < MNTPATHLEN) {
- strcpy (me->fullpath, fullpath);
- me->has_full_path = _gf_true;
- }
- }
+ me = (struct mountentry *)GF_CALLOC(1, sizeof(*me), gf_nfs_mt_mountentry);
+ if (!me)
+ return -1;
+ nfs = (struct nfs_state *)ms->nfsx->private;
- INIT_LIST_HEAD (&me->mlist);
- /* Must get the IP or hostname of the client so we
- * can map it into the mount entry.
- */
- ret = rpcsvc_transport_peername (req->trans, me->hostname, MNTPATHLEN);
- if (ret == -1)
- goto free_err;
+ update_rmtab = mount_open_rmtab(nfs->rmtab, &sh);
- colon = strrchr (me->hostname, ':');
- if (colon) {
- *colon = '\0';
+ snprintf(me->exname, MNTPATHLEN, "%s", expname);
+ /* Sometimes we don't care about the full path
+ * so a NULL value for fullpath is valid.
+ */
+ if (fullpath) {
+ if (strlen(fullpath) < MNTPATHLEN) {
+ strcpy(me->fullpath, fullpath);
+ me->has_full_path = _gf_true;
}
- LOCK (&ms->mountlock);
- {
- /* in case locking fails, we just don't write the rmtab */
- if (update_rmtab && gf_store_lock (sh)) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_LOCK_FAIL,
- "Failed to lock '%s', changes will not be "
- "written", nfs->rmtab);
- } else if (update_rmtab) {
- __mount_read_rmtab (sh, &ms->mountlist, _gf_false);
- }
+ }
- /* do not add duplicates */
- list_for_each_entry (cur, &ms->mountlist, mlist) {
- if (!strcmp(cur->hostname, me->hostname) &&
- !strcmp(cur->exname, me->exname)) {
- GF_FREE (me);
- goto dont_add;
- }
- }
- list_add_tail (&me->mlist, &ms->mountlist);
- __mountdict_insert (ms, me);
+ INIT_LIST_HEAD(&me->mlist);
+ /* Must get the IP or hostname of the client so we
+ * can map it into the mount entry.
+ */
+ ret = rpcsvc_transport_peername(req->trans, me->hostname, MNTPATHLEN);
+ if (ret == -1)
+ goto free_err;
- /* only write the rmtab in case it was locked */
- if (update_rmtab && gf_store_locked_local (sh))
- __mount_rewrite_rmtab (ms, sh);
- }
+ colon = strrchr(me->hostname, ':');
+ if (colon) {
+ *colon = '\0';
+ }
+ LOCK(&ms->mountlock);
+ {
+ /* in case locking fails, we just don't write the rmtab */
+ if (update_rmtab && gf_store_lock(sh)) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_LOCK_FAIL,
+ "Failed to lock '%s', changes will not be "
+ "written",
+ nfs->rmtab);
+ } else if (update_rmtab) {
+ __mount_read_rmtab(sh, &ms->mountlist, _gf_false);
+ }
+
+ /* do not add duplicates */
+ list_for_each_entry(cur, &ms->mountlist, mlist)
+ {
+ if (!strcmp(cur->hostname, me->hostname) &&
+ !strcmp(cur->exname, me->exname)) {
+ GF_FREE(me);
+ goto dont_add;
+ }
+ }
+ list_add_tail(&me->mlist, &ms->mountlist);
+ __mountdict_insert(ms, me);
+
+ /* only write the rmtab in case it was locked */
+ if (update_rmtab && gf_store_locked_local(sh))
+ __mount_rewrite_rmtab(ms, sh);
+ }
dont_add:
- if (update_rmtab && gf_store_locked_local (sh))
- gf_store_unlock (sh);
+ if (update_rmtab && gf_store_locked_local(sh))
+ gf_store_unlock(sh);
- UNLOCK (&ms->mountlock);
+ UNLOCK(&ms->mountlock);
free_err:
- if (update_rmtab)
- gf_store_handle_destroy (sh);
+ if (update_rmtab)
+ gf_store_handle_destroy(sh);
- if (ret == -1)
- GF_FREE (me);
+ if (ret == -1)
+ GF_FREE(me);
- return ret;
+ return ret;
}
-
int
-__mnt3_get_volume_id (struct mount3_state *ms, xlator_t *mntxl,
- uuid_t volumeid)
+__mnt3_get_volume_id(struct mount3_state *ms, xlator_t *mntxl, uuid_t volumeid)
{
- int ret = -1;
- struct mnt3_export *exp = NULL;
-
- if ((!ms) || (!mntxl))
- return ret;
-
- LOCK (&ms->mountlock);
- list_for_each_entry (exp, &ms->exportlist, explist) {
- if (exp->vol == mntxl) {
- gf_uuid_copy (volumeid, exp->volumeid);
- ret = 0;
- goto out;
- }
+ int ret = -1;
+ struct mnt3_export *exp = NULL;
+
+ if ((!ms) || (!mntxl))
+ return ret;
+
+ LOCK(&ms->mountlock);
+ list_for_each_entry(exp, &ms->exportlist, explist)
+ {
+ if (exp->vol == mntxl) {
+ gf_uuid_copy(volumeid, exp->volumeid);
+ ret = 0;
+ goto out;
}
+ }
out:
- UNLOCK (&ms->mountlock);
- return ret;
+ UNLOCK(&ms->mountlock);
+ return ret;
}
int
-__mnt3_build_mountid_from_path (const char *path, uuid_t mountid)
+__mnt3_build_mountid_from_path(const char *path, uuid_t mountid)
{
- uint32_t hashed_path = 0;
- int ret = -1;
+ uint32_t hashed_path = 0;
+ int ret = -1;
- if (!path)
- goto out;
+ if (!path)
+ goto out;
- while (strlen (path) > 0 && path[0] == '/')
- path++;
+ while (strlen(path) > 0 && path[0] == '/')
+ path++;
- /* Clear the mountid */
- gf_uuid_clear (mountid);
+ /* Clear the mountid */
+ gf_uuid_clear(mountid);
- hashed_path = SuperFastHash (path, strlen (path));
- if (hashed_path == 1) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_HASH_PATH_FAIL,
- "failed to hash path: %s", path);
- goto out;
- }
+ hashed_path = SuperFastHash(path, strlen(path));
+ if (hashed_path == 1) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_HASH_PATH_FAIL,
+ "failed to hash path: %s", path);
+ goto out;
+ }
- memcpy (mountid, &hashed_path, sizeof (hashed_path));
- ret = 0;
+ memcpy(mountid, &hashed_path, sizeof(hashed_path));
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-__mnt3_get_mount_id (xlator_t *mntxl, uuid_t mountid)
+__mnt3_get_mount_id(xlator_t *mntxl, uuid_t mountid)
{
- int ret = -1;
- uint32_t hashed_path = 0;
+ int ret = -1;
+ uint32_t hashed_path = 0;
+ /* first clear the mountid */
+ gf_uuid_clear(mountid);
- /* first clear the mountid */
- gf_uuid_clear (mountid);
+ hashed_path = SuperFastHash(mntxl->name, strlen(mntxl->name));
+ if (hashed_path == 1) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_HASH_XLATOR_FAIL,
+ "failed to hash xlator name: %s", mntxl->name);
+ goto out;
+ }
- hashed_path = SuperFastHash (mntxl->name, strlen (mntxl->name));
- if (hashed_path == 1) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_HASH_XLATOR_FAIL,
- "failed to hash xlator name: %s", mntxl->name);
- goto out;
- }
-
- memcpy (mountid, &hashed_path, sizeof (hashed_path));
- ret = 0;
+ memcpy(mountid, &hashed_path, sizeof(hashed_path));
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
int32_t
-mnt3svc_lookup_mount_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
+mnt3svc_lookup_mount_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
{
- mountres3 res = {0, };
- rpcsvc_request_t *req = NULL;
- struct nfs3_fh fh = {{0}, };
- struct mount3_state *ms = NULL;
- mountstat3 status = 0;
- int autharr[10];
- int autharrlen = 0;
- rpcsvc_t *svc = NULL;
- xlator_t *mntxl = NULL;
- uuid_t volumeid = {0, };
- char *path = NULL;
- uuid_t mountid = {1, };
- char fhstr[1536];
- int alloclen = 0;
-
- req = (rpcsvc_request_t *)frame->local;
-
- if (!req)
- return -1;
-
- mntxl = (xlator_t *)cookie;
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_NOT_FOUND,
- "mount state not found");
- op_ret = -1;
- op_errno = EINVAL;
- }
-
- if (op_ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, op_errno,
- NFS_MSG_LOOKUP_MNT_ERROR, "error=%s",
- strerror (op_errno));
- status = mnt3svc_errno_to_mnterr (op_errno);
- }
- if (status != MNT3_OK)
- goto xmit_res;
-
- alloclen = strlen(mntxl->name) + 2;
- path = GF_MALLOC (alloclen, gf_nfs_mt_char);
- if (!path) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY,
- "Memory allocation failed.");
- goto xmit_res;
- }
-
- snprintf (path, alloclen, "/%s", mntxl->name);
- mnt3svc_update_mountlist (ms, req, path, NULL);
- GF_FREE (path);
- if (gf_nfs_dvm_off (nfs_state (ms->nfsx))) {
- fh = nfs3_fh_build_indexed_root_fh (ms->nfsx->children, mntxl);
- goto xmit_res;
- }
+ mountres3 res = {
+ 0,
+ };
+ rpcsvc_request_t *req = NULL;
+ struct nfs3_fh fh = {
+ {0},
+ };
+ struct mount3_state *ms = NULL;
+ mountstat3 status = 0;
+ int autharr[10];
+ int autharrlen = 0;
+ rpcsvc_t *svc = NULL;
+ xlator_t *mntxl = NULL;
+ uuid_t volumeid = {
+ 0,
+ };
+ char *path = NULL;
+ uuid_t mountid = {
+ 1,
+ };
+ char fhstr[1536];
+ int alloclen = 0;
+
+ req = (rpcsvc_request_t *)frame->local;
+
+ if (!req)
+ return -1;
- __mnt3_get_mount_id (mntxl, mountid);
- __mnt3_get_volume_id (ms, mntxl, volumeid);
- fh = nfs3_fh_build_uuid_root_fh (volumeid, mountid);
+ mntxl = (xlator_t *)cookie;
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_NOT_FOUND,
+ "mount state not found");
+ op_ret = -1;
+ op_errno = EINVAL;
+ }
+
+ if (op_ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, op_errno, NFS_MSG_LOOKUP_MNT_ERROR,
+ "error=%s", strerror(op_errno));
+ status = mnt3svc_errno_to_mnterr(op_errno);
+ }
+ if (status != MNT3_OK)
+ goto xmit_res;
+
+ alloclen = strlen(mntxl->name) + 2;
+ path = GF_MALLOC(alloclen, gf_nfs_mt_char);
+ if (!path) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed.");
+ goto xmit_res;
+ }
+
+ snprintf(path, alloclen, "/%s", mntxl->name);
+ mnt3svc_update_mountlist(ms, req, path, NULL);
+ GF_FREE(path);
+ if (gf_nfs_dvm_off(nfs_state(ms->nfsx))) {
+ fh = nfs3_fh_build_indexed_root_fh(ms->nfsx->children, mntxl);
+ goto xmit_res;
+ }
+
+ __mnt3_get_mount_id(mntxl, mountid);
+ __mnt3_get_volume_id(ms, mntxl, volumeid);
+ fh = nfs3_fh_build_uuid_root_fh(volumeid, mountid);
xmit_res:
- nfs3_fh_to_str (&fh, fhstr, sizeof (fhstr));
- gf_msg_debug (GF_MNT, 0, "MNT reply: fh %s, status: %d", fhstr,
- status);
- if (op_ret == 0) {
- svc = rpcsvc_request_service (req);
- autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr,
- 10);
- }
-
- res = mnt3svc_set_mountres3 (status, &fh, autharr, autharrlen);
- mnt3svc_submit_reply (req, (void *)&res,
- (mnt3_serializer)xdr_serialize_mountres3);
-
- return 0;
+ nfs3_fh_to_str(&fh, fhstr, sizeof(fhstr));
+ gf_msg_debug(GF_MNT, 0, "MNT reply: fh %s, status: %d", fhstr, status);
+ if (op_ret == 0) {
+ svc = rpcsvc_request_service(req);
+ autharrlen = rpcsvc_auth_array(svc, mntxl->name, autharr, 10);
+ }
+
+ res = mnt3svc_set_mountres3(status, &fh, autharr, autharrlen);
+ mnt3svc_submit_reply(req, (void *)&res,
+ (mnt3_serializer)xdr_serialize_mountres3);
+
+ return 0;
}
-
int
-mnt3_match_dirpath_export (const char *expname, const char *dirpath,
- gf_boolean_t export_parsing_match)
+mnt3_match_dirpath_export(const char *expname, const char *dirpath,
+ gf_boolean_t export_parsing_match)
{
- int ret = 0;
- size_t dlen;
- char *fullpath = NULL;
- char *second_slash = NULL;
- char *dirdup = NULL;
+ int ret = 0;
+ size_t dlen;
+ char *fullpath = NULL;
+ char *second_slash = NULL;
+ char *dirdup = NULL;
- if ((!expname) || (!dirpath))
- return 0;
+ if ((!expname) || (!dirpath))
+ return 0;
- dirdup = strdupa (dirpath);
+ dirdup = strdupa(dirpath);
- /* Some clients send a dirpath for mount that includes the slash at the
- * end. String compare for searching the export will fail because our
- * exports list does not include that slash. Remove the slash to
- * compare.
- */
- dlen = strlen (dirdup);
- if (dlen && dirdup[dlen - 1] == '/')
- dirdup[dlen - 1] = '\0';
+ /* Some clients send a dirpath for mount that includes the slash at the
+ * end. String compare for searching the export will fail because our
+ * exports list does not include that slash. Remove the slash to
+ * compare.
+ */
+ dlen = strlen(dirdup);
+ if (dlen && dirdup[dlen - 1] == '/')
+ dirdup[dlen - 1] = '\0';
- /* Here we try to match fullpaths with export names */
- fullpath = dirdup;
+ /* Here we try to match fullpaths with export names */
+ fullpath = dirdup;
- if (export_parsing_match) {
- if (dirdup[0] == '/')
- fullpath = dirdup + 1;
+ if (export_parsing_match) {
+ if (dirdup[0] == '/')
+ fullpath = dirdup + 1;
- second_slash = strchr (fullpath, '/');
- if (second_slash)
- *second_slash = '\0';
- }
+ second_slash = strchr(fullpath, '/');
+ if (second_slash)
+ *second_slash = '\0';
+ }
- /* The export name begins with a slash so move it forward by one
- * to ignore the slash when we want to compare the fullpath and
- * export.
- */
- if (fullpath[0] != '/')
- expname++;
+ /* The export name begins with a slash so move it forward by one
+ * to ignore the slash when we want to compare the fullpath and
+ * export.
+ */
+ if (fullpath[0] != '/')
+ expname++;
- if (strcmp (expname, fullpath) == 0)
- ret = 1;
+ if (strcmp(expname, fullpath) == 0)
+ ret = 1;
- return ret;
+ return ret;
}
-
int
-mnt3svc_mount_inode (rpcsvc_request_t *req, struct mount3_state *ms,
- xlator_t * xl, inode_t *exportinode)
+mnt3svc_mount_inode(rpcsvc_request_t *req, struct mount3_state *ms,
+ xlator_t *xl, inode_t *exportinode)
{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- loc_t exportloc = {0, };
-
- if ((!req) || (!xl) || (!ms) || (!exportinode))
- return ret;
-
- ret = nfs_inode_loc_fill (exportinode, &exportloc, NFS_RESOLVE_EXIST);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_INODE_LOC_FILL_ERROR,
- "Loc fill failed for export inode"
- ": gfid %s, volume: %s",
- uuid_utoa (exportinode->gfid), xl->name);
- goto err;
- }
-
- /* To service the mount request, all we need to do
- * is to send a lookup fop that returns the stat
- * for the root of the child volume. This is
- * used to build the root fh sent to the client.
- */
- nfs_request_user_init (&nfu, req);
- ret = nfs_lookup (ms->nfsx, xl, &nfu, &exportloc,
- mnt3svc_lookup_mount_cbk, (void *)req);
+ int ret = -EFAULT;
+ nfs_user_t nfu = {
+ 0,
+ };
+ loc_t exportloc = {
+ 0,
+ };
+
+ if ((!req) || (!xl) || (!ms) || (!exportinode))
+ return ret;
- nfs_loc_wipe (&exportloc);
+ ret = nfs_inode_loc_fill(exportinode, &exportloc, NFS_RESOLVE_EXIST);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_INODE_LOC_FILL_ERROR,
+ "Loc fill failed for export inode"
+ ": gfid %s, volume: %s",
+ uuid_utoa(exportinode->gfid), xl->name);
+ goto err;
+ }
+
+ /* To service the mount request, all we need to do
+ * is to send a lookup fop that returns the stat
+ * for the root of the child volume. This is
+ * used to build the root fh sent to the client.
+ */
+ nfs_request_user_init(&nfu, req);
+ ret = nfs_lookup(ms->nfsx, xl, &nfu, &exportloc, mnt3svc_lookup_mount_cbk,
+ (void *)req);
+
+ nfs_loc_wipe(&exportloc);
err:
- return ret;
+ return ret;
}
-
/* For a volume mount request, we just have to create loc on the root inode,
* and send a lookup. In the lookup callback the mount reply is send along with
* the file handle.
*/
int
-mnt3svc_volume_mount (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp)
+mnt3svc_volume_mount(rpcsvc_request_t *req, struct mount3_state *ms,
+ struct mnt3_export *exp)
{
- inode_t *exportinode = NULL;
- int ret = -EFAULT;
- uuid_t rootgfid = {0, };
-
- if ((!req) || (!exp) || (!ms))
- return ret;
-
- rootgfid[15] = 1;
- exportinode = inode_find (exp->vol->itable, rootgfid);
- if (!exportinode) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOENT,
- NFS_MSG_GET_ROOT_INODE_FAIL,
- "Failed to get root inode");
- ret = -ENOENT;
- goto err;
- }
+ inode_t *exportinode = NULL;
+ int ret = -EFAULT;
+ uuid_t rootgfid = {
+ 0,
+ };
+
+ if ((!req) || (!exp) || (!ms))
+ return ret;
+
+ rootgfid[15] = 1;
+ exportinode = inode_find(exp->vol->itable, rootgfid);
+ if (!exportinode) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOENT, NFS_MSG_GET_ROOT_INODE_FAIL,
+ "Failed to get root inode");
+ ret = -ENOENT;
+ goto err;
+ }
- ret = mnt3svc_mount_inode (req, ms, exp->vol, exportinode);
- inode_unref (exportinode);
+ ret = mnt3svc_mount_inode(req, ms, exp->vol, exportinode);
+ inode_unref(exportinode);
err:
- return ret;
+ return ret;
}
-
/* The catch with directory exports is that the first component of the export
* name will be the name of the volume.
* Any lookup that needs to be performed to build the directory's file handle
@@ -951,280 +950,280 @@ err:
* we need to strip out the volume name first.
*/
char *
-mnt3_get_volume_subdir (char *dirpath, char **volname)
+mnt3_get_volume_subdir(char *dirpath, char **volname)
{
- /* subdir points to the first / after the volume name while dirpath
- * points to the first char of the volume name.
- */
- char *subdir = NULL;
- int volname_len = 0;
- static char *root = "/";
-
- /* all callers are expected to pass a valid *dirpath */
- GF_ASSERT (dirpath);
-
- if (dirpath[0] == '/')
- dirpath++;
-
- subdir = index (dirpath, (int)'/');
- if (!subdir) {
- subdir = root;
- volname_len = strlen (dirpath);
- } else {
- volname_len = subdir - dirpath;
- }
-
- if (!volname)
- goto out;
-
- if (!*volname)
- goto out;
-
- strncpy (*volname, dirpath, volname_len);
- *(*volname + volname_len) = '\0';
+ /* subdir points to the first / after the volume name while dirpath
+ * points to the first char of the volume name.
+ */
+ char *subdir = NULL;
+ int volname_len = 0;
+ static char *root = "/";
+
+ /* all callers are expected to pass a valid *dirpath */
+ GF_ASSERT(dirpath);
+
+ if (dirpath[0] == '/')
+ dirpath++;
+
+ subdir = index(dirpath, (int)'/');
+ if (!subdir) {
+ subdir = root;
+ volname_len = strlen(dirpath);
+ } else {
+ volname_len = subdir - dirpath;
+ }
+
+ if (!volname)
+ goto out;
+
+ if (!*volname)
+ goto out;
+
+ strncpy(*volname, dirpath, volname_len);
+ *(*volname + volname_len) = '\0';
out:
- return subdir;
+ return subdir;
}
-
void
-mnt3_resolve_state_wipe (mnt3_resolve_t *mres)
+mnt3_resolve_state_wipe(mnt3_resolve_t *mres)
{
- if (!mres)
- return;
-
- nfs_loc_wipe (&mres->resolveloc);
- GF_FREE (mres);
+ if (!mres)
+ return;
+ nfs_loc_wipe(&mres->resolveloc);
+ GF_FREE(mres);
}
-
/* Sets up the component argument to contain the next component in the path and
* sets up path as an absolute path starting from the next component.
*/
static char *
-setup_next_component (char *path, size_t plen, char *component, size_t clen)
+setup_next_component(char *path, size_t plen, char *component, size_t clen)
{
- char *comp = NULL;
- char *nextcomp = NULL;
-
- if ((!path) || (!component))
- return NULL;
-
- strncpy (component, path, clen);
- comp = index (component, (int)'/');
- if (!comp)
- goto err;
-
- comp++;
- nextcomp = index (comp, (int)'/');
- if (nextcomp) {
- strncpy (path, nextcomp, plen);
- *nextcomp = '\0';
- } else
- path[0] = '\0';
+ char *comp = NULL;
+ char *nextcomp = NULL;
+
+ if ((!path) || (!component))
+ return NULL;
+
+ strncpy(component, path, clen);
+ comp = index(component, (int)'/');
+ if (!comp)
+ goto err;
+
+ comp++;
+ nextcomp = index(comp, (int)'/');
+ if (nextcomp) {
+ strncpy(path, nextcomp, plen);
+ *nextcomp = '\0';
+ } else
+ path[0] = '\0';
err:
- return comp;
+ return comp;
}
int32_t
-mnt3_resolve_subdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent);
+mnt3_resolve_subdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent);
int32_t
-mnt3_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf, dict_t *xdata);
+mnt3_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ struct iatt *buf, dict_t *xdata);
/* There are multiple components in the directory export path and each one
* needs to be looked up one after the other.
*/
int
-__mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres)
+__mnt3_resolve_export_subdir_comp(mnt3_resolve_t *mres)
{
- char dupsubdir[MNTPATHLEN];
- char *nextcomp = NULL;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- uuid_t gfid = {0, };
-
- if (!mres)
- return ret;
-
- nextcomp = setup_next_component (mres->remainingdir,
- sizeof (mres->remainingdir),
- dupsubdir, sizeof (dupsubdir));
- if (!nextcomp)
- goto err;
-
- /* Wipe the contents of the previous component */
- gf_uuid_copy (gfid, mres->resolveloc.inode->gfid);
- nfs_loc_wipe (&mres->resolveloc);
- ret = nfs_entry_loc_fill (mres->mstate->nfsx, mres->exp->vol->itable,
- gfid, nextcomp, &mres->resolveloc,
- NFS_RESOLVE_CREATE, NULL);
- if ((ret < 0) && (ret != -2)) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EFAULT,
- NFS_MSG_RESOLVE_INODE_FAIL, "Failed to resolve and "
- "create inode: parent gfid %s, entry %s",
- uuid_utoa (gfid), nextcomp);
- ret = -EFAULT;
- goto err;
- }
+ char dupsubdir[MNTPATHLEN];
+ char *nextcomp = NULL;
+ int ret = -EFAULT;
+ nfs_user_t nfu = {
+ 0,
+ };
+ uuid_t gfid = {
+ 0,
+ };
+
+ if (!mres)
+ return ret;
- nfs_request_user_init (&nfu, mres->req);
- if (IA_ISLNK (mres->resolveloc.inode->ia_type)) {
- ret = nfs_readlink (mres->mstate->nfsx, mres->exp->vol, &nfu,
- &mres->resolveloc, mnt3_readlink_cbk, mres);
- gf_msg_debug (GF_MNT, 0, "Symlink found , need to resolve"
- " into directory handle");
- goto err;
- }
- ret = nfs_lookup (mres->mstate->nfsx, mres->exp->vol, &nfu,
- &mres->resolveloc, mnt3_resolve_subdir_cbk, mres);
+ nextcomp = setup_next_component(mres->remainingdir,
+ sizeof(mres->remainingdir), dupsubdir,
+ sizeof(dupsubdir));
+ if (!nextcomp)
+ goto err;
+
+ /* Wipe the contents of the previous component */
+ gf_uuid_copy(gfid, mres->resolveloc.inode->gfid);
+ nfs_loc_wipe(&mres->resolveloc);
+ ret = nfs_entry_loc_fill(mres->mstate->nfsx, mres->exp->vol->itable, gfid,
+ nextcomp, &mres->resolveloc, NFS_RESOLVE_CREATE,
+ NULL);
+ if ((ret < 0) && (ret != -2)) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EFAULT, NFS_MSG_RESOLVE_INODE_FAIL,
+ "Failed to resolve and "
+ "create inode: parent gfid %s, entry %s",
+ uuid_utoa(gfid), nextcomp);
+ ret = -EFAULT;
+ goto err;
+ }
+
+ nfs_request_user_init(&nfu, mres->req);
+ if (IA_ISLNK(mres->resolveloc.inode->ia_type)) {
+ ret = nfs_readlink(mres->mstate->nfsx, mres->exp->vol, &nfu,
+ &mres->resolveloc, mnt3_readlink_cbk, mres);
+ gf_msg_debug(GF_MNT, 0,
+ "Symlink found , need to resolve"
+ " into directory handle");
+ goto err;
+ }
+ ret = nfs_lookup(mres->mstate->nfsx, mres->exp->vol, &nfu,
+ &mres->resolveloc, mnt3_resolve_subdir_cbk, mres);
err:
- return ret;
+ return ret;
}
-int __mnt3_resolve_subdir (mnt3_resolve_t *mres);
+int
+__mnt3_resolve_subdir(mnt3_resolve_t *mres);
/*
* Per the AFR2 comments, this function performs the "fresh" lookup
* by deleting the inode from cache and calling __mnt3_resolve_subdir
* again.
*/
-int __mnt3_fresh_lookup (mnt3_resolve_t *mres) {
- inode_unlink (mres->resolveloc.inode,
- mres->resolveloc.parent, mres->resolveloc.name);
- strncpy (mres->remainingdir, mres->resolveloc.path,
- strlen(mres->resolveloc.path));
- nfs_loc_wipe (&mres->resolveloc);
- return __mnt3_resolve_subdir (mres);
+int
+__mnt3_fresh_lookup(mnt3_resolve_t *mres)
+{
+ inode_unlink(mres->resolveloc.inode, mres->resolveloc.parent,
+ mres->resolveloc.name);
+ strncpy(mres->remainingdir, mres->resolveloc.path,
+ strlen(mres->resolveloc.path));
+ nfs_loc_wipe(&mres->resolveloc);
+ return __mnt3_resolve_subdir(mres);
}
int32_t
-mnt3_resolve_subdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
+mnt3_resolve_subdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
{
- mnt3_resolve_t *mres = NULL;
- mountstat3 mntstat = MNT3ERR_SERVERFAULT;
- struct nfs3_fh fh = {{0}, };
- int autharr[10];
- int autharrlen = 0;
- rpcsvc_t *svc = NULL;
- mountres3 res = {0, };
- xlator_t *mntxl = NULL;
- char *path = NULL;
- struct mount3_state *ms = NULL;
- int authcode = 0;
- char *authorized_host = NULL;
- char *authorized_path = NULL;
- inode_t *linked_inode = NULL;
-
- mres = frame->local;
- ms = mres->mstate;
- mntxl = (xlator_t *)cookie;
- if (op_ret == -1 && op_errno == ESTALE) {
- /* Nuke inode from cache and try the LOOKUP
- * request again. */
- return __mnt3_fresh_lookup (mres);
- } else if (op_ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, op_errno,
- NFS_MSG_RESOLVE_SUBDIR_FAIL, "path=%s (%s)",
- mres->resolveloc.path, strerror (op_errno));
- mntstat = mnt3svc_errno_to_mnterr (op_errno);
- goto err;
+ mnt3_resolve_t *mres = NULL;
+ mountstat3 mntstat = MNT3ERR_SERVERFAULT;
+ struct nfs3_fh fh = {
+ {0},
+ };
+ int autharr[10];
+ int autharrlen = 0;
+ rpcsvc_t *svc = NULL;
+ mountres3 res = {
+ 0,
+ };
+ xlator_t *mntxl = NULL;
+ char *path = NULL;
+ struct mount3_state *ms = NULL;
+ int authcode = 0;
+ char *authorized_host = NULL;
+ char *authorized_path = NULL;
+ inode_t *linked_inode = NULL;
+
+ mres = frame->local;
+ ms = mres->mstate;
+ mntxl = (xlator_t *)cookie;
+ if (op_ret == -1 && op_errno == ESTALE) {
+ /* Nuke inode from cache and try the LOOKUP
+ * request again. */
+ return __mnt3_fresh_lookup(mres);
+ } else if (op_ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, op_errno, NFS_MSG_RESOLVE_SUBDIR_FAIL,
+ "path=%s (%s)", mres->resolveloc.path, strerror(op_errno));
+ mntstat = mnt3svc_errno_to_mnterr(op_errno);
+ goto err;
+ }
+
+ linked_inode = inode_link(mres->resolveloc.inode, mres->resolveloc.parent,
+ mres->resolveloc.name, buf);
+
+ if (linked_inode)
+ nfs_fix_generation(this, linked_inode);
+
+ nfs3_fh_build_child_fh(&mres->parentfh, buf, &fh);
+ if (strlen(mres->remainingdir) <= 0) {
+ int alloclen;
+ op_ret = -1;
+ mntstat = MNT3_OK;
+
+ /* Construct the full path */
+ int resolveloc_path_len = strlen(mres->resolveloc.path);
+ alloclen = strlen(mres->exp->expname) + resolveloc_path_len + 1;
+ mres->exp->fullpath = GF_MALLOC(alloclen, gf_nfs_mt_char);
+ if (!mres->exp->fullpath) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed.");
+ goto err;
+ }
+ snprintf(mres->exp->fullpath, alloclen, "%s%s", mres->exp->expname,
+ mres->resolveloc.path);
+
+ /* Check if this path is authorized to be mounted */
+ authcode = mnt3_authenticate_request(
+ ms, mres->req, NULL, NULL, mres->exp->fullpath, &authorized_path,
+ &authorized_host, FALSE);
+ if (authcode != 0) {
+ mntstat = MNT3ERR_ACCES;
+ gf_msg_debug(GF_MNT, 0, "Client mount not allowed");
+ op_ret = -1;
+ goto err;
}
- linked_inode = inode_link (mres->resolveloc.inode,
- mres->resolveloc.parent,
- mres->resolveloc.name, buf);
-
- if (linked_inode)
- nfs_fix_generation (this, linked_inode);
-
- nfs3_fh_build_child_fh (&mres->parentfh, buf, &fh);
- if (strlen (mres->remainingdir) <= 0) {
- int alloclen;
- op_ret = -1;
- mntstat = MNT3_OK;
-
- /* Construct the full path */
- int resolveloc_path_len = strlen(mres->resolveloc.path);
- alloclen = strlen (mres->exp->expname) +
- resolveloc_path_len + 1;
- mres->exp->fullpath = GF_MALLOC (alloclen, gf_nfs_mt_char);
- if (!mres->exp->fullpath) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY,
- "Memory allocation failed.");
- goto err;
- }
- snprintf (mres->exp->fullpath, alloclen, "%s%s",
- mres->exp->expname, mres->resolveloc.path);
-
- /* Check if this path is authorized to be mounted */
- authcode = mnt3_authenticate_request (ms, mres->req, NULL, NULL,
- mres->exp->fullpath,
- &authorized_path,
- &authorized_host,
- FALSE);
- if (authcode != 0) {
- mntstat = MNT3ERR_ACCES;
- gf_msg_debug (GF_MNT, 0, "Client mount not allowed");
- op_ret = -1;
- goto err;
- }
-
- alloclen = strlen (mres->exp->vol->name) +
- resolveloc_path_len + 2;
- path = GF_MALLOC (alloclen, gf_nfs_mt_char);
- if (!path) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- goto err;
- }
- /* Build mountid from the authorized path and stick it in the
- * filehandle that will get passed back to the client
- */
- __mnt3_build_mountid_from_path (authorized_path, fh.mountid);
-
- snprintf (path, alloclen, "/%s%s", mres->exp->vol->name,
- mres->resolveloc.path);
-
- mnt3svc_update_mountlist (mres->mstate, mres->req,
- path, mres->exp->fullpath);
- GF_FREE (path);
- } else {
- mres->parentfh = fh;
- op_ret = __mnt3_resolve_export_subdir_comp (mres);
- if (op_ret < 0)
- mntstat = mnt3svc_errno_to_mnterr (-op_ret);
+ alloclen = strlen(mres->exp->vol->name) + resolveloc_path_len + 2;
+ path = GF_MALLOC(alloclen, gf_nfs_mt_char);
+ if (!path) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto err;
}
+ /* Build mountid from the authorized path and stick it in the
+ * filehandle that will get passed back to the client
+ */
+ __mnt3_build_mountid_from_path(authorized_path, fh.mountid);
+
+ snprintf(path, alloclen, "/%s%s", mres->exp->vol->name,
+ mres->resolveloc.path);
+
+ mnt3svc_update_mountlist(mres->mstate, mres->req, path,
+ mres->exp->fullpath);
+ GF_FREE(path);
+ } else {
+ mres->parentfh = fh;
+ op_ret = __mnt3_resolve_export_subdir_comp(mres);
+ if (op_ret < 0)
+ mntstat = mnt3svc_errno_to_mnterr(-op_ret);
+ }
err:
- if (op_ret == -1) {
- gf_msg_debug (GF_MNT, 0, "Mount reply status: %d", mntstat);
- svc = rpcsvc_request_service (mres->req);
- autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr,
- 10);
-
- res = mnt3svc_set_mountres3 (mntstat, &fh, autharr, autharrlen);
- mnt3svc_submit_reply (mres->req, (void *)&res,
- (mnt3_serializer)xdr_serialize_mountres3);
- mnt3_resolve_state_wipe (mres);
- }
+ if (op_ret == -1) {
+ gf_msg_debug(GF_MNT, 0, "Mount reply status: %d", mntstat);
+ svc = rpcsvc_request_service(mres->req);
+ autharrlen = rpcsvc_auth_array(svc, mntxl->name, autharr, 10);
- GF_FREE (authorized_path);
- GF_FREE (authorized_host);
+ res = mnt3svc_set_mountres3(mntstat, &fh, autharr, autharrlen);
+ mnt3svc_submit_reply(mres->req, (void *)&res,
+ (mnt3_serializer)xdr_serialize_mountres3);
+ mnt3_resolve_state_wipe(mres);
+ }
- return 0;
+ GF_FREE(authorized_path);
+ GF_FREE(authorized_host);
+
+ return 0;
}
/* This function resolves symbolic link into directory path from
@@ -1251,105 +1250,106 @@ err:
* similar to udp
*/
int32_t
-mnt3_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf, dict_t *xdata)
+mnt3_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ struct iatt *buf, dict_t *xdata)
{
- mnt3_resolve_t *mres = NULL;
- int ret = -EFAULT;
- char *real_loc = NULL;
- size_t path_len = 0;
- size_t parent_path_len = 0;
- char *parent_path = NULL;
- char *absolute_path = NULL;
- char *relative_path = NULL;
- int mntstat = 0;
-
- GF_ASSERT (frame);
-
- mres = frame->local;
- if (!mres || !path || (path[0] == '/') || (op_ret < 0))
- goto mnterr;
-
- /* Finding current location of symlink */
- parent_path_len = strlen (mres->resolveloc.path) - strlen (mres->resolveloc.name);
- parent_path = gf_strndup (mres->resolveloc.path, parent_path_len);
- if (!parent_path) {
- ret = -ENOMEM;
- goto mnterr;
- }
-
- relative_path = gf_strdup (path);
- if (!relative_path) {
- ret = -ENOMEM;
- goto mnterr;
- }
- /* Resolving into absolute path */
- ret = gf_build_absolute_path (parent_path, relative_path, &absolute_path);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret,
- NFS_MSG_RESOLVE_SYMLINK_ERROR,
- "Cannot resolve symlink, path is out of boundary "
- "from current location %s and with relative path "
- "%s pointed by symlink", parent_path, relative_path);
-
- goto mnterr;
- }
-
- /* Building the actual mount path to be mounted */
- path_len = strlen (mres->exp->vol->name) + strlen (absolute_path)
- + strlen (mres->remainingdir) + 1;
- real_loc = GF_MALLOC (path_len, gf_nfs_mt_char);
- if (!real_loc) {
- ret = -ENOMEM;
- goto mnterr;
- }
- snprintf (real_loc, path_len, "%s%s", mres->exp->vol->name, absolute_path);
- gf_path_strip_trailing_slashes (real_loc);
-
- /* There may entries after symlink in the mount path,
- * we should include remaining entries too */
- if (strlen (mres->remainingdir) > 0)
- strcat (real_loc, mres->remainingdir);
-
- gf_msg_debug (GF_MNT, 0, "Resolved path is : %s%s "
- "and actual mount path is %s",
- absolute_path, mres->remainingdir, real_loc);
-
- /* After the resolving the symlink , parsing should be done
- * for the populated mount path
- */
- ret = mnt3_parse_dir_exports (mres->req, mres->mstate, real_loc,
- _gf_true);
-
- if (ret) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_RESOLVE_ERROR,
- "Resolved into an unknown path %s%s "
- "from the current location of symlink %s",
- absolute_path, mres->remainingdir, parent_path);
- }
-
- GF_FREE (real_loc);
- GF_FREE (absolute_path);
- GF_FREE (parent_path);
- GF_FREE (relative_path);
-
- return ret;
+ mnt3_resolve_t *mres = NULL;
+ int ret = -EFAULT;
+ char *real_loc = NULL;
+ size_t path_len = 0;
+ size_t parent_path_len = 0;
+ char *parent_path = NULL;
+ char *absolute_path = NULL;
+ char *relative_path = NULL;
+ int mntstat = 0;
+
+ GF_ASSERT(frame);
+
+ mres = frame->local;
+ if (!mres || !path || (path[0] == '/') || (op_ret < 0))
+ goto mnterr;
+
+ /* Finding current location of symlink */
+ parent_path_len = strlen(mres->resolveloc.path) -
+ strlen(mres->resolveloc.name);
+ parent_path = gf_strndup(mres->resolveloc.path, parent_path_len);
+ if (!parent_path) {
+ ret = -ENOMEM;
+ goto mnterr;
+ }
+
+ relative_path = gf_strdup(path);
+ if (!relative_path) {
+ ret = -ENOMEM;
+ goto mnterr;
+ }
+ /* Resolving into absolute path */
+ ret = gf_build_absolute_path(parent_path, relative_path, &absolute_path);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SYMLINK_ERROR,
+ "Cannot resolve symlink, path is out of boundary "
+ "from current location %s and with relative path "
+ "%s pointed by symlink",
+ parent_path, relative_path);
+
+ goto mnterr;
+ }
+
+ /* Building the actual mount path to be mounted */
+ path_len = strlen(mres->exp->vol->name) + strlen(absolute_path) +
+ strlen(mres->remainingdir) + 1;
+ real_loc = GF_MALLOC(path_len, gf_nfs_mt_char);
+ if (!real_loc) {
+ ret = -ENOMEM;
+ goto mnterr;
+ }
+ snprintf(real_loc, path_len, "%s%s", mres->exp->vol->name, absolute_path);
+ gf_path_strip_trailing_slashes(real_loc);
+
+ /* There may entries after symlink in the mount path,
+ * we should include remaining entries too */
+ if (strlen(mres->remainingdir) > 0)
+ strcat(real_loc, mres->remainingdir);
+
+ gf_msg_debug(GF_MNT, 0,
+ "Resolved path is : %s%s "
+ "and actual mount path is %s",
+ absolute_path, mres->remainingdir, real_loc);
+
+ /* After the resolving the symlink , parsing should be done
+ * for the populated mount path
+ */
+ ret = mnt3_parse_dir_exports(mres->req, mres->mstate, real_loc, _gf_true);
+
+ if (ret) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_RESOLVE_ERROR,
+ "Resolved into an unknown path %s%s "
+ "from the current location of symlink %s",
+ absolute_path, mres->remainingdir, parent_path);
+ }
+
+ GF_FREE(real_loc);
+ GF_FREE(absolute_path);
+ GF_FREE(parent_path);
+ GF_FREE(relative_path);
+
+ return ret;
mnterr:
- if (mres) {
- mntstat = mnt3svc_errno_to_mnterr (-ret);
- mnt3svc_mnt_error_reply (mres->req, mntstat);
- } else
- gf_msg (GF_MNT, GF_LOG_CRITICAL, EINVAL, NFS_MSG_INVALID_ENTRY,
- "mres == NULL, this should *never* happen");
- if (absolute_path)
- GF_FREE (absolute_path);
- if (parent_path)
- GF_FREE (parent_path);
- if (relative_path)
- GF_FREE (relative_path);
- return ret;
+ if (mres) {
+ mntstat = mnt3svc_errno_to_mnterr(-ret);
+ mnt3svc_mnt_error_reply(mres->req, mntstat);
+ } else
+ gf_msg(GF_MNT, GF_LOG_CRITICAL, EINVAL, NFS_MSG_INVALID_ENTRY,
+ "mres == NULL, this should *never* happen");
+ if (absolute_path)
+ GF_FREE(absolute_path);
+ if (parent_path)
+ GF_FREE(parent_path);
+ if (relative_path)
+ GF_FREE(relative_path);
+ return ret;
}
/* We will always have to perform a hard lookup on all the components of a
@@ -1364,69 +1364,72 @@ mnterr:
* of the exported directory can be built.
*/
int
-__mnt3_resolve_subdir (mnt3_resolve_t *mres)
+__mnt3_resolve_subdir(mnt3_resolve_t *mres)
{
- char dupsubdir[MNTPATHLEN];
- char *firstcomp = NULL;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- uuid_t rootgfid = {0, };
-
- if (!mres)
- return ret;
-
- firstcomp = setup_next_component (mres->remainingdir,
- sizeof (mres->remainingdir),
- dupsubdir, sizeof (dupsubdir));
- if (!firstcomp)
- goto err;
-
- rootgfid[15] = 1;
- ret = nfs_entry_loc_fill (mres->mstate->nfsx, mres->exp->vol->itable,
- rootgfid, firstcomp, &mres->resolveloc,
- NFS_RESOLVE_CREATE, NULL);
- if ((ret < 0) && (ret != -2)) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EFAULT,
- NFS_MSG_RESOLVE_INODE_FAIL, "Failed to resolve and "
- "create inode for volume root: %s",
- mres->exp->vol->name);
- ret = -EFAULT;
- goto err;
- }
+ char dupsubdir[MNTPATHLEN];
+ char *firstcomp = NULL;
+ int ret = -EFAULT;
+ nfs_user_t nfu = {
+ 0,
+ };
+ uuid_t rootgfid = {
+ 0,
+ };
+
+ if (!mres)
+ return ret;
- nfs_request_user_init (&nfu, mres->req);
- if (IA_ISLNK (mres->resolveloc.inode->ia_type)) {
- ret = nfs_readlink (mres->mstate->nfsx, mres->exp->vol, &nfu,
- &mres->resolveloc, mnt3_readlink_cbk, mres);
- gf_msg_debug (GF_MNT, 0, "Symlink found , need to resolve "
- "into directory handle");
- goto err;
- }
- ret = nfs_lookup (mres->mstate->nfsx, mres->exp->vol, &nfu,
- &mres->resolveloc, mnt3_resolve_subdir_cbk, mres);
+ firstcomp = setup_next_component(mres->remainingdir,
+ sizeof(mres->remainingdir), dupsubdir,
+ sizeof(dupsubdir));
+ if (!firstcomp)
+ goto err;
+
+ rootgfid[15] = 1;
+ ret = nfs_entry_loc_fill(mres->mstate->nfsx, mres->exp->vol->itable,
+ rootgfid, firstcomp, &mres->resolveloc,
+ NFS_RESOLVE_CREATE, NULL);
+ if ((ret < 0) && (ret != -2)) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EFAULT, NFS_MSG_RESOLVE_INODE_FAIL,
+ "Failed to resolve and "
+ "create inode for volume root: %s",
+ mres->exp->vol->name);
+ ret = -EFAULT;
+ goto err;
+ }
+
+ nfs_request_user_init(&nfu, mres->req);
+ if (IA_ISLNK(mres->resolveloc.inode->ia_type)) {
+ ret = nfs_readlink(mres->mstate->nfsx, mres->exp->vol, &nfu,
+ &mres->resolveloc, mnt3_readlink_cbk, mres);
+ gf_msg_debug(GF_MNT, 0,
+ "Symlink found , need to resolve "
+ "into directory handle");
+ goto err;
+ }
+ ret = nfs_lookup(mres->mstate->nfsx, mres->exp->vol, &nfu,
+ &mres->resolveloc, mnt3_resolve_subdir_cbk, mres);
err:
- return ret;
+ return ret;
}
-
static gf_boolean_t
-mnt3_match_subnet_v4 (struct addrinfo *ai, uint32_t saddr, uint32_t mask)
+mnt3_match_subnet_v4(struct addrinfo *ai, uint32_t saddr, uint32_t mask)
{
- for (; ai; ai = ai->ai_next) {
- struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
+ for (; ai; ai = ai->ai_next) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
- if (sin->sin_family != AF_INET)
- continue;
+ if (sin->sin_family != AF_INET)
+ continue;
- if (mask_match (saddr, sin->sin_addr.s_addr, mask))
- return _gf_true;
- }
+ if (mask_match(saddr, sin->sin_addr.s_addr, mask))
+ return _gf_true;
+ }
- return _gf_false;
+ return _gf_false;
}
-
/**
* This function will verify if the client is allowed to mount
* the directory or not. Client's IP address will be compared with
@@ -1440,446 +1443,448 @@ mnt3_match_subnet_v4 (struct addrinfo *ai, uint32_t saddr, uint32_t mask)
* TODO: Support IPv6 subnetwork
*/
int
-mnt3_verify_auth (struct sockaddr_in *client_addr, struct mnt3_export *export)
+mnt3_verify_auth(struct sockaddr_in *client_addr, struct mnt3_export *export)
{
- int retvalue = -EACCES;
- int ret = 0;
- struct host_auth_spec *host = NULL;
- struct sockaddr_in *allowed_addr = NULL;
- struct addrinfo *allowed_addrinfo = NULL;
-
- struct addrinfo hint = {
- .ai_family = AF_INET,
- .ai_protocol = (int)IPPROTO_TCP,
- .ai_flags = AI_CANONNAME,
- };
-
- /* Sanity check */
- if ((NULL == client_addr) ||
- (NULL == export) ||
- (NULL == export->hostspec)) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
- "Invalid argument");
- return retvalue;
- }
-
- host = export->hostspec;
-
- /*
- * Currently IPv4 subnetwork is supported i.e. AF_INET.
- * TODO: IPv6 subnetwork i.e. AF_INET6.
- */
- if (client_addr->sin_family != AF_INET) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EAFNOSUPPORT,
- NFS_MSG_UNSUPPORTED_VERSION,
- "Only IPv4 is supported for subdir-auth");
- return retvalue;
- }
+ int retvalue = -EACCES;
+ int ret = 0;
+ struct host_auth_spec *host = NULL;
+ struct sockaddr_in *allowed_addr = NULL;
+ struct addrinfo *allowed_addrinfo = NULL;
+
+ struct addrinfo hint = {
+ .ai_family = AF_INET,
+ .ai_protocol = (int)IPPROTO_TCP,
+ .ai_flags = AI_CANONNAME,
+ };
+
+ /* Sanity check */
+ if ((NULL == client_addr) || (NULL == export) ||
+ (NULL == export->hostspec)) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
+ "Invalid argument");
+ return retvalue;
+ }
- /* Try to see if the client IP matches the allowed IP list.*/
- while (NULL != host){
- GF_ASSERT (host->host_addr);
+ host = export->hostspec;
- if (NULL != allowed_addrinfo) {
- freeaddrinfo (allowed_addrinfo);
- allowed_addrinfo = NULL;
- }
+ /*
+ * Currently IPv4 subnetwork is supported i.e. AF_INET.
+ * TODO: IPv6 subnetwork i.e. AF_INET6.
+ */
+ if (client_addr->sin_family != AF_INET) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EAFNOSUPPORT, NFS_MSG_UNSUPPORTED_VERSION,
+ "Only IPv4 is supported for subdir-auth");
+ return retvalue;
+ }
- /* Get the addrinfo for the allowed host (host_addr). */
- ret = getaddrinfo (host->host_addr, NULL,
- &hint, &allowed_addrinfo);
- if (0 != ret){
- /*
- * getaddrinfo() FAILED for the host IP addr. Continue
- * to search other allowed hosts in the hostspec list.
- */
- gf_msg_debug (GF_MNT, 0, "getaddrinfo: %s\n",
- gai_strerror (ret));
- host = host->next;
- continue;
- }
+ /* Try to see if the client IP matches the allowed IP list.*/
+ while (NULL != host) {
+ GF_ASSERT(host->host_addr);
- allowed_addr = (struct sockaddr_in *)(allowed_addrinfo->ai_addr);
- if (NULL == allowed_addr) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_INVALID_ENTRY, "Invalid structure");
- break;
- }
+ if (NULL != allowed_addrinfo) {
+ freeaddrinfo(allowed_addrinfo);
+ allowed_addrinfo = NULL;
+ }
- /* Check if the network addr of both IPv4 socket match */
- if (mnt3_match_subnet_v4 (allowed_addrinfo,
- client_addr->sin_addr.s_addr,
- host->netmask)) {
- retvalue = 0;
- break;
- }
+ /* Get the addrinfo for the allowed host (host_addr). */
+ ret = getaddrinfo(host->host_addr, NULL, &hint, &allowed_addrinfo);
+ if (0 != ret) {
+ /*
+ * getaddrinfo() FAILED for the host IP addr. Continue
+ * to search other allowed hosts in the hostspec list.
+ */
+ gf_msg_debug(GF_MNT, 0, "getaddrinfo: %s\n", gai_strerror(ret));
+ host = host->next;
+ continue;
+ }
- /* No match yet, continue the search */
- host = host->next;
+ allowed_addr = (struct sockaddr_in *)(allowed_addrinfo->ai_addr);
+ if (NULL == allowed_addr) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
+ "Invalid structure");
+ break;
}
- /* FREE the dynamic memory allocated by getaddrinfo() */
- if (NULL != allowed_addrinfo) {
- freeaddrinfo (allowed_addrinfo);
+ /* Check if the network addr of both IPv4 socket match */
+ if (mnt3_match_subnet_v4(allowed_addrinfo, client_addr->sin_addr.s_addr,
+ host->netmask)) {
+ retvalue = 0;
+ break;
}
- return retvalue;
+ /* No match yet, continue the search */
+ host = host->next;
+ }
+
+ /* FREE the dynamic memory allocated by getaddrinfo() */
+ if (NULL != allowed_addrinfo) {
+ freeaddrinfo(allowed_addrinfo);
+ }
+
+ return retvalue;
}
int
-mnt3_resolve_subdir (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp, char *subdir,
- gf_boolean_t send_reply)
+mnt3_resolve_subdir(rpcsvc_request_t *req, struct mount3_state *ms,
+ struct mnt3_export *exp, char *subdir,
+ gf_boolean_t send_reply)
{
- mnt3_resolve_t *mres = NULL;
- int ret = -EFAULT;
- struct nfs3_fh pfh = GF_NFS3FH_STATIC_INITIALIZER;
- struct sockaddr_in *sin = NULL;
-
- if ((!req) || (!ms) || (!exp) || (!subdir))
- return ret;
-
- sin = (struct sockaddr_in *)(&(req->trans->peerinfo.sockaddr));
-
- /* Need to check AUTH */
- if (NULL != exp->hostspec) {
- ret = mnt3_verify_auth (sin, exp);
- if (0 != ret) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EACCES,
- NFS_MSG_AUTH_VERIFY_FAILED,
- "AUTH verification failed");
- return ret;
- }
- }
+ mnt3_resolve_t *mres = NULL;
+ int ret = -EFAULT;
+ struct nfs3_fh pfh = GF_NFS3FH_STATIC_INITIALIZER;
+ struct sockaddr_in *sin = NULL;
- /* no reply is needed (WebNFS permissions checking), just return */
- if (!send_reply)
- return 0; /* no error, mnt3_verify_auth() allowed it */
+ if ((!req) || (!ms) || (!exp) || (!subdir))
+ return ret;
- mres = GF_CALLOC (1, sizeof (mnt3_resolve_t), gf_nfs_mt_mnt3_resolve);
- if (!mres) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- goto err;
+ sin = (struct sockaddr_in *)(&(req->trans->peerinfo.sockaddr));
+
+ /* Need to check AUTH */
+ if (NULL != exp->hostspec) {
+ ret = mnt3_verify_auth(sin, exp);
+ if (0 != ret) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EACCES, NFS_MSG_AUTH_VERIFY_FAILED,
+ "AUTH verification failed");
+ return ret;
}
+ }
+
+ /* no reply is needed (WebNFS permissions checking), just return */
+ if (!send_reply)
+ return 0; /* no error, mnt3_verify_auth() allowed it */
- mres->exp = exp;
- mres->mstate = ms;
- mres->req = req;
+ mres = GF_CALLOC(1, sizeof(mnt3_resolve_t), gf_nfs_mt_mnt3_resolve);
+ if (!mres) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto err;
+ }
- snprintf (mres->remainingdir, MNTPATHLEN, "%s", subdir);
- gf_path_strip_trailing_slashes (mres->remainingdir);
+ mres->exp = exp;
+ mres->mstate = ms;
+ mres->req = req;
- if (gf_nfs_dvm_off (nfs_state (ms->nfsx)))
- pfh = nfs3_fh_build_indexed_root_fh (
- mres->mstate->nfsx->children,
+ snprintf(mres->remainingdir, MNTPATHLEN, "%s", subdir);
+ gf_path_strip_trailing_slashes(mres->remainingdir);
+
+ if (gf_nfs_dvm_off(nfs_state(ms->nfsx)))
+ pfh = nfs3_fh_build_indexed_root_fh(mres->mstate->nfsx->children,
mres->exp->vol);
- else
- pfh = nfs3_fh_build_uuid_root_fh (exp->volumeid, exp->mountid);
+ else
+ pfh = nfs3_fh_build_uuid_root_fh(exp->volumeid, exp->mountid);
- mres->parentfh = pfh;
- ret = __mnt3_resolve_subdir (mres);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL,
- "Failed to resolve export dir: %s", mres->exp->expname);
- GF_FREE (mres);
- }
+ mres->parentfh = pfh;
+ ret = __mnt3_resolve_subdir(mres);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL,
+ "Failed to resolve export dir: %s", mres->exp->expname);
+ GF_FREE(mres);
+ }
err:
- return ret;
+ return ret;
}
-
int
-mnt3_resolve_export_subdir (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp)
+mnt3_resolve_export_subdir(rpcsvc_request_t *req, struct mount3_state *ms,
+ struct mnt3_export *exp)
{
- char *volume_subdir = NULL;
- int ret = -EFAULT;
+ char *volume_subdir = NULL;
+ int ret = -EFAULT;
- if ((!req) || (!ms) || (!exp))
- return ret;
+ if ((!req) || (!ms) || (!exp))
+ return ret;
- volume_subdir = mnt3_get_volume_subdir (exp->expname, NULL);
+ volume_subdir = mnt3_get_volume_subdir(exp->expname, NULL);
- ret = mnt3_resolve_subdir (req, ms, exp, volume_subdir, _gf_true);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL,
- "Failed to resolve export dir: %s", exp->expname);
- goto err;
- }
+ ret = mnt3_resolve_subdir(req, ms, exp, volume_subdir, _gf_true);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL,
+ "Failed to resolve export dir: %s", exp->expname);
+ goto err;
+ }
err:
- return ret;
+ return ret;
}
-
int
-mnt3svc_mount (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp)
+mnt3svc_mount(rpcsvc_request_t *req, struct mount3_state *ms,
+ struct mnt3_export *exp)
{
- int ret = -EFAULT;
+ int ret = -EFAULT;
- if ((!req) || (!ms) || (!exp))
- return ret;
+ if ((!req) || (!ms) || (!exp))
+ return ret;
- if (exp->exptype == MNT3_EXPTYPE_VOLUME)
- ret = mnt3svc_volume_mount (req, ms, exp);
- else if (exp->exptype == MNT3_EXPTYPE_DIR)
- ret = mnt3_resolve_export_subdir (req, ms, exp);
+ if (exp->exptype == MNT3_EXPTYPE_VOLUME)
+ ret = mnt3svc_volume_mount(req, ms, exp);
+ else if (exp->exptype == MNT3_EXPTYPE_DIR)
+ ret = mnt3_resolve_export_subdir(req, ms, exp);
- return ret;
+ return ret;
}
-
/* mnt3_mntpath_to_xlator sets this to 1 if the mount is for a full
-* volume or 2 for a subdir in the volume.
-*
-* The parameter 'export_parsing_match' indicates whether this function
-* is being called by an exports parser or whether it is being called
-* during mount. The behavior is different since we don't have to resolve
-* the path when doing the parse.
-*/
+ * volume or 2 for a subdir in the volume.
+ *
+ * The parameter 'export_parsing_match' indicates whether this function
+ * is being called by an exports parser or whether it is being called
+ * during mount. The behavior is different since we don't have to resolve
+ * the path when doing the parse.
+ */
struct mnt3_export *
-mnt3_mntpath_to_export (struct mount3_state *ms, const char *dirpath,
- gf_boolean_t export_parsing_match)
+mnt3_mntpath_to_export(struct mount3_state *ms, const char *dirpath,
+ gf_boolean_t export_parsing_match)
{
- struct mnt3_export *exp = NULL;
- struct mnt3_export *found = NULL;
-
- if ((!ms) || (!dirpath))
- return NULL;
-
- LOCK (&ms->mountlock);
- list_for_each_entry (exp, &ms->exportlist, explist) {
-
- /* Search for the an exact match with the volume */
- if (mnt3_match_dirpath_export (exp->expname, dirpath,
- export_parsing_match)) {
- found = exp;
- gf_msg_debug (GF_MNT, 0, "Found export volume: "
- "%s", exp->vol->name);
- goto foundexp;
- }
- }
+ struct mnt3_export *exp = NULL;
+ struct mnt3_export *found = NULL;
- gf_msg_debug (GF_MNT, 0, "Export not found");
+ if ((!ms) || (!dirpath))
+ return NULL;
+
+ LOCK(&ms->mountlock);
+ list_for_each_entry(exp, &ms->exportlist, explist)
+ {
+ /* Search for the an exact match with the volume */
+ if (mnt3_match_dirpath_export(exp->expname, dirpath,
+ export_parsing_match)) {
+ found = exp;
+ gf_msg_debug(GF_MNT, 0,
+ "Found export volume: "
+ "%s",
+ exp->vol->name);
+ goto foundexp;
+ }
+ }
+
+ gf_msg_debug(GF_MNT, 0, "Export not found");
foundexp:
- UNLOCK (&ms->mountlock);
- return found;
+ UNLOCK(&ms->mountlock);
+ return found;
}
-
static int
-mnt3_check_client_net_check (rpcsvc_t *svc, char *expvol,
- char *ipaddr, uint16_t port)
+mnt3_check_client_net_check(rpcsvc_t *svc, char *expvol, char *ipaddr,
+ uint16_t port)
{
- int ret = RPCSVC_AUTH_REJECT;
-
- if ((!svc) || (!expvol) || (!ipaddr))
- goto err;
-
- ret = rpcsvc_auth_check (svc, expvol, ipaddr);
- if (ret == RPCSVC_AUTH_REJECT) {
- gf_msg (GF_MNT, GF_LOG_INFO, 0, NFS_MSG_PEER_NOT_ALLOWED,
- "Peer %s not allowed", ipaddr);
- goto err;
- }
-
- ret = rpcsvc_transport_privport_check (svc, expvol, port);
- if (ret == RPCSVC_AUTH_REJECT) {
- gf_msg (GF_MNT, GF_LOG_INFO, errno, NFS_MSG_PEER_NOT_ALLOWED,
- "Peer %s rejected. Unprivileged "
- "port %d not allowed", ipaddr, port);
- goto err;
- }
-
- ret = RPCSVC_AUTH_ACCEPT;
+ int ret = RPCSVC_AUTH_REJECT;
+
+ if ((!svc) || (!expvol) || (!ipaddr))
+ goto err;
+
+ ret = rpcsvc_auth_check(svc, expvol, ipaddr);
+ if (ret == RPCSVC_AUTH_REJECT) {
+ gf_msg(GF_MNT, GF_LOG_INFO, 0, NFS_MSG_PEER_NOT_ALLOWED,
+ "Peer %s not allowed", ipaddr);
+ goto err;
+ }
+
+ ret = rpcsvc_transport_privport_check(svc, expvol, port);
+ if (ret == RPCSVC_AUTH_REJECT) {
+ gf_msg(GF_MNT, GF_LOG_INFO, errno, NFS_MSG_PEER_NOT_ALLOWED,
+ "Peer %s rejected. Unprivileged "
+ "port %d not allowed",
+ ipaddr, port);
+ goto err;
+ }
+
+ ret = RPCSVC_AUTH_ACCEPT;
err:
- return ret;
+ return ret;
}
int
-mnt3_check_client_net_tcp (rpcsvc_request_t *req, char *volname)
+mnt3_check_client_net_tcp(rpcsvc_request_t *req, char *volname)
{
- rpcsvc_t *svc = NULL;
- rpc_transport_t *trans = NULL;
- union gf_sock_union sock_union;
- socklen_t socksize = sizeof (struct sockaddr_in);
- char peer[RPCSVC_PEER_STRLEN] = {0,};
- char *ipaddr = NULL;
- uint16_t port = 0;
- int ret = RPCSVC_AUTH_REJECT;
-
- if ((!req) || (!volname))
- goto err;
-
- svc = rpcsvc_request_service (req);
- trans = rpcsvc_request_transport (req);
- if ((!svc) || (!trans))
- goto err;
-
- ret = rpcsvc_transport_peeraddr (trans, peer, RPCSVC_PEER_STRLEN,
- &sock_union.storage, socksize);
- if (ret != 0) {
- gf_msg (GF_MNT, GF_LOG_WARNING, ENOENT,
- NFS_MSG_GET_PEER_ADDR_FAIL, "Failed to get peer "
- "addr: %s", gai_strerror (ret));
- ret = RPCSVC_AUTH_REJECT;
- goto err;
- }
-
- /* peer[] gets IP:PORT formar, slash the port out */
- if (!get_host_name ((char *)peer, &ipaddr))
- ipaddr = peer;
-
- port = ntohs (sock_union.sin.sin_port);
-
- ret = mnt3_check_client_net_check (svc, volname, ipaddr, port);
+ rpcsvc_t *svc = NULL;
+ rpc_transport_t *trans = NULL;
+ union gf_sock_union sock_union;
+ socklen_t socksize = sizeof(struct sockaddr_in);
+ char peer[RPCSVC_PEER_STRLEN] = {
+ 0,
+ };
+ char *ipaddr = NULL;
+ uint16_t port = 0;
+ int ret = RPCSVC_AUTH_REJECT;
+
+ if ((!req) || (!volname))
+ goto err;
+
+ svc = rpcsvc_request_service(req);
+ trans = rpcsvc_request_transport(req);
+ if ((!svc) || (!trans))
+ goto err;
+
+ ret = rpcsvc_transport_peeraddr(trans, peer, RPCSVC_PEER_STRLEN,
+ &sock_union.storage, socksize);
+ if (ret != 0) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, ENOENT, NFS_MSG_GET_PEER_ADDR_FAIL,
+ "Failed to get peer "
+ "addr: %s",
+ gai_strerror(ret));
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ /* peer[] gets IP:PORT formar, slash the port out */
+ if (!get_host_name((char *)peer, &ipaddr))
+ ipaddr = peer;
+
+ port = ntohs(sock_union.sin.sin_port);
+
+ ret = mnt3_check_client_net_check(svc, volname, ipaddr, port);
err:
- return ret;
+ return ret;
}
static int
-mnt3_check_client_net_udp (struct svc_req *req, char *volname, xlator_t *nfsx)
+mnt3_check_client_net_udp(struct svc_req *req, char *volname, xlator_t *nfsx)
{
- rpcsvc_t *svc = NULL;
- struct sockaddr_in *sin = NULL;
- char ipaddr[INET_ADDRSTRLEN + 1] = {0, };
- uint16_t port = 0;
- int ret = RPCSVC_AUTH_REJECT;
- struct nfs_state *nfs = NULL;
-
- if ((!req) || (!volname) || (!nfsx))
- goto err;
+ rpcsvc_t *svc = NULL;
+ struct sockaddr_in *sin = NULL;
+ char ipaddr[INET_ADDRSTRLEN + 1] = {
+ 0,
+ };
+ uint16_t port = 0;
+ int ret = RPCSVC_AUTH_REJECT;
+ struct nfs_state *nfs = NULL;
+
+ if ((!req) || (!volname) || (!nfsx))
+ goto err;
#if !defined(_TIRPC_SVC_H)
- sin = svc_getcaller (req->rq_xprt);
+ sin = svc_getcaller(req->rq_xprt);
#else
- sin = (struct sockaddr_in *)svc_getcaller (req->rq_xprt);
- /* TIRPC's svc_getcaller() returns a pointer to a sockaddr_in6, even
- * though it might actually be an IPv4 address. It ought return a
- * struct sockaddr and make the caller upcast it to the proper
- * address family. Sigh.
- */
+ sin = (struct sockaddr_in *)svc_getcaller(req->rq_xprt);
+ /* TIRPC's svc_getcaller() returns a pointer to a sockaddr_in6, even
+ * though it might actually be an IPv4 address. It ought return a
+ * struct sockaddr and make the caller upcast it to the proper
+ * address family. Sigh.
+ */
#endif
- if (!sin)
- goto err;
- /* And let's make sure that it's actually an IPv4 address. */
+ if (!sin)
+ goto err;
+ /* And let's make sure that it's actually an IPv4 address. */
- GF_ASSERT (sin->sin_family == AF_INET);
+ GF_ASSERT(sin->sin_family == AF_INET);
- (void) inet_ntop (AF_INET, &sin->sin_addr, ipaddr, INET_ADDRSTRLEN);
+ (void)inet_ntop(AF_INET, &sin->sin_addr, ipaddr, INET_ADDRSTRLEN);
- port = ntohs (sin->sin_port);
+ port = ntohs(sin->sin_port);
- nfs = (struct nfs_state *)nfsx->private;
- if (nfs != NULL)
- svc = nfs->rpcsvc;
+ nfs = (struct nfs_state *)nfsx->private;
+ if (nfs != NULL)
+ svc = nfs->rpcsvc;
- ret = mnt3_check_client_net_check (svc, volname, ipaddr, port);
+ ret = mnt3_check_client_net_check(svc, volname, ipaddr, port);
err:
- return ret;
+ return ret;
}
-
int
-mnt3_parse_dir_exports (rpcsvc_request_t *req, struct mount3_state *ms,
- char *path, gf_boolean_t send_reply)
+mnt3_parse_dir_exports(rpcsvc_request_t *req, struct mount3_state *ms,
+ char *path, gf_boolean_t send_reply)
{
- char volname[1024] = {0, };
- struct mnt3_export *exp = NULL;
- char *volname_ptr = NULL;
- char *subdir = NULL;
- int ret = -ENOENT;
- struct nfs_state *nfs = NULL;
-
- if ((!ms) || (!path))
- return -1;
-
- volname_ptr = volname;
- subdir = mnt3_get_volume_subdir (path, &volname_ptr);
+ char volname[1024] = {
+ 0,
+ };
+ struct mnt3_export *exp = NULL;
+ char *volname_ptr = NULL;
+ char *subdir = NULL;
+ int ret = -ENOENT;
+ struct nfs_state *nfs = NULL;
+
+ if ((!ms) || (!path))
+ return -1;
- /* first try to match the full export/subdir */
- exp = mnt3_mntpath_to_export (ms, path, _gf_false);
+ volname_ptr = volname;
+ subdir = mnt3_get_volume_subdir(path, &volname_ptr);
+
+ /* first try to match the full export/subdir */
+ exp = mnt3_mntpath_to_export(ms, path, _gf_false);
+ if (!exp) {
+ gf_msg_trace(GF_MNT, 0,
+ "Could not find exact matching export "
+ "for path=%s",
+ path);
+ /* if no exact match is found, look for a fallback */
+ exp = mnt3_mntpath_to_export(ms, volname, _gf_true);
if (!exp) {
- gf_msg_trace (GF_MNT, 0, "Could not find exact matching export "
- "for path=%s", path);
- /* if no exact match is found, look for a fallback */
- exp = mnt3_mntpath_to_export (ms, volname, _gf_true);
- if (!exp) {
- gf_msg_trace (GF_MNT, 0, "Could not find export for "
- "volume %s", volname);
- goto err;
- }
- }
- gf_msg_trace (GF_MNT, 0, "volume %s and export %s will be used for "
- "path %s", exp->vol->name, exp->expname, path);
-
- nfs = (struct nfs_state *)ms->nfsx->private;
- if (!nfs)
- goto err;
-
- if (!nfs_subvolume_started (nfs, exp->vol)) {
- gf_msg_debug (GF_MNT, 0, "Volume %s not started",
- exp->vol->name);
- goto err;
- }
-
- ret = mnt3_check_client_net_tcp (req, exp->vol->name);
- if (ret == RPCSVC_AUTH_REJECT) {
- gf_msg_debug (GF_MNT, 0, "Client mount not allowed");
- ret = -EACCES;
- goto err;
- }
-
- ret = mnt3_resolve_subdir (req, ms, exp, subdir, send_reply);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL,
- "Failed to resolve export dir: %s", subdir);
- goto err;
- }
+ gf_msg_trace(GF_MNT, 0,
+ "Could not find export for "
+ "volume %s",
+ volname);
+ goto err;
+ }
+ }
+ gf_msg_trace(GF_MNT, 0,
+ "volume %s and export %s will be used for "
+ "path %s",
+ exp->vol->name, exp->expname, path);
+
+ nfs = (struct nfs_state *)ms->nfsx->private;
+ if (!nfs)
+ goto err;
+
+ if (!nfs_subvolume_started(nfs, exp->vol)) {
+ gf_msg_debug(GF_MNT, 0, "Volume %s not started", exp->vol->name);
+ goto err;
+ }
+
+ ret = mnt3_check_client_net_tcp(req, exp->vol->name);
+ if (ret == RPCSVC_AUTH_REJECT) {
+ gf_msg_debug(GF_MNT, 0, "Client mount not allowed");
+ ret = -EACCES;
+ goto err;
+ }
+
+ ret = mnt3_resolve_subdir(req, ms, exp, subdir, send_reply);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RESOLVE_SUBDIR_FAIL,
+ "Failed to resolve export dir: %s", subdir);
+ goto err;
+ }
err:
- return ret;
+ return ret;
}
-
int
-mnt3_find_export (rpcsvc_request_t *req, char *path, struct mnt3_export **e)
+mnt3_find_export(rpcsvc_request_t *req, char *path, struct mnt3_export **e)
{
- int ret = -EFAULT;
- struct mount3_state *ms = NULL;
- struct mnt3_export *exp = NULL;
-
- if ((!req) || (!path) || (!e))
- return -1;
-
- ms = (struct mount3_state *) rpcsvc_request_program_private (req);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_NOT_FOUND, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto err;
- }
+ int ret = -EFAULT;
+ struct mount3_state *ms = NULL;
+ struct mnt3_export *exp = NULL;
- gf_msg_debug (GF_MNT, 0, "dirpath: %s", path);
- exp = mnt3_mntpath_to_export (ms, path, _gf_false);
- if (exp) {
- ret = 0;
- *e = exp;
- goto err;
- }
+ if ((!req) || (!path) || (!e))
+ return -1;
- if (!gf_mnt3_export_dirs(ms)) {
- ret = -1;
- goto err;
- }
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_NOT_FOUND,
+ "Mount state not present");
+ rpcsvc_request_seterr(req, SYSTEM_ERR);
+ goto err;
+ }
+
+ gf_msg_debug(GF_MNT, 0, "dirpath: %s", path);
+ exp = mnt3_mntpath_to_export(ms, path, _gf_false);
+ if (exp) {
+ ret = 0;
+ *e = exp;
+ goto err;
+ }
- ret = mnt3_parse_dir_exports (req, ms, path, _gf_true);
+ if (!gf_mnt3_export_dirs(ms)) {
+ ret = -1;
+ goto err;
+ }
+
+ ret = mnt3_parse_dir_exports(req, ms, path, _gf_true);
err:
- return ret;
+ return ret;
}
/**
@@ -1892,25 +1897,29 @@ err:
* failure: NULL
*/
char *
-_mnt3_get_peer_addr (const rpcsvc_request_t *req)
+_mnt3_get_peer_addr(const rpcsvc_request_t *req)
{
- rpc_transport_t *trans = NULL;
- struct sockaddr_storage sastorage = {0, };
- char peer[RPCSVC_PEER_STRLEN] = {0, };
- char *peerdup = NULL;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO (GF_NFS, req, out);
-
- trans = rpcsvc_request_transport (req);
- ret = rpcsvc_transport_peeraddr (trans, peer, RPCSVC_PEER_STRLEN,
- &sastorage, sizeof (sastorage));
- if (ret != 0)
- goto out;
-
- peerdup = gf_strdup (peer);
+ rpc_transport_t *trans = NULL;
+ struct sockaddr_storage sastorage = {
+ 0,
+ };
+ char peer[RPCSVC_PEER_STRLEN] = {
+ 0,
+ };
+ char *peerdup = NULL;
+ int ret = 0;
+
+ GF_VALIDATE_OR_GOTO(GF_NFS, req, out);
+
+ trans = rpcsvc_request_transport(req);
+ ret = rpcsvc_transport_peeraddr(trans, peer, RPCSVC_PEER_STRLEN, &sastorage,
+ sizeof(sastorage));
+ if (ret != 0)
+ goto out;
+
+ peerdup = gf_strdup(peer);
out:
- return peerdup;
+ return peerdup;
}
/**
@@ -1925,27 +1934,27 @@ out:
*
*/
char *
-_mnt3_get_host_from_peer (const char *peer_addr)
+_mnt3_get_host_from_peer(const char *peer_addr)
{
- char *part = NULL;
- size_t host_len = 0;
- char *colon = NULL;
-
- colon = strrchr (peer_addr, ':');
- if (!colon) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_BAD_PEER,
- "Bad peer %s", peer_addr);
- goto out;
- }
-
- host_len = colon - peer_addr;
- if (host_len < RPCSVC_PEER_STRLEN)
- part = gf_strndup (peer_addr, host_len);
- else
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_PEER_TOO_LONG,
- "Peer too long %s", peer_addr);
+ char *part = NULL;
+ size_t host_len = 0;
+ char *colon = NULL;
+
+ colon = strrchr(peer_addr, ':');
+ if (!colon) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_BAD_PEER, "Bad peer %s",
+ peer_addr);
+ goto out;
+ }
+
+ host_len = colon - peer_addr;
+ if (host_len < RPCSVC_PEER_STRLEN)
+ part = gf_strndup(peer_addr, host_len);
+ else
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_PEER_TOO_LONG,
+ "Peer too long %s", peer_addr);
out:
- return part;
+ return part;
}
/**
@@ -1956,13 +1965,13 @@ out:
*
*/
int
-mnt3_check_cached_fh (struct mount3_state *ms, struct nfs3_fh *fh,
- const char *host_addr, gf_boolean_t is_write_op)
+mnt3_check_cached_fh(struct mount3_state *ms, struct nfs3_fh *fh,
+ const char *host_addr, gf_boolean_t is_write_op)
{
- if (!is_write_op)
- return is_nfs_fh_cached (ms->authcache, fh, host_addr);
+ if (!is_write_op)
+ return is_nfs_fh_cached(ms->authcache, fh, host_addr);
- return is_nfs_fh_cached_and_writeable (ms->authcache, fh, host_addr);
+ return is_nfs_fh_cached_and_writeable(ms->authcache, fh, host_addr);
}
/**
@@ -1984,109 +1993,103 @@ mnt3_check_cached_fh (struct mount3_state *ms, struct nfs3_fh *fh,
* -EROFS for unauthorized write operations (rm, mkdir, write)
*/
int
-_mnt3_authenticate_req (struct mount3_state *ms, rpcsvc_request_t *req,
- struct nfs3_fh *fh, const char *path,
- char **authorized_export, char **authorized_host,
- gf_boolean_t is_write_op)
+_mnt3_authenticate_req(struct mount3_state *ms, rpcsvc_request_t *req,
+ struct nfs3_fh *fh, const char *path,
+ char **authorized_export, char **authorized_host,
+ gf_boolean_t is_write_op)
{
- char *peer_addr = NULL;
- char *host_addr_ip = NULL;
- char *host_addr_fqdn = NULL;
- int auth_status_code = -EACCES;
- char *pathdup = NULL;
- size_t dlen = 0;
- char *auth_host = NULL;
- gf_boolean_t fh_cached = _gf_false;
- struct export_item *expitem = NULL;
-
- GF_VALIDATE_OR_GOTO (GF_MNT, ms, out);
- GF_VALIDATE_OR_GOTO (GF_MNT, req, out);
-
- peer_addr = _mnt3_get_peer_addr (req);
-
- if (!peer_addr)
- goto free_and_out;
-
- host_addr_ip = _mnt3_get_host_from_peer (peer_addr);
-
- if (!host_addr_ip)
- goto free_and_out;
-
- if (path) {
- /* Need to strip out trailing '/' */
- pathdup = strdupa (path);
- dlen = strlen (pathdup);
- if (dlen > 0 && pathdup[dlen-1] == '/')
- pathdup[dlen-1] = '\0';
- }
-
- /* Check if the filehandle is cached */
- fh_cached = mnt3_check_cached_fh (ms, fh, host_addr_ip, is_write_op);
- if (fh_cached) {
- gf_msg_trace (GF_MNT, 0, "Found cached FH for %s",
- host_addr_ip);
- auth_status_code = 0;
- goto free_and_out;
- }
-
- /* Check if the IP is authorized */
- auth_status_code = mnt3_auth_host (ms->auth_params, host_addr_ip,
- fh, pathdup, is_write_op, &expitem);
-
- gf_msg_debug (GF_MNT, 0, "access from IP %s is %s", host_addr_ip,
- auth_status_code ? "denied" : "allowed");
-
- if (auth_status_code != 0) {
- /* If not, check if the FQDN is authorized */
- host_addr_fqdn = gf_rev_dns_lookup (host_addr_ip);
- auth_status_code = mnt3_auth_host (ms->auth_params,
- host_addr_fqdn,
- fh, pathdup, is_write_op,
- &expitem);
-
- gf_msg_debug (GF_MNT, 0, "access from FQDN %s is %s",
- host_addr_fqdn, auth_status_code ? "denied" :
- "allowed");
-
- if (auth_status_code == 0)
- auth_host = host_addr_fqdn;
- } else
- auth_host = host_addr_ip;
-
- /* Skip the lines that set authorized export &
- * host if they are null.
- */
- if (!authorized_export || !authorized_host) {
- /* Cache the file handle if it was authorized */
- if (fh && auth_status_code == 0)
- cache_nfs_fh (ms->authcache, fh, host_addr_ip, expitem);
-
- goto free_and_out;
- }
-
- if (!fh && auth_status_code == 0) {
- *authorized_export = gf_strdup (pathdup);
- if (!*authorized_export)
- gf_msg (GF_MNT, GF_LOG_CRITICAL, ENOMEM,
- NFS_MSG_NO_MEMORY,
- "Allocation error when copying "
- "authorized path");
-
- *authorized_host = gf_strdup (auth_host);
- if (!*authorized_host)
- gf_msg (GF_MNT, GF_LOG_CRITICAL, ENOMEM,
- NFS_MSG_NO_MEMORY,
- "Allocation error when copying "
- "authorized host");
- }
+ char *peer_addr = NULL;
+ char *host_addr_ip = NULL;
+ char *host_addr_fqdn = NULL;
+ int auth_status_code = -EACCES;
+ char *pathdup = NULL;
+ size_t dlen = 0;
+ char *auth_host = NULL;
+ gf_boolean_t fh_cached = _gf_false;
+ struct export_item *expitem = NULL;
+
+ GF_VALIDATE_OR_GOTO(GF_MNT, ms, out);
+ GF_VALIDATE_OR_GOTO(GF_MNT, req, out);
+
+ peer_addr = _mnt3_get_peer_addr(req);
+
+ if (!peer_addr)
+ goto free_and_out;
+
+ host_addr_ip = _mnt3_get_host_from_peer(peer_addr);
+
+ if (!host_addr_ip)
+ goto free_and_out;
+
+ if (path) {
+ /* Need to strip out trailing '/' */
+ pathdup = strdupa(path);
+ dlen = strlen(pathdup);
+ if (dlen > 0 && pathdup[dlen - 1] == '/')
+ pathdup[dlen - 1] = '\0';
+ }
+
+ /* Check if the filehandle is cached */
+ fh_cached = mnt3_check_cached_fh(ms, fh, host_addr_ip, is_write_op);
+ if (fh_cached) {
+ gf_msg_trace(GF_MNT, 0, "Found cached FH for %s", host_addr_ip);
+ auth_status_code = 0;
+ goto free_and_out;
+ }
+
+ /* Check if the IP is authorized */
+ auth_status_code = mnt3_auth_host(ms->auth_params, host_addr_ip, fh,
+ pathdup, is_write_op, &expitem);
+
+ gf_msg_debug(GF_MNT, 0, "access from IP %s is %s", host_addr_ip,
+ auth_status_code ? "denied" : "allowed");
+
+ if (auth_status_code != 0) {
+ /* If not, check if the FQDN is authorized */
+ host_addr_fqdn = gf_rev_dns_lookup(host_addr_ip);
+ auth_status_code = mnt3_auth_host(ms->auth_params, host_addr_fqdn, fh,
+ pathdup, is_write_op, &expitem);
+
+ gf_msg_debug(GF_MNT, 0, "access from FQDN %s is %s", host_addr_fqdn,
+ auth_status_code ? "denied" : "allowed");
+
+ if (auth_status_code == 0)
+ auth_host = host_addr_fqdn;
+ } else
+ auth_host = host_addr_ip;
+
+ /* Skip the lines that set authorized export &
+ * host if they are null.
+ */
+ if (!authorized_export || !authorized_host) {
+ /* Cache the file handle if it was authorized */
+ if (fh && auth_status_code == 0)
+ cache_nfs_fh(ms->authcache, fh, host_addr_ip, expitem);
+
+ goto free_and_out;
+ }
+
+ if (!fh && auth_status_code == 0) {
+ *authorized_export = gf_strdup(pathdup);
+ if (!*authorized_export)
+ gf_msg(GF_MNT, GF_LOG_CRITICAL, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Allocation error when copying "
+ "authorized path");
+
+ *authorized_host = gf_strdup(auth_host);
+ if (!*authorized_host)
+ gf_msg(GF_MNT, GF_LOG_CRITICAL, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Allocation error when copying "
+ "authorized host");
+ }
free_and_out:
- /* Free allocated strings after doing the auth */
- GF_FREE (peer_addr);
- GF_FREE (host_addr_fqdn);
- GF_FREE (host_addr_ip);
+ /* Free allocated strings after doing the auth */
+ GF_FREE(peer_addr);
+ GF_FREE(host_addr_fqdn);
+ GF_FREE(host_addr_ip);
out:
- return auth_status_code;
+ return auth_status_code;
}
/**
@@ -2114,827 +2117,810 @@ out:
* -EROFS for unauthorized write operations (rm, mkdir, write)
*/
int
-mnt3_authenticate_request (struct mount3_state *ms, rpcsvc_request_t *req,
- struct nfs3_fh *fh, const char *volname,
- const char *path, char **authorized_path,
- char **authorized_host, gf_boolean_t is_write_op)
+mnt3_authenticate_request(struct mount3_state *ms, rpcsvc_request_t *req,
+ struct nfs3_fh *fh, const char *volname,
+ const char *path, char **authorized_path,
+ char **authorized_host, gf_boolean_t is_write_op)
{
- int auth_status_code = -EACCES;
- char *parent_path = NULL;
- const char *parent_old = NULL;
-
- GF_VALIDATE_OR_GOTO (GF_MNT, ms, out);
- GF_VALIDATE_OR_GOTO (GF_MNT, req, out);
-
- /* If this option is not set, just allow it through */
- if (!ms->nfs->exports_auth) {
- /* This function is called in a variety of use-cases (mount
- * + each fop) so path/authorized_path are not always present.
- * For the cases which it _is_ present we need to populate the
- * authorized_path. */
- if (path && authorized_path)
- *authorized_path = gf_strdup (path);
-
- auth_status_code = 0;
- goto out;
- }
-
- /* First check if the path is allowed */
- auth_status_code = _mnt3_authenticate_req (ms, req, fh, path,
- authorized_path,
- authorized_host,
- is_write_op);
-
- /* If the filehandle is set, just exit since we have to make only
- * one call to the function above
- */
- if (fh)
- goto out;
-
- parent_old = path;
- while (auth_status_code != 0) {
- /* Get the path's parent */
- parent_path = gf_resolve_path_parent (parent_old);
- if (!parent_path) /* Nothing left in the path to resolve */
- goto out;
-
- /* Authenticate it */
- auth_status_code = _mnt3_authenticate_req (ms, req, fh,
- parent_path,
- authorized_path,
- authorized_host,
- is_write_op);
-
- parent_old = strdupa (parent_path); /* Copy the parent onto the
- * stack.
- */
-
- GF_FREE (parent_path); /* Free the allocated parent string */
- }
+ int auth_status_code = -EACCES;
+ char *parent_path = NULL;
+ const char *parent_old = NULL;
+
+ GF_VALIDATE_OR_GOTO(GF_MNT, ms, out);
+ GF_VALIDATE_OR_GOTO(GF_MNT, req, out);
+
+ /* If this option is not set, just allow it through */
+ if (!ms->nfs->exports_auth) {
+ /* This function is called in a variety of use-cases (mount
+ * + each fop) so path/authorized_path are not always present.
+ * For the cases which it _is_ present we need to populate the
+ * authorized_path. */
+ if (path && authorized_path)
+ *authorized_path = gf_strdup(path);
+
+ auth_status_code = 0;
+ goto out;
+ }
+
+ /* First check if the path is allowed */
+ auth_status_code = _mnt3_authenticate_req(
+ ms, req, fh, path, authorized_path, authorized_host, is_write_op);
+
+ /* If the filehandle is set, just exit since we have to make only
+ * one call to the function above
+ */
+ if (fh)
+ goto out;
+
+ parent_old = path;
+ while (auth_status_code != 0) {
+ /* Get the path's parent */
+ parent_path = gf_resolve_path_parent(parent_old);
+ if (!parent_path) /* Nothing left in the path to resolve */
+ goto out;
+
+ /* Authenticate it */
+ auth_status_code = _mnt3_authenticate_req(ms, req, fh, parent_path,
+ authorized_path,
+ authorized_host, is_write_op);
+
+ parent_old = strdupa(parent_path); /* Copy the parent onto the
+ * stack.
+ */
+
+ GF_FREE(parent_path); /* Free the allocated parent string */
+ }
out:
- return auth_status_code;
+ return auth_status_code;
}
int
-mnt3svc_mnt (rpcsvc_request_t *req)
+mnt3svc_mnt(rpcsvc_request_t *req)
{
- struct iovec pvec = {0, };
- char path[MNTPATHLEN];
- int ret = -1;
- struct mount3_state *ms = NULL;
- mountstat3 mntstat = MNT3ERR_SERVERFAULT;
- struct mnt3_export *exp = NULL;
- struct nfs_state *nfs = NULL;
- int authcode = 0;
-
- if (!req)
- return -1;
-
- pvec.iov_base = path;
- pvec.iov_len = MNTPATHLEN;
- ret = xdr_to_mountpath (pvec, req->msg[0]);
- if (ret == -1) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ARGS_DECODE_ERROR,
- "Failed to decode args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_NOT_FOUND,
- "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- ret = -1;
- goto rpcerr;
- }
-
- nfs = (struct nfs_state *)ms->nfsx->private;
- gf_msg_debug (GF_MNT, 0, "dirpath: %s", path);
- ret = mnt3_find_export (req, path, &exp);
- if (ret < 0) {
- mntstat = mnt3svc_errno_to_mnterr (-ret);
- goto mnterr;
- } else if (!exp) {
- /*
- * SPECIAL CASE: exp is NULL if "path" is subdir in
- * call to mnt3_find_export().
- *
- * This is subdir mount, we are already DONE!
- * nfs_subvolume_started() and mnt3_check_client_net_tcp()
- * validation are done in mnt3_parse_dir_exports()
- * which is invoked through mnt3_find_export().
- *
- * TODO: All mount should happen thorugh mnt3svc_mount()
- * It needs more clean up.
- */
- return (0);
- }
-
- if (!nfs_subvolume_started (nfs, exp->vol)) {
- gf_msg_debug (GF_MNT, 0, "Volume %s not started",
- exp->vol->name);
- ret = -1;
- mntstat = MNT3ERR_NOENT;
- goto mnterr;
- }
-
- ret = mnt3_check_client_net_tcp (req, exp->vol->name);
- if (ret == RPCSVC_AUTH_REJECT) {
- mntstat = MNT3ERR_ACCES;
- gf_msg_debug (GF_MNT, 0, "Client mount not allowed");
- ret = -1;
- goto mnterr;
- }
+ struct iovec pvec = {
+ 0,
+ };
+ char path[MNTPATHLEN];
+ int ret = -1;
+ struct mount3_state *ms = NULL;
+ mountstat3 mntstat = MNT3ERR_SERVERFAULT;
+ struct mnt3_export *exp = NULL;
+ struct nfs_state *nfs = NULL;
+ int authcode = 0;
+
+ if (!req)
+ return -1;
- /* The second authentication check is the exports/netgroups
- * check.
+ pvec.iov_base = path;
+ pvec.iov_len = MNTPATHLEN;
+ ret = xdr_to_mountpath(pvec, req->msg[0]);
+ if (ret == -1) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ARGS_DECODE_ERROR,
+ "Failed to decode args");
+ rpcsvc_request_seterr(req, GARBAGE_ARGS);
+ goto rpcerr;
+ }
+
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_NOT_FOUND,
+ "Mount state not present");
+ rpcsvc_request_seterr(req, SYSTEM_ERR);
+ ret = -1;
+ goto rpcerr;
+ }
+
+ nfs = (struct nfs_state *)ms->nfsx->private;
+ gf_msg_debug(GF_MNT, 0, "dirpath: %s", path);
+ ret = mnt3_find_export(req, path, &exp);
+ if (ret < 0) {
+ mntstat = mnt3svc_errno_to_mnterr(-ret);
+ goto mnterr;
+ } else if (!exp) {
+ /*
+ * SPECIAL CASE: exp is NULL if "path" is subdir in
+ * call to mnt3_find_export().
+ *
+ * This is subdir mount, we are already DONE!
+ * nfs_subvolume_started() and mnt3_check_client_net_tcp()
+ * validation are done in mnt3_parse_dir_exports()
+ * which is invoked through mnt3_find_export().
+ *
+ * TODO: All mount should happen thorugh mnt3svc_mount()
+ * It needs more clean up.
*/
- authcode = mnt3_authenticate_request (ms, req, NULL, NULL, path, NULL,
- NULL, _gf_false);
- if (authcode != 0) {
- mntstat = MNT3ERR_ACCES;
- gf_msg_debug (GF_MNT, 0, "Client mount not allowed");
- ret = -1;
- goto mnterr;
- }
-
- ret = mnt3svc_mount (req, ms, exp);
-
- if (ret < 0)
- mntstat = mnt3svc_errno_to_mnterr (-ret);
+ return (0);
+ }
+
+ if (!nfs_subvolume_started(nfs, exp->vol)) {
+ gf_msg_debug(GF_MNT, 0, "Volume %s not started", exp->vol->name);
+ ret = -1;
+ mntstat = MNT3ERR_NOENT;
+ goto mnterr;
+ }
+
+ ret = mnt3_check_client_net_tcp(req, exp->vol->name);
+ if (ret == RPCSVC_AUTH_REJECT) {
+ mntstat = MNT3ERR_ACCES;
+ gf_msg_debug(GF_MNT, 0, "Client mount not allowed");
+ ret = -1;
+ goto mnterr;
+ }
+
+ /* The second authentication check is the exports/netgroups
+ * check.
+ */
+ authcode = mnt3_authenticate_request(ms, req, NULL, NULL, path, NULL, NULL,
+ _gf_false);
+ if (authcode != 0) {
+ mntstat = MNT3ERR_ACCES;
+ gf_msg_debug(GF_MNT, 0, "Client mount not allowed");
+ ret = -1;
+ goto mnterr;
+ }
+
+ ret = mnt3svc_mount(req, ms, exp);
+
+ if (ret < 0)
+ mntstat = mnt3svc_errno_to_mnterr(-ret);
mnterr:
- if (ret < 0) {
- mnt3svc_mnt_error_reply (req, mntstat);
- ret = 0;
- }
+ if (ret < 0) {
+ mnt3svc_mnt_error_reply(req, mntstat);
+ ret = 0;
+ }
rpcerr:
- return ret;
+ return ret;
}
-
int
-mnt3svc_null (rpcsvc_request_t *req)
+mnt3svc_null(rpcsvc_request_t *req)
{
- struct iovec dummyvec = {0, };
+ struct iovec dummyvec = {
+ 0,
+ };
- if (!req) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
- "Got NULL request!");
- return 0;
- }
- rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL);
+ if (!req) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
+ "Got NULL request!");
return 0;
+ }
+ rpcsvc_submit_generic(req, &dummyvec, 1, NULL, 0, NULL);
+ return 0;
}
-
mountlist
-__build_mountlist (struct mount3_state *ms, int *count)
+__build_mountlist(struct mount3_state *ms, int *count)
{
- struct mountbody *mlist = NULL;
- struct mountbody *prev = NULL;
- struct mountbody *first = NULL;
- size_t namelen = 0;
- int ret = -1;
- struct mountentry *me = NULL;
-
- if ((!ms) || (!count))
- return NULL;
-
- /* read rmtab, other peers might have updated it */
- mount_read_rmtab(ms);
-
- *count = 0;
- gf_msg_debug (GF_MNT, 0, "Building mount list:");
- list_for_each_entry (me, &ms->mountlist, mlist) {
- namelen = strlen (me->exname);
- mlist = GF_CALLOC (1, sizeof (*mlist), gf_nfs_mt_mountbody);
- if (!mlist) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory allocation failed");
- goto free_list;
- }
- if (!first)
- first = mlist;
-
- mlist->ml_directory = GF_MALLOC (namelen + 2,
- gf_nfs_mt_char);
- if (!mlist->ml_directory) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory allocation failed");
- goto free_list;
- }
+ struct mountbody *mlist = NULL;
+ struct mountbody *prev = NULL;
+ struct mountbody *first = NULL;
+ size_t namelen = 0;
+ int ret = -1;
+ struct mountentry *me = NULL;
+
+ if ((!ms) || (!count))
+ return NULL;
- strcpy (mlist->ml_directory, me->exname);
+ /* read rmtab, other peers might have updated it */
+ mount_read_rmtab(ms);
- namelen = strlen (me->hostname);
- mlist->ml_hostname = GF_MALLOC (namelen + 2,
- gf_nfs_mt_char);
- if (!mlist->ml_hostname) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory allocation failed");
- goto free_list;
- }
+ *count = 0;
+ gf_msg_debug(GF_MNT, 0, "Building mount list:");
+ list_for_each_entry(me, &ms->mountlist, mlist)
+ {
+ namelen = strlen(me->exname);
+ mlist = GF_CALLOC(1, sizeof(*mlist), gf_nfs_mt_mountbody);
+ if (!mlist) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto free_list;
+ }
+ if (!first)
+ first = mlist;
- strcat (mlist->ml_hostname, me->hostname);
+ mlist->ml_directory = GF_MALLOC(namelen + 2, gf_nfs_mt_char);
+ if (!mlist->ml_directory) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto free_list;
+ }
- gf_msg_debug (GF_MNT, 0, "mount entry: dir: %s, host: %s",
- mlist->ml_directory, mlist->ml_hostname);
- if (prev) {
- prev->ml_next = mlist;
- prev = mlist;
- } else
- prev = mlist;
+ strcpy(mlist->ml_directory, me->exname);
- (*count)++;
+ namelen = strlen(me->hostname);
+ mlist->ml_hostname = GF_MALLOC(namelen + 2, gf_nfs_mt_char);
+ if (!mlist->ml_hostname) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto free_list;
}
- ret = 0;
+ strcat(mlist->ml_hostname, me->hostname);
+
+ gf_msg_debug(GF_MNT, 0, "mount entry: dir: %s, host: %s",
+ mlist->ml_directory, mlist->ml_hostname);
+ if (prev) {
+ prev->ml_next = mlist;
+ prev = mlist;
+ } else
+ prev = mlist;
+
+ (*count)++;
+ }
+
+ ret = 0;
free_list:
- if (ret == -1) {
- xdr_free_mountlist (first);
- first = NULL;
- }
+ if (ret == -1) {
+ xdr_free_mountlist(first);
+ first = NULL;
+ }
- return first;
+ return first;
}
-
mountlist
-mnt3svc_build_mountlist (struct mount3_state *ms, int *count)
+mnt3svc_build_mountlist(struct mount3_state *ms, int *count)
{
- struct mountbody *first = NULL;
+ struct mountbody *first = NULL;
- LOCK (&ms->mountlock);
- {
- first = __build_mountlist (ms, count);
- }
- UNLOCK (&ms->mountlock);
+ LOCK(&ms->mountlock);
+ {
+ first = __build_mountlist(ms, count);
+ }
+ UNLOCK(&ms->mountlock);
- return first;
+ return first;
}
-
int
-mnt3svc_dump (rpcsvc_request_t *req)
+mnt3svc_dump(rpcsvc_request_t *req)
{
- int ret = -1;
- struct mount3_state *ms = NULL;
- mountlist mlist;
- mountstat3 mstat = 0;
- mnt3_serializer sfunc = NULL;
- void *arg = NULL;
-
-
- if (!req)
- return -1;
+ int ret = -1;
+ struct mount3_state *ms = NULL;
+ mountlist mlist;
+ mountstat3 mstat = 0;
+ mnt3_serializer sfunc = NULL;
+ void *arg = NULL;
+
+ if (!req)
+ return -1;
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto rpcerr;
- }
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ rpcsvc_request_seterr(req, SYSTEM_ERR);
+ goto rpcerr;
+ }
- sfunc = (mnt3_serializer)xdr_serialize_mountlist;
- mlist = mnt3svc_build_mountlist (ms, &ret);
- arg = &mlist;
+ sfunc = (mnt3_serializer)xdr_serialize_mountlist;
+ mlist = mnt3svc_build_mountlist(ms, &ret);
+ arg = &mlist;
- if (!mlist) {
- if (ret != 0) {
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- ret = -1;
- goto rpcerr;
- } else {
- arg = &mstat;
- sfunc = (mnt3_serializer)xdr_serialize_mountstat3;
- }
+ if (!mlist) {
+ if (ret != 0) {
+ rpcsvc_request_seterr(req, SYSTEM_ERR);
+ ret = -1;
+ goto rpcerr;
+ } else {
+ arg = &mstat;
+ sfunc = (mnt3_serializer)xdr_serialize_mountstat3;
}
+ }
- mnt3svc_submit_reply (req, arg, sfunc);
+ mnt3svc_submit_reply(req, arg, sfunc);
- xdr_free_mountlist (mlist);
- ret = 0;
+ xdr_free_mountlist(mlist);
+ ret = 0;
rpcerr:
- return ret;
+ return ret;
}
-
int
-mnt3svc_umount (struct mount3_state *ms, char *dirpath, char *hostname)
+mnt3svc_umount(struct mount3_state *ms, char *dirpath, char *hostname)
{
- struct mountentry *me = NULL;
- int ret = -1;
- gf_store_handle_t *sh = NULL;
- struct nfs_state *nfs = NULL;
- gf_boolean_t update_rmtab = _gf_false;
-
- if ((!ms) || (!dirpath) || (!hostname))
- return -1;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
-
- update_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
- if (update_rmtab) {
- ret = gf_store_lock (sh);
- if (ret)
- goto out_free;
- }
-
- LOCK (&ms->mountlock);
- {
- if (update_rmtab)
- __mount_read_rmtab (sh, &ms->mountlist, _gf_false);
+ struct mountentry *me = NULL;
+ int ret = -1;
+ gf_store_handle_t *sh = NULL;
+ struct nfs_state *nfs = NULL;
+ gf_boolean_t update_rmtab = _gf_false;
- if (list_empty (&ms->mountlist)) {
- ret = 0;
- goto out_unlock;
- }
+ if ((!ms) || (!dirpath) || (!hostname))
+ return -1;
- ret = -1;
- list_for_each_entry (me, &ms->mountlist, mlist) {
- if ((strcmp (me->exname, dirpath) == 0) &&
- (strcmp (me->hostname, hostname) == 0)) {
- ret = 0;
- break;
- }
- }
+ nfs = (struct nfs_state *)ms->nfsx->private;
- /* Need this check here because at the end of the search me
- * might still be pointing to the last entry, which may not be
- * the one we're looking for.
- */
- if (ret == -1) {/* Not found in list. */
- gf_msg_trace (GF_MNT, 0, "Export not found");
- goto out_unlock;
- }
+ update_rmtab = mount_open_rmtab(nfs->rmtab, &sh);
+ if (update_rmtab) {
+ ret = gf_store_lock(sh);
+ if (ret)
+ goto out_free;
+ }
- if (!me)
- goto out_unlock;
+ LOCK(&ms->mountlock);
+ {
+ if (update_rmtab)
+ __mount_read_rmtab(sh, &ms->mountlist, _gf_false);
- gf_msg_debug (GF_MNT, 0, "Unmounting: dir %s, host: %s",
- me->exname, me->hostname);
+ if (list_empty(&ms->mountlist)) {
+ ret = 0;
+ goto out_unlock;
+ }
- list_del (&me->mlist);
- GF_FREE (me);
+ ret = -1;
+ list_for_each_entry(me, &ms->mountlist, mlist)
+ {
+ if ((strcmp(me->exname, dirpath) == 0) &&
+ (strcmp(me->hostname, hostname) == 0)) {
+ ret = 0;
+ break;
+ }
+ }
- if (update_rmtab)
- __mount_rewrite_rmtab (ms, sh);
+ /* Need this check here because at the end of the search me
+ * might still be pointing to the last entry, which may not be
+ * the one we're looking for.
+ */
+ if (ret == -1) { /* Not found in list. */
+ gf_msg_trace(GF_MNT, 0, "Export not found");
+ goto out_unlock;
}
-out_unlock:
- UNLOCK (&ms->mountlock);
+
+ if (!me)
+ goto out_unlock;
+
+ gf_msg_debug(GF_MNT, 0, "Unmounting: dir %s, host: %s", me->exname,
+ me->hostname);
+
+ list_del(&me->mlist);
+ GF_FREE(me);
if (update_rmtab)
- gf_store_unlock (sh);
+ __mount_rewrite_rmtab(ms, sh);
+ }
+out_unlock:
+ UNLOCK(&ms->mountlock);
+
+ if (update_rmtab)
+ gf_store_unlock(sh);
out_free:
- if (update_rmtab)
- gf_store_handle_destroy (sh);
+ if (update_rmtab)
+ gf_store_handle_destroy(sh);
- return ret;
+ return ret;
}
-
int
-mnt3svc_umnt (rpcsvc_request_t *req)
+mnt3svc_umnt(rpcsvc_request_t *req)
{
- char hostname[MNTPATHLEN];
- char dirpath[MNTPATHLEN];
- struct iovec pvec = {0, };
- int ret = -1;
- struct mount3_state *ms = NULL;
- mountstat3 mstat = MNT3_OK;
- char *colon = NULL;
-
- if (!req)
- return -1;
-
- /* Remove the mount point from the exports list. */
- pvec.iov_base = dirpath;
- pvec.iov_len = MNTPATHLEN;
- ret = xdr_to_mountpath (pvec, req->msg[0]);
- if (ret == -1) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ARGS_DECODE_ERROR,
- "Failed decode args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_NOT_FOUND, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- ret = -1;
- goto rpcerr;
- }
-
- ret = rpcsvc_transport_peername (req->trans, hostname, MNTPATHLEN);
- if (ret != 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOENT,
- NFS_MSG_GET_REMOTE_NAME_FAIL,
- "Failed to get remote name: %s", gai_strerror (ret));
- goto rpcerr;
- }
+ char hostname[MNTPATHLEN];
+ char dirpath[MNTPATHLEN];
+ struct iovec pvec = {
+ 0,
+ };
+ int ret = -1;
+ struct mount3_state *ms = NULL;
+ mountstat3 mstat = MNT3_OK;
+ char *colon = NULL;
+
+ if (!req)
+ return -1;
- colon = strrchr (hostname, ':');
- if (colon) {
- *colon= '\0';
- }
- gf_path_strip_trailing_slashes (dirpath);
- gf_msg_debug (GF_MNT, 0, "dirpath: %s, hostname: %s", dirpath,
- hostname);
- ret = mnt3svc_umount (ms, dirpath, hostname);
+ /* Remove the mount point from the exports list. */
+ pvec.iov_base = dirpath;
+ pvec.iov_len = MNTPATHLEN;
+ ret = xdr_to_mountpath(pvec, req->msg[0]);
+ if (ret == -1) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ARGS_DECODE_ERROR,
+ "Failed decode args");
+ rpcsvc_request_seterr(req, GARBAGE_ARGS);
+ goto rpcerr;
+ }
+
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_NOT_FOUND,
+ "Mount state not present");
+ rpcsvc_request_seterr(req, SYSTEM_ERR);
+ ret = -1;
+ goto rpcerr;
+ }
+
+ ret = rpcsvc_transport_peername(req->trans, hostname, MNTPATHLEN);
+ if (ret != 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOENT, NFS_MSG_GET_REMOTE_NAME_FAIL,
+ "Failed to get remote name: %s", gai_strerror(ret));
+ goto rpcerr;
+ }
+
+ colon = strrchr(hostname, ':');
+ if (colon) {
+ *colon = '\0';
+ }
+ gf_path_strip_trailing_slashes(dirpath);
+ gf_msg_debug(GF_MNT, 0, "dirpath: %s, hostname: %s", dirpath, hostname);
+ ret = mnt3svc_umount(ms, dirpath, hostname);
- if (ret == -1) {
- ret = 0;
- mstat = MNT3ERR_NOENT;
- }
- /* FIXME: also take care of the corner case where the
- * client was resolvable at mount but not at the umount - vice-versa.
- */
- mnt3svc_submit_reply (req, &mstat,
- (mnt3_serializer)xdr_serialize_mountstat3);
+ if (ret == -1) {
+ ret = 0;
+ mstat = MNT3ERR_NOENT;
+ }
+ /* FIXME: also take care of the corner case where the
+ * client was resolvable at mount but not at the umount - vice-versa.
+ */
+ mnt3svc_submit_reply(req, &mstat,
+ (mnt3_serializer)xdr_serialize_mountstat3);
rpcerr:
- return ret;
+ return ret;
}
-
int
-__mnt3svc_umountall (struct mount3_state *ms)
+__mnt3svc_umountall(struct mount3_state *ms)
{
- struct mountentry *me = NULL;
- struct mountentry *tmp = NULL;
+ struct mountentry *me = NULL;
+ struct mountentry *tmp = NULL;
- if (!ms)
- return -1;
+ if (!ms)
+ return -1;
- if (list_empty (&ms->mountlist))
- return 0;
+ if (list_empty(&ms->mountlist))
+ return 0;
- list_for_each_entry_safe (me, tmp, &ms->mountlist, mlist) {
- list_del (&me->mlist); /* Remove from the mount list */
- __mountdict_remove (ms, me); /* Remove from the mount dict */
- GF_FREE (me);
- }
+ list_for_each_entry_safe(me, tmp, &ms->mountlist, mlist)
+ {
+ list_del(&me->mlist); /* Remove from the mount list */
+ __mountdict_remove(ms, me); /* Remove from the mount dict */
+ GF_FREE(me);
+ }
- return 0;
+ return 0;
}
-
int
-mnt3svc_umountall (struct mount3_state *ms)
+mnt3svc_umountall(struct mount3_state *ms)
{
- int ret = -1;
- if (!ms)
- return -1;
+ int ret = -1;
+ if (!ms)
+ return -1;
- LOCK (&ms->mountlock);
- {
- ret = __mnt3svc_umountall (ms);
- }
- UNLOCK (&ms->mountlock);
+ LOCK(&ms->mountlock);
+ {
+ ret = __mnt3svc_umountall(ms);
+ }
+ UNLOCK(&ms->mountlock);
- return ret;
+ return ret;
}
-
int
-mnt3svc_umntall (rpcsvc_request_t *req)
+mnt3svc_umntall(rpcsvc_request_t *req)
{
- int ret = RPCSVC_ACTOR_ERROR;
- struct mount3_state *ms = NULL;
- mountstat3 mstat = MNT3_OK;
-
- if (!req)
- return ret;
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_NOT_FOUND, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto rpcerr;
- }
+ int ret = RPCSVC_ACTOR_ERROR;
+ struct mount3_state *ms = NULL;
+ mountstat3 mstat = MNT3_OK;
+
+ if (!req)
+ return ret;
+
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_NOT_FOUND,
+ "Mount state not present");
+ rpcsvc_request_seterr(req, SYSTEM_ERR);
+ goto rpcerr;
+ }
- mnt3svc_umountall (ms);
- mnt3svc_submit_reply (req, &mstat,
- (mnt3_serializer)xdr_serialize_mountstat3);
+ mnt3svc_umountall(ms);
+ mnt3svc_submit_reply(req, &mstat,
+ (mnt3_serializer)xdr_serialize_mountstat3);
- ret = RPCSVC_ACTOR_SUCCESS;
+ ret = RPCSVC_ACTOR_SUCCESS;
rpcerr:
- return ret;
+ return ret;
}
-
exports
-mnt3_xlchildren_to_exports (rpcsvc_t *svc, struct mount3_state *ms)
+mnt3_xlchildren_to_exports(rpcsvc_t *svc, struct mount3_state *ms)
{
- struct exportnode *elist = NULL;
- struct exportnode *prev = NULL;
- struct exportnode *first = NULL;
- size_t namelen = 0;
- int ret = -1;
- char *addrstr = NULL;
- struct mnt3_export *ent = NULL;
- struct nfs_state *nfs = NULL;
-
- if ((!ms) || (!svc))
- return NULL;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
- if (!nfs)
- return NULL;
-
- LOCK (&ms->mountlock);
- list_for_each_entry(ent, &ms->exportlist, explist) {
-
- /* If volume is not started yet, do not list it for tools like
- * showmount.
- */
- if (!nfs_subvolume_started (nfs, ent->vol))
- continue;
-
- elist = GF_CALLOC (1, sizeof (*elist), gf_nfs_mt_exportnode);
- if (!elist) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory allocation failed");
- goto free_list;
- }
- if (!first)
- first = elist;
- namelen = strlen (ent->expname);
- elist->ex_dir = GF_MALLOC (namelen + 2,
- gf_nfs_mt_char);
- if (!elist->ex_dir) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory allocation failed");
- goto free_list;
+ struct exportnode *elist = NULL;
+ struct exportnode *prev = NULL;
+ struct exportnode *first = NULL;
+ size_t namelen = 0;
+ int ret = -1;
+ char *addrstr = NULL;
+ struct mnt3_export *ent = NULL;
+ struct nfs_state *nfs = NULL;
+
+ if ((!ms) || (!svc))
+ return NULL;
+
+ nfs = (struct nfs_state *)ms->nfsx->private;
+ if (!nfs)
+ return NULL;
+
+ LOCK(&ms->mountlock);
+ list_for_each_entry(ent, &ms->exportlist, explist)
+ {
+ /* If volume is not started yet, do not list it for tools like
+ * showmount.
+ */
+ if (!nfs_subvolume_started(nfs, ent->vol))
+ continue;
+
+ elist = GF_CALLOC(1, sizeof(*elist), gf_nfs_mt_exportnode);
+ if (!elist) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto free_list;
+ }
+ if (!first)
+ first = elist;
+ namelen = strlen(ent->expname);
+ elist->ex_dir = GF_MALLOC(namelen + 2, gf_nfs_mt_char);
+ if (!elist->ex_dir) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto free_list;
+ }
+ strcpy(elist->ex_dir, ent->expname);
+
+ addrstr = rpcsvc_volume_allowed(svc->options, ent->vol->name);
+ if (addrstr) {
+ /* create a groupnode per allowed client */
+ char *pos = NULL;
+ char *addr = NULL;
+ char *addrs = NULL;
+ struct groupnode *group = NULL;
+ struct groupnode *prev_group = NULL;
+
+ /* strtok_r() modifies the string, dup it */
+ addrs = gf_strdup(addrstr);
+ if (!addrs)
+ goto free_list;
+
+ while (1) {
+ /* only pass addrs on the 1st call */
+ addr = strtok_r(group ? NULL : addrs, ",", &pos);
+ if (addr == NULL)
+ /* no mode clients */
+ break;
+
+ group = GF_CALLOC(1, sizeof(struct groupnode),
+ gf_nfs_mt_groupnode);
+ if (!group) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory "
+ "allocation failed");
+ GF_FREE(addrs);
+ goto free_list;
}
- strcpy (elist->ex_dir, ent->expname);
-
- addrstr = rpcsvc_volume_allowed (svc->options, ent->vol->name);
- if (addrstr) {
- /* create a groupnode per allowed client */
- char *pos = NULL;
- char *addr = NULL;
- char *addrs = NULL;
- struct groupnode *group = NULL;
- struct groupnode *prev_group = NULL;
-
- /* strtok_r() modifies the string, dup it */
- addrs = gf_strdup (addrstr);
- if (!addrs)
- goto free_list;
-
- while (1) {
- /* only pass addrs on the 1st call */
- addr = strtok_r (group ? NULL : addrs, ",",
- &pos);
- if (addr == NULL)
- /* no mode clients */
- break;
-
- group = GF_CALLOC (1, sizeof (struct groupnode),
- gf_nfs_mt_groupnode);
- if (!group) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory "
- "allocation failed");
- GF_FREE (addrs);
- goto free_list;
- }
-
- group->gr_name = gf_strdup (addr);
- if (!group->gr_name) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory "
- "allocation failed");
- GF_FREE (group);
- GF_FREE (addrs);
- goto free_list;
- }
-
- /* chain the groups together */
- if (!elist->ex_groups)
- elist->ex_groups = group;
- else if (!prev_group->gr_next)
- prev_group->gr_next = group;
- prev_group = group;
- }
-
- GF_FREE (addrs);
- } else {
- elist->ex_groups = GF_CALLOC (1,
- sizeof (struct groupnode),
- gf_nfs_mt_groupnode);
- if (!elist->ex_groups) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY, "Memory allocation "
- "failed");
- goto free_list;
- }
-
- addrstr = gf_strdup ("No Access");
- if (!addrstr)
- goto free_list;
-
- elist->ex_groups->gr_name = addrstr;
+
+ group->gr_name = gf_strdup(addr);
+ if (!group->gr_name) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory "
+ "allocation failed");
+ GF_FREE(group);
+ GF_FREE(addrs);
+ goto free_list;
}
- if (prev) {
- prev->ex_next = elist;
- prev = elist;
- } else
- prev = elist;
+ /* chain the groups together */
+ if (!elist->ex_groups)
+ elist->ex_groups = group;
+ else if (!prev_group->gr_next)
+ prev_group->gr_next = group;
+ prev_group = group;
+ }
+
+ GF_FREE(addrs);
+ } else {
+ elist->ex_groups = GF_CALLOC(1, sizeof(struct groupnode),
+ gf_nfs_mt_groupnode);
+ if (!elist->ex_groups) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation "
+ "failed");
+ goto free_list;
+ }
+
+ addrstr = gf_strdup("No Access");
+ if (!addrstr)
+ goto free_list;
+
+ elist->ex_groups->gr_name = addrstr;
}
- ret = 0;
+ if (prev) {
+ prev->ex_next = elist;
+ prev = elist;
+ } else
+ prev = elist;
+ }
+
+ ret = 0;
free_list:
- UNLOCK (&ms->mountlock);
- if (ret == -1) {
- xdr_free_exports_list (first);
- first = NULL;
- }
+ UNLOCK(&ms->mountlock);
+ if (ret == -1) {
+ xdr_free_exports_list(first);
+ first = NULL;
+ }
- return first;
+ return first;
}
-
int
-mnt3svc_export (rpcsvc_request_t *req)
+mnt3svc_export(rpcsvc_request_t *req)
{
- struct mount3_state *ms = NULL;
- exports elist = NULL;
- int ret = -1;
-
- if (!req)
- return -1;
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_NOT_FOUND, "mount state not found");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto err;
- }
+ struct mount3_state *ms = NULL;
+ exports elist = NULL;
+ int ret = -1;
- /* Using the children translator names, build the export list */
- elist = mnt3_xlchildren_to_exports (rpcsvc_request_service (req),
- ms);
- /* Do not return error when exports list is empty. An exports list can
- * be empty when no subvolumes have come up. No point returning error
- * and confusing the user.
- if (!elist) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to build exports list");
- nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto err;
- }
- */
-
- /* Note how the serializer is passed to the generic reply function. */
- mnt3svc_submit_reply (req, &elist,
- (mnt3_serializer)xdr_serialize_exports);
+ if (!req)
+ return -1;
- xdr_free_exports_list (elist);
- ret = 0;
+ ms = (struct mount3_state *)rpcsvc_request_program_private(req);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_NOT_FOUND,
+ "mount state not found");
+ rpcsvc_request_seterr(req, SYSTEM_ERR);
+ goto err;
+ }
+
+ /* Using the children translator names, build the export list */
+ elist = mnt3_xlchildren_to_exports(rpcsvc_request_service(req), ms);
+ /* Do not return error when exports list is empty. An exports list can
+ * be empty when no subvolumes have come up. No point returning error
+ * and confusing the user.
+ if (!elist) {
+ gf_log (GF_MNT, GF_LOG_ERROR, "Failed to build exports list");
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
+ goto err;
+ }
+ */
+
+ /* Note how the serializer is passed to the generic reply function. */
+ mnt3svc_submit_reply(req, &elist, (mnt3_serializer)xdr_serialize_exports);
+
+ xdr_free_exports_list(elist);
+ ret = 0;
err:
- return ret;
+ return ret;
}
-
/*
* __mnt3udp_get_mstate() Fetches mount3_state from xlator
* Linkage: Static
* Usage: Used only for UDP MOUNT codepath
*/
static struct mount3_state *
-__mnt3udp_get_mstate (xlator_t *nfsx)
+__mnt3udp_get_mstate(xlator_t *nfsx)
{
- struct nfs_state *nfs = NULL;
- struct mount3_state *ms = NULL;
+ struct nfs_state *nfs = NULL;
+ struct mount3_state *ms = NULL;
- if (nfsx == NULL)
- return NULL;
+ if (nfsx == NULL)
+ return NULL;
- nfs = (struct nfs_state *)nfsx->private;
- if (nfs == NULL)
- return NULL;
+ nfs = (struct nfs_state *)nfsx->private;
+ if (nfs == NULL)
+ return NULL;
- ms = (struct mount3_state *)nfs->mstate;
- return ms;
+ ms = (struct mount3_state *)nfs->mstate;
+ return ms;
}
extern int
-glfs_resolve_at (struct glfs *, xlator_t *, inode_t *,
- const char *, loc_t *, struct iatt *, int, int);
+glfs_resolve_at(struct glfs *, xlator_t *, inode_t *, const char *, loc_t *,
+ struct iatt *, int, int);
extern struct glfs *
-glfs_new_from_ctx (glusterfs_ctx_t *);
+glfs_new_from_ctx(glusterfs_ctx_t *);
extern void
-glfs_free_from_ctx (struct glfs *);
+glfs_free_from_ctx(struct glfs *);
static inode_t *
-__mnt3udp_get_export_subdir_inode (struct svc_req *req, char *subdir,
- char *expname, /* OUT */
- struct mnt3_export *exp)
+__mnt3udp_get_export_subdir_inode(struct svc_req *req, char *subdir,
+ char *expname, /* OUT */
+ struct mnt3_export *exp)
{
- inode_t *inode = NULL;
- loc_t loc = {0, };
- struct iatt buf = {0, };
- int ret = -1;
- glfs_t *fs = NULL;
-
- if ((!req) || (!subdir) || (!expname) || (!exp))
- return NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt buf = {
+ 0,
+ };
+ int ret = -1;
+ glfs_t *fs = NULL;
+
+ if ((!req) || (!subdir) || (!expname) || (!exp))
+ return NULL;
- /* AUTH check for subdir i.e. nfs.export-dir */
- if (exp->hostspec) {
- struct sockaddr_in *sin = NULL;
+ /* AUTH check for subdir i.e. nfs.export-dir */
+ if (exp->hostspec) {
+ struct sockaddr_in *sin = NULL;
#if !defined(_TIRPC_SVC_H)
- sin = svc_getcaller (req->rq_xprt);
+ sin = svc_getcaller(req->rq_xprt);
#else
- sin = (struct sockaddr_in *)svc_getcaller (req->rq_xprt);
- /* TIRPC's svc_getcaller() returns a pointer to a
- * sockaddr_in6, even though it might actually be an
- * IPv4 address. It ought return a struct sockaddr and
- * make the caller upcast it to the proper address family.
- */
+ sin = (struct sockaddr_in *)svc_getcaller(req->rq_xprt);
+ /* TIRPC's svc_getcaller() returns a pointer to a
+ * sockaddr_in6, even though it might actually be an
+ * IPv4 address. It ought return a struct sockaddr and
+ * make the caller upcast it to the proper address family.
+ */
#endif
- /* And let's make sure that it's actually an IPv4 address. */
- GF_ASSERT (sin->sin_family == AF_INET);
-
- ret = mnt3_verify_auth (sin, exp);
- if (ret) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EACCES,
- NFS_MSG_AUTH_VERIFY_FAILED,
- "AUTH(nfs.export-dir) verification failed");
- errno = EACCES;
- return NULL;
- }
- }
+ /* And let's make sure that it's actually an IPv4 address. */
+ GF_ASSERT(sin->sin_family == AF_INET);
- /*
- * IMP: glfs_t fs object is not used by glfs_resolve_at (). The main
- * purpose is to not change the ABI of glfs_resolve_at () and not to
- * pass a NULL object.
- *
- * TODO: Instead of linking against libgfapi.so, just for one API
- * i.e. glfs_resolve_at(), It would be cleaner if PATH name to
- * inode resolution code can be moved to libglusterfs.so or so.
- * refer bugzilla for more details :
- * https://bugzilla.redhat.com/show_bug.cgi?id=1161573
- */
- fs = glfs_new_from_ctx (exp->vol->ctx);
- if (!fs)
- return NULL;
+ ret = mnt3_verify_auth(sin, exp);
+ if (ret) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EACCES, NFS_MSG_AUTH_VERIFY_FAILED,
+ "AUTH(nfs.export-dir) verification failed");
+ errno = EACCES;
+ return NULL;
+ }
+ }
+
+ /*
+ * IMP: glfs_t fs object is not used by glfs_resolve_at (). The main
+ * purpose is to not change the ABI of glfs_resolve_at () and not to
+ * pass a NULL object.
+ *
+ * TODO: Instead of linking against libgfapi.so, just for one API
+ * i.e. glfs_resolve_at(), It would be cleaner if PATH name to
+ * inode resolution code can be moved to libglusterfs.so or so.
+ * refer bugzilla for more details :
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1161573
+ */
+ fs = glfs_new_from_ctx(exp->vol->ctx);
+ if (!fs)
+ return NULL;
- ret = glfs_resolve_at (fs, exp->vol, NULL, subdir,
- &loc, &buf, 1 /* Follow link */,
- 0 /* Hard lookup */);
+ ret = glfs_resolve_at(fs, exp->vol, NULL, subdir, &loc, &buf,
+ 1 /* Follow link */, 0 /* Hard lookup */);
- glfs_free_from_ctx (fs);
+ glfs_free_from_ctx(fs);
- if (ret != 0) {
- loc_wipe (&loc);
- return NULL;
- }
+ if (ret != 0) {
+ loc_wipe(&loc);
+ return NULL;
+ }
- inode = inode_ref (loc.inode);
- snprintf (expname, PATH_MAX, "/%s%s", exp->vol->name, loc.path);
+ inode = inode_ref(loc.inode);
+ snprintf(expname, PATH_MAX, "/%s%s", exp->vol->name, loc.path);
- loc_wipe (&loc);
+ loc_wipe(&loc);
- return inode;
+ return inode;
}
static inode_t *
-__mnt3udp_get_export_volume_inode (struct svc_req *req, char *volpath,
- char *expname, /* OUT */
- struct mnt3_export *exp)
+__mnt3udp_get_export_volume_inode(struct svc_req *req, char *volpath,
+ char *expname, /* OUT */
+ struct mnt3_export *exp)
{
- char *rpath = NULL;
- inode_t *inode = NULL;
+ char *rpath = NULL;
+ inode_t *inode = NULL;
- if ((!req) || (!volpath) || (!expname) || (!exp))
- return NULL;
+ if ((!req) || (!volpath) || (!expname) || (!exp))
+ return NULL;
- rpath = strchr (volpath, '/');
- if (rpath == NULL)
- rpath = "/";
+ rpath = strchr(volpath, '/');
+ if (rpath == NULL)
+ rpath = "/";
- inode = inode_from_path (exp->vol->itable, rpath);
- snprintf (expname, PATH_MAX, "/%s", exp->vol->name);
+ inode = inode_from_path(exp->vol->itable, rpath);
+ snprintf(expname, PATH_MAX, "/%s", exp->vol->name);
- return inode;
+ return inode;
}
/*
@@ -2943,162 +2929,161 @@ __mnt3udp_get_export_volume_inode (struct svc_req *req, char *volpath,
* when nfs.mount-udp is ENABLED (set to TRUE/ON).
*/
struct nfs3_fh *
-nfs3_rootfh (struct svc_req *req, xlator_t *nfsx,
- char *path, char *expname /* OUT */)
+nfs3_rootfh(struct svc_req *req, xlator_t *nfsx, char *path,
+ char *expname /* OUT */)
{
- struct nfs3_fh *fh = NULL;
- inode_t *inode = NULL;
- struct mnt3_export *exp = NULL;
- struct mount3_state *ms = NULL;
- struct nfs_state *nfs = NULL;
- int mnt3type = MNT3_EXPTYPE_DIR;
- int ret = RPCSVC_AUTH_REJECT;
-
- if ((!req) || (!nfsx) || (!path) || (!expname)) {
- errno = EFAULT;
- return NULL;
- }
-
- /*
- * 1. First check if the MOUNT is for whole volume.
- * i.e. __mnt3udp_get_export_volume_inode ()
- * 2. If NOT, then TRY for SUBDIR MOUNT.
- * i.e. __mnt3udp_get_export_subdir_inode ()
- * 3. If a subdir is exported using nfs.export-dir,
- * then the mount type would be MNT3_EXPTYPE_DIR,
- * so make sure to find the proper path to be
- * resolved using mnt3_get_volume_subdir()
- * 3. Make sure subdir export is allowed.
- */
- ms = __mnt3udp_get_mstate(nfsx);
- if (!ms) {
- errno = EFAULT;
- return NULL;
- }
-
- exp = mnt3_mntpath_to_export (ms, path , _gf_false);
- if (exp != NULL)
- mnt3type = exp->exptype;
+ struct nfs3_fh *fh = NULL;
+ inode_t *inode = NULL;
+ struct mnt3_export *exp = NULL;
+ struct mount3_state *ms = NULL;
+ struct nfs_state *nfs = NULL;
+ int mnt3type = MNT3_EXPTYPE_DIR;
+ int ret = RPCSVC_AUTH_REJECT;
+
+ if ((!req) || (!nfsx) || (!path) || (!expname)) {
+ errno = EFAULT;
+ return NULL;
+ }
+
+ /*
+ * 1. First check if the MOUNT is for whole volume.
+ * i.e. __mnt3udp_get_export_volume_inode ()
+ * 2. If NOT, then TRY for SUBDIR MOUNT.
+ * i.e. __mnt3udp_get_export_subdir_inode ()
+ * 3. If a subdir is exported using nfs.export-dir,
+ * then the mount type would be MNT3_EXPTYPE_DIR,
+ * so make sure to find the proper path to be
+ * resolved using mnt3_get_volume_subdir()
+ * 3. Make sure subdir export is allowed.
+ */
+ ms = __mnt3udp_get_mstate(nfsx);
+ if (!ms) {
+ errno = EFAULT;
+ return NULL;
+ }
- if (mnt3type == MNT3_EXPTYPE_DIR) {
- char volname [MNTPATHLEN] = {0, };
- char *volptr = volname;
+ exp = mnt3_mntpath_to_export(ms, path, _gf_false);
+ if (exp != NULL)
+ mnt3type = exp->exptype;
- /* Subdir export (nfs3.export-dirs) check */
- if (!gf_mnt3_export_dirs(ms)) {
- errno = EACCES;
- return NULL;
- }
+ if (mnt3type == MNT3_EXPTYPE_DIR) {
+ char volname[MNTPATHLEN] = {
+ 0,
+ };
+ char *volptr = volname;
- path = mnt3_get_volume_subdir (path, &volptr);
- if (exp == NULL)
- exp = mnt3_mntpath_to_export (ms, volname , _gf_false);
+ /* Subdir export (nfs3.export-dirs) check */
+ if (!gf_mnt3_export_dirs(ms)) {
+ errno = EACCES;
+ return NULL;
}
- if (exp == NULL) {
- errno = ENOENT;
- return NULL;
- }
+ path = mnt3_get_volume_subdir(path, &volptr);
+ if (exp == NULL)
+ exp = mnt3_mntpath_to_export(ms, volname, _gf_false);
+ }
- nfs = (struct nfs_state *)nfsx->private;
- if (!nfs_subvolume_started (nfs, exp->vol)) {
- errno = ENOENT;
- return NULL;
- }
+ if (exp == NULL) {
+ errno = ENOENT;
+ return NULL;
+ }
- /* AUTH check: respect nfs.rpc-auth-allow/reject */
- ret = mnt3_check_client_net_udp (req, exp->vol->name, nfsx);
- if (ret == RPCSVC_AUTH_REJECT) {
- errno = EACCES;
- return NULL;
- }
+ nfs = (struct nfs_state *)nfsx->private;
+ if (!nfs_subvolume_started(nfs, exp->vol)) {
+ errno = ENOENT;
+ return NULL;
+ }
- switch (mnt3type) {
+ /* AUTH check: respect nfs.rpc-auth-allow/reject */
+ ret = mnt3_check_client_net_udp(req, exp->vol->name, nfsx);
+ if (ret == RPCSVC_AUTH_REJECT) {
+ errno = EACCES;
+ return NULL;
+ }
+ switch (mnt3type) {
case MNT3_EXPTYPE_VOLUME:
- inode = __mnt3udp_get_export_volume_inode (req, path,
- expname, exp);
- break;
+ inode = __mnt3udp_get_export_volume_inode(req, path, expname, exp);
+ break;
case MNT3_EXPTYPE_DIR:
- inode = __mnt3udp_get_export_subdir_inode (req, path,
- expname, exp);
- break;
+ inode = __mnt3udp_get_export_subdir_inode(req, path, expname, exp);
+ break;
default:
- /* Never reachable */
- gf_msg (GF_MNT, GF_LOG_ERROR, EFAULT, NFS_MSG_UNKNOWN_MNT_TYPE,
- "Unknown MOUNT3 type");
- errno = EFAULT;
- goto err;
- }
-
- if (inode == NULL) {
- /* Don't over-write errno */
- if (!errno)
- errno = ENOENT;
- goto err;
- }
-
- /* Build the inode from FH */
- fh = GF_CALLOC (1, sizeof(*fh), gf_nfs_mt_nfs3_fh);
- if (fh == NULL) {
- errno = ENOMEM;
- goto err;
- }
-
- (void) nfs3_build_fh (inode, exp->volumeid, fh);
+ /* Never reachable */
+ gf_msg(GF_MNT, GF_LOG_ERROR, EFAULT, NFS_MSG_UNKNOWN_MNT_TYPE,
+ "Unknown MOUNT3 type");
+ errno = EFAULT;
+ goto err;
+ }
+
+ if (inode == NULL) {
+ /* Don't over-write errno */
+ if (!errno)
+ errno = ENOENT;
+ goto err;
+ }
+
+ /* Build the inode from FH */
+ fh = GF_CALLOC(1, sizeof(*fh), gf_nfs_mt_nfs3_fh);
+ if (fh == NULL) {
+ errno = ENOMEM;
+ goto err;
+ }
+
+ (void)nfs3_build_fh(inode, exp->volumeid, fh);
err:
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- return fh;
+ return fh;
}
int
-mount3udp_add_mountlist (xlator_t *nfsx, char *host, char *export)
+mount3udp_add_mountlist(xlator_t *nfsx, char *host, char *export)
{
- struct mountentry *me = NULL;
- struct mount3_state *ms = NULL;
+ struct mountentry *me = NULL;
+ struct mount3_state *ms = NULL;
- if ((!host) || (!export) || (!nfsx))
- return -1;
+ if ((!host) || (!export) || (!nfsx))
+ return -1;
- ms = __mnt3udp_get_mstate (nfsx);
- if (!ms)
- return -1;
+ ms = __mnt3udp_get_mstate(nfsx);
+ if (!ms)
+ return -1;
- me = GF_CALLOC (1, sizeof (*me), gf_nfs_mt_mountentry);
- if (!me)
- return -1;
+ me = GF_CALLOC(1, sizeof(*me), gf_nfs_mt_mountentry);
+ if (!me)
+ return -1;
- snprintf (me->exname, MNTPATHLEN, "%s", export);
- snprintf (me->hostname, MNTPATHLEN, "%s", host);
- INIT_LIST_HEAD (&me->mlist);
- LOCK (&ms->mountlock);
- {
- list_add_tail (&me->mlist, &ms->mountlist);
- mount_rewrite_rmtab(ms, NULL);
- }
- UNLOCK (&ms->mountlock);
- return 0;
+ snprintf(me->exname, MNTPATHLEN, "%s", export);
+ snprintf(me->hostname, MNTPATHLEN, "%s", host);
+ INIT_LIST_HEAD(&me->mlist);
+ LOCK(&ms->mountlock);
+ {
+ list_add_tail(&me->mlist, &ms->mountlist);
+ mount_rewrite_rmtab(ms, NULL);
+ }
+ UNLOCK(&ms->mountlock);
+ return 0;
}
int
-mount3udp_delete_mountlist (xlator_t *nfsx, char *hostname, char *export)
+mount3udp_delete_mountlist(xlator_t *nfsx, char *hostname, char *export)
{
- struct mount3_state *ms = NULL;
+ struct mount3_state *ms = NULL;
- if ((!hostname) || (!export) || (!nfsx))
- return -1;
+ if ((!hostname) || (!export) || (!nfsx))
+ return -1;
- ms = __mnt3udp_get_mstate (nfsx);
- if (!ms)
- return -1;
+ ms = __mnt3udp_get_mstate(nfsx);
+ if (!ms)
+ return -1;
- mnt3svc_umount (ms, export, hostname);
- return 0;
+ mnt3svc_umount(ms, export, hostname);
+ return 0;
}
/**
@@ -3113,90 +3098,88 @@ mount3udp_delete_mountlist (xlator_t *nfsx, char *hostname, char *export)
* NB: This does not support IPv6 currently.
*/
int
-mnt3_export_fill_hostspec (struct host_auth_spec* hostspec, const char* hostip)
+mnt3_export_fill_hostspec(struct host_auth_spec *hostspec, const char *hostip)
{
- char *ipdupstr = NULL;
- char *savptr = NULL;
- char *endptr = NULL;
- char *ip = NULL;
- char *token = NULL;
- int ret = -1;
- long prefixlen = IPv4_ADDR_SIZE; /* default */
- uint32_t shiftbits = 0;
- size_t length = 0;
-
- /* Create copy of the string so that the source won't change
- */
- ipdupstr = gf_strdup (hostip);
- if (NULL == ipdupstr) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- goto err;
- }
-
- ip = strtok_r (ipdupstr, "/", &savptr);
- /* Validate the Hostname or IPv4 address
- * TODO: IPv6 support for subdir auth.
- */
- length = strlen (ip);
- if ((!valid_ipv4_address (ip, (int)length, _gf_false)) &&
- (!valid_host_name (ip, (int)length))) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
- "Invalid hostname or IPv4 address: %s", ip);
- goto err;
- }
-
- hostspec->host_addr = gf_strdup (ip);
- if (NULL == hostspec->host_addr) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- goto err;
- }
-
- /**
- * User provided CIDR address (xx.xx.xx.xx/n format) is split
- * into HOST (IP addr or hostname) and network prefix(n) from
- * which netmask would be calculated. This CIDR address may
- * denote a single, distinct interface address or the beginning
- * address of an entire network.
- *
- * e.g. the IPv4 block 192.168.100.0/24 represents the 256
- * IPv4 addresses from 192.168.100.0 to 192.168.100.255.
- * Therefore to check if an IP matches 192.168.100.0/24
- * we should mask the IP with FFFFFF00 and compare it with
- * host address part of CIDR.
- *
- * Refer: mask_match() in common-utils.c.
- */
- token = strtok_r (NULL, "/", &savptr);
- if (token != NULL) {
- prefixlen = strtol (token, &endptr, 10);
- if ((errno != 0) || (*endptr != '\0') ||
- (prefixlen < 0) || (prefixlen > IPv4_ADDR_SIZE)) {
- gf_msg (THIS->name, GF_LOG_WARNING, EINVAL,
- NFS_MSG_INVALID_ENTRY,
- "Invalid IPv4 subnetwork mask");
- goto err;
- }
- }
-
- /*
- * 1. Calculate the network mask address.
- * 2. Convert it into Big-Endian format.
- * 3. Store it in hostspec netmask.
- */
- shiftbits = IPv4_ADDR_SIZE - prefixlen;
- hostspec->netmask = htonl ((uint32_t)~0 << shiftbits);
-
- ret = 0; /* SUCCESS */
+ char *ipdupstr = NULL;
+ char *savptr = NULL;
+ char *endptr = NULL;
+ char *ip = NULL;
+ char *token = NULL;
+ int ret = -1;
+ long prefixlen = IPv4_ADDR_SIZE; /* default */
+ uint32_t shiftbits = 0;
+ size_t length = 0;
+
+ /* Create copy of the string so that the source won't change
+ */
+ ipdupstr = gf_strdup(hostip);
+ if (NULL == ipdupstr) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto err;
+ }
+
+ ip = strtok_r(ipdupstr, "/", &savptr);
+ /* Validate the Hostname or IPv4 address
+ * TODO: IPv6 support for subdir auth.
+ */
+ length = strlen(ip);
+ if ((!valid_ipv4_address(ip, (int)length, _gf_false)) &&
+ (!valid_host_name(ip, (int)length))) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
+ "Invalid hostname or IPv4 address: %s", ip);
+ goto err;
+ }
+
+ hostspec->host_addr = gf_strdup(ip);
+ if (NULL == hostspec->host_addr) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto err;
+ }
+
+ /**
+ * User provided CIDR address (xx.xx.xx.xx/n format) is split
+ * into HOST (IP addr or hostname) and network prefix(n) from
+ * which netmask would be calculated. This CIDR address may
+ * denote a single, distinct interface address or the beginning
+ * address of an entire network.
+ *
+ * e.g. the IPv4 block 192.168.100.0/24 represents the 256
+ * IPv4 addresses from 192.168.100.0 to 192.168.100.255.
+ * Therefore to check if an IP matches 192.168.100.0/24
+ * we should mask the IP with FFFFFF00 and compare it with
+ * host address part of CIDR.
+ *
+ * Refer: mask_match() in common-utils.c.
+ */
+ token = strtok_r(NULL, "/", &savptr);
+ if (token != NULL) {
+ prefixlen = strtol(token, &endptr, 10);
+ if ((errno != 0) || (*endptr != '\0') || (prefixlen < 0) ||
+ (prefixlen > IPv4_ADDR_SIZE)) {
+ gf_msg(THIS->name, GF_LOG_WARNING, EINVAL, NFS_MSG_INVALID_ENTRY,
+ "Invalid IPv4 subnetwork mask");
+ goto err;
+ }
+ }
+
+ /*
+ * 1. Calculate the network mask address.
+ * 2. Convert it into Big-Endian format.
+ * 3. Store it in hostspec netmask.
+ */
+ shiftbits = IPv4_ADDR_SIZE - prefixlen;
+ hostspec->netmask = htonl((uint32_t)~0 << shiftbits);
+
+ ret = 0; /* SUCCESS */
err:
- if (NULL != ipdupstr) {
- GF_FREE (ipdupstr);
- }
- return ret;
+ if (NULL != ipdupstr) {
+ GF_FREE(ipdupstr);
+ }
+ return ret;
}
-
/**
* This function will parse the AUTH parameter passed along with
* "export-dir" option. If AUTH parameter is present then it will be
@@ -3210,80 +3193,75 @@ err:
* @return This function will return 0 on success and -1 on failure.
*/
int
-mnt3_export_parse_auth_param (struct mnt3_export* exp, char* exportpath)
+mnt3_export_parse_auth_param(struct mnt3_export *exp, char *exportpath)
{
- char *token = NULL;
- char *savPtr = NULL;
- char *hostip = NULL;
- struct host_auth_spec *host = NULL;
- int ret = 0;
-
- /* Using exportpath directly in strtok_r because we want
- * to strip off AUTH parameter from exportpath. */
- token = strtok_r (exportpath, "(", &savPtr);
-
- /* Get the next token, which will be the AUTH parameter. */
- token = strtok_r (NULL, ")", &savPtr);
-
- if (NULL == token) {
- /* If AUTH is not present then we should return success. */
- return 0;
- }
+ char *token = NULL;
+ char *savPtr = NULL;
+ char *hostip = NULL;
+ struct host_auth_spec *host = NULL;
+ int ret = 0;
- /* Free any previously allocated hostspec structure. */
- if (NULL != exp->hostspec) {
- GF_FREE (exp->hostspec);
- exp->hostspec = NULL;
- }
+ /* Using exportpath directly in strtok_r because we want
+ * to strip off AUTH parameter from exportpath. */
+ token = strtok_r(exportpath, "(", &savPtr);
- exp->hostspec = GF_CALLOC (1,
- sizeof (*(exp->hostspec)),
- gf_nfs_mt_auth_spec);
- if (NULL == exp->hostspec){
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- return -1;
- }
+ /* Get the next token, which will be the AUTH parameter. */
+ token = strtok_r(NULL, ")", &savPtr);
- /* AUTH parameter can have multiple entries. For each entry
- * a host_auth_spec structure is created. */
- host = exp->hostspec;
+ if (NULL == token) {
+ /* If AUTH is not present then we should return success. */
+ return 0;
+ }
+
+ /* Free any previously allocated hostspec structure. */
+ if (NULL != exp->hostspec) {
+ GF_FREE(exp->hostspec);
+ exp->hostspec = NULL;
+ }
+
+ exp->hostspec = GF_CALLOC(1, sizeof(*(exp->hostspec)), gf_nfs_mt_auth_spec);
+ if (NULL == exp->hostspec) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ return -1;
+ }
- hostip = strtok_r (token, "|", &savPtr);
+ /* AUTH parameter can have multiple entries. For each entry
+ * a host_auth_spec structure is created. */
+ host = exp->hostspec;
- /* Parse all AUTH parameters separated by '|' */
- while (NULL != hostip){
- ret = mnt3_export_fill_hostspec (host, hostip);
- if (0 != ret) {
- gf_msg (GF_MNT, GF_LOG_WARNING, 0,
- NFS_MSG_PARSE_HOSTSPEC_FAIL,
- "Failed to parse hostspec: %s", hostip);
- goto err;
- }
+ hostip = strtok_r(token, "|", &savPtr);
- hostip = strtok_r (NULL, "|", &savPtr);
- if (NULL == hostip) {
- break;
- }
+ /* Parse all AUTH parameters separated by '|' */
+ while (NULL != hostip) {
+ ret = mnt3_export_fill_hostspec(host, hostip);
+ if (0 != ret) {
+ gf_msg(GF_MNT, GF_LOG_WARNING, 0, NFS_MSG_PARSE_HOSTSPEC_FAIL,
+ "Failed to parse hostspec: %s", hostip);
+ goto err;
+ }
- host->next = GF_CALLOC (1, sizeof (*(host)),
- gf_nfs_mt_auth_spec);
- if (NULL == host->next){
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM,
- NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- goto err;
- }
- host = host->next;
+ hostip = strtok_r(NULL, "|", &savPtr);
+ if (NULL == hostip) {
+ break;
}
- /* In case of success return from here */
- return 0;
+ host->next = GF_CALLOC(1, sizeof(*(host)), gf_nfs_mt_auth_spec);
+ if (NULL == host->next) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto err;
+ }
+ host = host->next;
+ }
+
+ /* In case of success return from here */
+ return 0;
err:
- /* In case of failure free up hostspec structure. */
- FREE_HOSTSPEC (exp);
+ /* In case of failure free up hostspec structure. */
+ FREE_HOSTSPEC(exp);
- return -1;
+ return -1;
}
/**
@@ -3292,419 +3270,410 @@ err:
* exportpath format: <abspath>[(hostdesc[|hostspec|...])]
*/
struct mnt3_export *
-mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath,
- uuid_t volumeid)
+mnt3_init_export_ent(struct mount3_state *ms, xlator_t *xl, char *exportpath,
+ uuid_t volumeid)
{
- struct mnt3_export *exp = NULL;
- int alloclen = 0;
- int ret = -1;
-
- if ((!ms) || (!xl))
- return NULL;
-
- exp = GF_CALLOC (1, sizeof (*exp), gf_nfs_mt_mnt3_export);
- if (!exp) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- return NULL;
- }
-
- if (NULL != exportpath) {
- /* If exportpath is not NULL then we should check if AUTH
- * parameter is present or not. If AUTH parameter is present
- * then it will be stripped and stored in mnt3_export (exp)
- * structure.
- */
- if (0 != mnt3_export_parse_auth_param (exp, exportpath)){
- gf_msg (GF_MNT, GF_LOG_ERROR, 0,
- NFS_MSG_PARSE_AUTH_PARAM_FAIL,
- "Failed to parse auth param");
- goto err;
- }
- }
-
+ struct mnt3_export *exp = NULL;
+ int alloclen = 0;
+ int ret = -1;
- INIT_LIST_HEAD (&exp->explist);
- if (exportpath)
- alloclen = strlen (xl->name) + 2 + strlen (exportpath);
- else
- alloclen = strlen (xl->name) + 2;
+ if ((!ms) || (!xl))
+ return NULL;
- exp->expname = GF_MALLOC (alloclen, gf_nfs_mt_char);
- if (!exp->expname) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- goto err;
- }
+ exp = GF_CALLOC(1, sizeof(*exp), gf_nfs_mt_mnt3_export);
+ if (!exp) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ return NULL;
+ }
- if (exportpath) {
- gf_msg_trace (GF_MNT, 0, "Initing dir export: %s:%s",
- xl->name, exportpath);
- exp->exptype = MNT3_EXPTYPE_DIR;
- ret = snprintf (exp->expname, alloclen, "/%s%s", xl->name,
- exportpath);
- } else {
- gf_msg_trace (GF_MNT, 0, "Initing volume export: %s",
- xl->name);
- exp->exptype = MNT3_EXPTYPE_VOLUME;
- ret = snprintf (exp->expname, alloclen, "/%s", xl->name);
- }
- if (ret < 0) {
- gf_msg (xl->name, GF_LOG_ERROR, ret, NFS_MSG_SET_EXP_FAIL,
- "Failed to set the export name");
- goto err;
- }
- /* Just copy without discrimination, we'll determine whether to
- * actually use it when a mount request comes in and a file handle
- * needs to be built.
+ if (NULL != exportpath) {
+ /* If exportpath is not NULL then we should check if AUTH
+ * parameter is present or not. If AUTH parameter is present
+ * then it will be stripped and stored in mnt3_export (exp)
+ * structure.
*/
- gf_uuid_copy (exp->volumeid, volumeid);
- exp->vol = xl;
-
- /* On success we should return from here*/
- return exp;
+ if (0 != mnt3_export_parse_auth_param(exp, exportpath)) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_PARSE_AUTH_PARAM_FAIL,
+ "Failed to parse auth param");
+ goto err;
+ }
+ }
+
+ INIT_LIST_HEAD(&exp->explist);
+ if (exportpath)
+ alloclen = strlen(xl->name) + 2 + strlen(exportpath);
+ else
+ alloclen = strlen(xl->name) + 2;
+
+ exp->expname = GF_MALLOC(alloclen, gf_nfs_mt_char);
+ if (!exp->expname) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ goto err;
+ }
+
+ if (exportpath) {
+ gf_msg_trace(GF_MNT, 0, "Initing dir export: %s:%s", xl->name,
+ exportpath);
+ exp->exptype = MNT3_EXPTYPE_DIR;
+ ret = snprintf(exp->expname, alloclen, "/%s%s", xl->name, exportpath);
+ } else {
+ gf_msg_trace(GF_MNT, 0, "Initing volume export: %s", xl->name);
+ exp->exptype = MNT3_EXPTYPE_VOLUME;
+ ret = snprintf(exp->expname, alloclen, "/%s", xl->name);
+ }
+ if (ret < 0) {
+ gf_msg(xl->name, GF_LOG_ERROR, ret, NFS_MSG_SET_EXP_FAIL,
+ "Failed to set the export name");
+ goto err;
+ }
+ /* Just copy without discrimination, we'll determine whether to
+ * actually use it when a mount request comes in and a file handle
+ * needs to be built.
+ */
+ gf_uuid_copy(exp->volumeid, volumeid);
+ exp->vol = xl;
+
+ /* On success we should return from here*/
+ return exp;
err:
- /* On failure free exp and it's members.*/
- if (NULL != exp) {
- mnt3_export_free (exp);
- exp = NULL;
- }
+ /* On failure free exp and it's members.*/
+ if (NULL != exp) {
+ mnt3_export_free(exp);
+ exp = NULL;
+ }
- return exp;
+ return exp;
}
-
int
-__mnt3_init_volume_direxports (struct mount3_state *ms, xlator_t *xlator,
- char *optstr, uuid_t volumeid)
+__mnt3_init_volume_direxports(struct mount3_state *ms, xlator_t *xlator,
+ char *optstr, uuid_t volumeid)
{
- struct mnt3_export *newexp = NULL;
- int ret = -1;
- char *savptr = NULL;
- char *dupopt = NULL;
- char *token = NULL;
-
- if ((!ms) || (!xlator) || (!optstr))
- return -1;
-
- dupopt = strdupa (optstr);
-
- token = strtok_r (dupopt, ",", &savptr);
- while (token) {
- newexp = mnt3_init_export_ent (ms, xlator, token, volumeid);
- if (!newexp) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0,
- NFS_MSG_INIT_DIR_EXP_FAIL, "Failed to init dir "
- "export: %s", token);
- ret = -1;
- goto err;
- }
+ struct mnt3_export *newexp = NULL;
+ int ret = -1;
+ char *savptr = NULL;
+ char *dupopt = NULL;
+ char *token = NULL;
- list_add_tail (&newexp->explist, &ms->exportlist);
- token = strtok_r (NULL, ",", &savptr);
+ if ((!ms) || (!xlator) || (!optstr))
+ return -1;
+
+ dupopt = strdupa(optstr);
+
+ token = strtok_r(dupopt, ",", &savptr);
+ while (token) {
+ newexp = mnt3_init_export_ent(ms, xlator, token, volumeid);
+ if (!newexp) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_INIT_DIR_EXP_FAIL,
+ "Failed to init dir "
+ "export: %s",
+ token);
+ ret = -1;
+ goto err;
}
- ret = 0;
+ list_add_tail(&newexp->explist, &ms->exportlist);
+ token = strtok_r(NULL, ",", &savptr);
+ }
+
+ ret = 0;
err:
- return ret;
+ return ret;
}
-
int
-__mnt3_init_volume (struct mount3_state *ms, dict_t *opts, xlator_t *xlator)
+__mnt3_init_volume(struct mount3_state *ms, dict_t *opts, xlator_t *xlator)
{
- struct mnt3_export *newexp = NULL;
- int ret = -1;
- char searchstr[1024];
- char *optstr = NULL;
- uuid_t volumeid = {0, };
+ struct mnt3_export *newexp = NULL;
+ int ret = -1;
+ char searchstr[1024];
+ char *optstr = NULL;
+ uuid_t volumeid = {
+ 0,
+ };
+
+ if ((!ms) || (!xlator) || (!opts))
+ return -1;
- if ((!ms) || (!xlator) || (!opts))
- return -1;
+ gf_uuid_clear(volumeid);
+ if (gf_nfs_dvm_off(nfs_state(ms->nfsx)))
+ goto no_dvm;
- gf_uuid_clear (volumeid);
- if (gf_nfs_dvm_off (nfs_state (ms->nfsx)))
- goto no_dvm;
+ ret = snprintf(searchstr, 1024, "nfs3.%s.volume-id", xlator->name);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_SNPRINTF_FAIL,
+ "snprintf failed");
+ ret = -1;
+ goto err;
+ }
- ret = snprintf (searchstr, 1024, "nfs3.%s.volume-id", xlator->name);
+ if (dict_get(opts, searchstr)) {
+ ret = dict_get_str(opts, searchstr, &optstr);
if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_SNPRINTF_FAIL,
- "snprintf failed");
- ret = -1;
- goto err;
- }
-
- if (dict_get (opts, searchstr)) {
- ret = dict_get_str (opts, searchstr, &optstr);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret,
- NFS_MSG_DICT_GET_FAILED, "Failed to read "
- "option: %s", searchstr);
- ret = -1;
- goto err;
- }
- } else {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_VOLID_MISSING,
- "DVM is on but volume-id not "
- "given for volume: %s", xlator->name);
- ret = -1;
- goto err;
- }
-
- if (optstr) {
- ret = gf_uuid_parse (optstr, volumeid);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret,
- NFS_MSG_PARSE_VOL_UUID_FAIL, "Failed to parse "
- "volume UUID");
- ret = -1;
- goto err;
- }
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_DICT_GET_FAILED,
+ "Failed to read "
+ "option: %s",
+ searchstr);
+ ret = -1;
+ goto err;
+ }
+ } else {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_VOLID_MISSING,
+ "DVM is on but volume-id not "
+ "given for volume: %s",
+ xlator->name);
+ ret = -1;
+ goto err;
+ }
+
+ if (optstr) {
+ ret = gf_uuid_parse(optstr, volumeid);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_PARSE_VOL_UUID_FAIL,
+ "Failed to parse "
+ "volume UUID");
+ ret = -1;
+ goto err;
}
+ }
no_dvm:
- ret = snprintf (searchstr, 1024, "nfs3.%s.export-dir", xlator->name);
+ ret = snprintf(searchstr, 1024, "nfs3.%s.export-dir", xlator->name);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_SNPRINTF_FAIL,
+ "snprintf failed");
+ ret = -1;
+ goto err;
+ }
+
+ if (dict_get(opts, searchstr)) {
+ ret = dict_get_str(opts, searchstr, &optstr);
if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_SNPRINTF_FAIL,
- "snprintf failed");
- ret = -1;
- goto err;
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_DICT_GET_FAILED,
+ "Failed to read "
+ "option: %s",
+ searchstr);
+ ret = -1;
+ goto err;
}
- if (dict_get (opts, searchstr)) {
- ret = dict_get_str (opts, searchstr, &optstr);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret,
- NFS_MSG_DICT_GET_FAILED, "Failed to read "
- "option: %s", searchstr);
- ret = -1;
- goto err;
- }
-
- ret = __mnt3_init_volume_direxports (ms, xlator, optstr,
- volumeid);
- if (ret == -1) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0,
- NFS_MSG_DIR_EXP_SETUP_FAIL, "Dir export "
- "setup failed for volume: %s", xlator->name);
- goto err;
- }
+ ret = __mnt3_init_volume_direxports(ms, xlator, optstr, volumeid);
+ if (ret == -1) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_DIR_EXP_SETUP_FAIL,
+ "Dir export "
+ "setup failed for volume: %s",
+ xlator->name);
+ goto err;
}
+ }
- if (ms->export_volumes) {
- newexp = mnt3_init_export_ent (ms, xlator, NULL, volumeid);
- if (!newexp) {
- ret = -1;
- goto err;
- }
-
- list_add_tail (&newexp->explist, &ms->exportlist);
+ if (ms->export_volumes) {
+ newexp = mnt3_init_export_ent(ms, xlator, NULL, volumeid);
+ if (!newexp) {
+ ret = -1;
+ goto err;
}
- ret = 0;
+ list_add_tail(&newexp->explist, &ms->exportlist);
+ }
+ ret = 0;
err:
- return ret;
+ return ret;
}
-
int
-__mnt3_init_volume_export (struct mount3_state *ms, dict_t *opts)
+__mnt3_init_volume_export(struct mount3_state *ms, dict_t *opts)
{
- int ret = -1;
- char *optstr = NULL;
- /* On by default. */
- gf_boolean_t boolt = _gf_true;
-
- if ((!ms) || (!opts))
- return -1;
-
- if (!dict_get (opts, "nfs3.export-volumes")) {
- ret = 0;
- goto err;
- }
+ int ret = -1;
+ char *optstr = NULL;
+ /* On by default. */
+ gf_boolean_t boolt = _gf_true;
- ret = dict_get_str (opts, "nfs3.export-volumes", &optstr);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_DICT_GET_FAILED,
- "Failed to read option: nfs3.export-volumes");
- ret = -1;
- goto err;
- }
+ if ((!ms) || (!opts))
+ return -1;
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_STR2BOOL_FAIL,
- "Failed to convert string to boolean");
- }
+ if (!dict_get(opts, "nfs3.export-volumes")) {
+ ret = 0;
+ goto err;
+ }
+
+ ret = dict_get_str(opts, "nfs3.export-volumes", &optstr);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_DICT_GET_FAILED,
+ "Failed to read option: nfs3.export-volumes");
+ ret = -1;
+ goto err;
+ }
+
+ ret = gf_string2boolean(optstr, &boolt);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_STR2BOOL_FAIL,
+ "Failed to convert string to boolean");
+ }
err:
- if (boolt == _gf_false) {
- gf_msg_trace (GF_MNT, 0, "Volume exports disabled");
- ms->export_volumes = 0;
- } else {
- gf_msg_trace (GF_MNT, 0, "Volume exports enabled");
- ms->export_volumes = 1;
- }
-
- return ret;
+ if (boolt == _gf_false) {
+ gf_msg_trace(GF_MNT, 0, "Volume exports disabled");
+ ms->export_volumes = 0;
+ } else {
+ gf_msg_trace(GF_MNT, 0, "Volume exports enabled");
+ ms->export_volumes = 1;
+ }
+
+ return ret;
}
-
int
-__mnt3_init_dir_export (struct mount3_state *ms, dict_t *opts)
+__mnt3_init_dir_export(struct mount3_state *ms, dict_t *opts)
{
- int ret = -1;
- char *optstr = NULL;
- /* On by default. */
- gf_boolean_t boolt = _gf_true;
-
- if ((!ms) || (!opts))
- return -1;
+ int ret = -1;
+ char *optstr = NULL;
+ /* On by default. */
+ gf_boolean_t boolt = _gf_true;
- if (!dict_get (opts, "nfs3.export-dirs")) {
- ret = 0;
- goto err;
- }
-
- ret = dict_get_str (opts, "nfs3.export-dirs", &optstr);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_DICT_GET_FAILED,
- "Failed to read option: nfs3.export-dirs");
- ret = -1;
- goto err;
- }
+ if ((!ms) || (!opts))
+ return -1;
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_STR2BOOL_FAIL,
- "Failed to convert string to boolean");
- }
+ if (!dict_get(opts, "nfs3.export-dirs")) {
+ ret = 0;
+ goto err;
+ }
+
+ ret = dict_get_str(opts, "nfs3.export-dirs", &optstr);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_DICT_GET_FAILED,
+ "Failed to read option: nfs3.export-dirs");
+ ret = -1;
+ goto err;
+ }
+
+ ret = gf_string2boolean(optstr, &boolt);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_STR2BOOL_FAIL,
+ "Failed to convert string to boolean");
+ }
err:
- if (boolt == _gf_false) {
- gf_msg_trace (GF_MNT, 0, "Dir exports disabled");
- ms->export_dirs = 0;
- } else {
- gf_msg_trace (GF_MNT, 0, "Dir exports enabled");
- ms->export_dirs = 1;
- }
-
- return ret;
+ if (boolt == _gf_false) {
+ gf_msg_trace(GF_MNT, 0, "Dir exports disabled");
+ ms->export_dirs = 0;
+ } else {
+ gf_msg_trace(GF_MNT, 0, "Dir exports enabled");
+ ms->export_dirs = 1;
+ }
+
+ return ret;
}
-
int
-mnt3_init_options (struct mount3_state *ms, dict_t *options)
+mnt3_init_options(struct mount3_state *ms, dict_t *options)
{
- xlator_list_t *volentry = NULL;
- int ret = -1;
-
- if ((!ms) || (!options))
- return -1;
-
- __mnt3_init_volume_export (ms, options);
- __mnt3_init_dir_export (ms, options);
- volentry = ms->nfsx->children;
- while (volentry) {
- gf_msg_trace (GF_MNT, 0, "Initing options for: %s",
- volentry->xlator->name);
- ret = __mnt3_init_volume (ms, options, volentry->xlator);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret,
- NFS_MSG_VOL_INIT_FAIL,
- "Volume init failed");
- goto err;
- }
+ xlator_list_t *volentry = NULL;
+ int ret = -1;
- volentry = volentry->next;
+ if ((!ms) || (!options))
+ return -1;
+
+ __mnt3_init_volume_export(ms, options);
+ __mnt3_init_dir_export(ms, options);
+ volentry = ms->nfsx->children;
+ while (volentry) {
+ gf_msg_trace(GF_MNT, 0, "Initing options for: %s",
+ volentry->xlator->name);
+ ret = __mnt3_init_volume(ms, options, volentry->xlator);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_VOL_INIT_FAIL,
+ "Volume init failed");
+ goto err;
}
+ volentry = volentry->next;
+ }
- ret = 0;
+ ret = 0;
err:
- return ret;
+ return ret;
}
struct mount3_state *
-mnt3_init_state (xlator_t *nfsx)
+mnt3_init_state(xlator_t *nfsx)
{
- struct mount3_state *ms = NULL;
- int ret = -1;
-
- if (!nfsx)
- return NULL;
+ struct mount3_state *ms = NULL;
+ int ret = -1;
- ms = GF_CALLOC (1, sizeof (*ms), gf_nfs_mt_mount3_state);
- if (!ms) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Memory allocation failed");
- return NULL;
- }
+ if (!nfsx)
+ return NULL;
- ms->iobpool = nfsx->ctx->iobuf_pool;
- ms->nfsx = nfsx;
- INIT_LIST_HEAD (&ms->exportlist);
- ret = mnt3_init_options (ms, nfsx->options);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_OPT_INIT_FAIL,
- "Options init failed");
- return NULL;
- }
+ ms = GF_CALLOC(1, sizeof(*ms), gf_nfs_mt_mount3_state);
+ if (!ms) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Memory allocation failed");
+ return NULL;
+ }
+
+ ms->iobpool = nfsx->ctx->iobuf_pool;
+ ms->nfsx = nfsx;
+ INIT_LIST_HEAD(&ms->exportlist);
+ ret = mnt3_init_options(ms, nfsx->options);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_OPT_INIT_FAIL,
+ "Options init failed");
+ return NULL;
+ }
- INIT_LIST_HEAD (&ms->mountlist);
- LOCK_INIT (&ms->mountlock);
+ INIT_LIST_HEAD(&ms->mountlist);
+ LOCK_INIT(&ms->mountlock);
- return ms;
+ return ms;
}
int
-mount_init_state (xlator_t *nfsx)
+mount_init_state(xlator_t *nfsx)
{
- int ret = -1;
- struct nfs_state *nfs = NULL;
-
- if (!nfsx)
- goto out;
-
- nfs = (struct nfs_state *)nfs_state (nfsx);
- /*Maintaining global state for MOUNT1 and MOUNT3*/
- nfs->mstate = mnt3_init_state (nfsx);
- if (!nfs->mstate) {
- gf_msg (GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Failed to allocate mount state");
- goto out;
- }
- ret = 0;
+ int ret = -1;
+ struct nfs_state *nfs = NULL;
+
+ if (!nfsx)
+ goto out;
+
+ nfs = (struct nfs_state *)nfs_state(nfsx);
+ /*Maintaining global state for MOUNT1 and MOUNT3*/
+ nfs->mstate = mnt3_init_state(nfsx);
+ if (!nfs->mstate) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Failed to allocate mount state");
+ goto out;
+ }
+ ret = 0;
out:
- return ret;
+ return ret;
}
-rpcsvc_actor_t mnt3svc_actors[MOUNT3_PROC_COUNT] = {
- {"NULL", MOUNT3_NULL, mnt3svc_null, NULL, 0, DRC_NA},
- {"MNT", MOUNT3_MNT, mnt3svc_mnt, NULL, 0, DRC_NA},
- {"DUMP", MOUNT3_DUMP, mnt3svc_dump, NULL, 0, DRC_NA},
- {"UMNT", MOUNT3_UMNT, mnt3svc_umnt, NULL, 0, DRC_NA},
- {"UMNTALL", MOUNT3_UMNTALL, mnt3svc_umntall, NULL, 0, DRC_NA},
- {"EXPORT", MOUNT3_EXPORT, mnt3svc_export, NULL, 0, DRC_NA}
-};
-
-
+rpcsvc_actor_t mnt3svc_actors[MOUNT3_PROC_COUNT] = {
+ {"NULL", MOUNT3_NULL, mnt3svc_null, NULL, 0, DRC_NA},
+ {"MNT", MOUNT3_MNT, mnt3svc_mnt, NULL, 0, DRC_NA},
+ {"DUMP", MOUNT3_DUMP, mnt3svc_dump, NULL, 0, DRC_NA},
+ {"UMNT", MOUNT3_UMNT, mnt3svc_umnt, NULL, 0, DRC_NA},
+ {"UMNTALL", MOUNT3_UMNTALL, mnt3svc_umntall, NULL, 0, DRC_NA},
+ {"EXPORT", MOUNT3_EXPORT, mnt3svc_export, NULL, 0, DRC_NA}};
/* Static init parts are assigned here, dynamic ones are done in
* mnt3svc_init and mnt3_init_state.
* Making MOUNT3 a synctask so that the blocking DNS calls during rpc auth
* gets offloaded to syncenv, keeping the main/poll thread unblocked
*/
-rpcsvc_program_t mnt3prog = {
- .progname = "MOUNT3",
- .prognum = MOUNT_PROGRAM,
- .progver = MOUNT_V3,
- .progport = GF_MOUNTV3_PORT,
- .actors = mnt3svc_actors,
- .numactors = MOUNT3_PROC_COUNT,
- .min_auth = AUTH_NULL,
- .synctask = _gf_true,
+rpcsvc_program_t mnt3prog = {
+ .progname = "MOUNT3",
+ .prognum = MOUNT_PROGRAM,
+ .progver = MOUNT_V3,
+ .progport = GF_MOUNTV3_PORT,
+ .actors = mnt3svc_actors,
+ .numactors = MOUNT3_PROC_COUNT,
+ .min_auth = AUTH_NULL,
+ .synctask = _gf_true,
};
/**
@@ -3718,79 +3687,82 @@ rpcsvc_program_t mnt3prog = {
*
*/
int
-__mnt3_mounted_exports_walk (dict_t *dict, char *key, data_t *val, void *tmp)
+__mnt3_mounted_exports_walk(dict_t *dict, char *key, data_t *val, void *tmp)
{
- char *path = NULL;
- char *host_addr_ip = NULL;
- char *host_addr_fqdn = NULL;
- char *keydup = NULL;
- char *colon = NULL;
- struct mnt3_auth_params *auth_params = NULL;
- int ret = 0;
- int auth_status_code = 0;
-
- gf_msg_trace (GF_MNT, 0, "Checking if key %s is authorized.", key);
-
- auth_params = (struct mnt3_auth_params *)tmp;
-
- /* Since we haven't obtained a lock around the mount dict
- * here, we want to duplicate the key and then process it.
- * Otherwise we would potentially have a race condition
- * by modifying the key in the dict when other threads
- * are accessing it.
- */
- keydup = strdupa (key);
-
- colon = strchr (keydup, ':');
- if (!colon)
- return 0;
-
- *colon = '\0';
-
- path = alloca (strlen (keydup) + 2);
- snprintf (path, strlen (keydup) + 2, "/%s", keydup);
-
- /* Host is one character after ':' */
- host_addr_ip = colon + 1;
-
- /* Check if the IP is authorized */
- auth_status_code = mnt3_auth_host (auth_params, host_addr_ip,
- NULL, path, FALSE, NULL);
- if (auth_status_code == 0) {
- goto out;
- }
-
- ret = gf_get_hostname_from_ip (host_addr_ip, &host_addr_fqdn);
- if (ret != 0) {
- gf_msg (GF_MNT, GF_LOG_DEBUG, 0, NFS_MSG_AUTH_ERROR ,
- "Authorization failed for IP [%s], but name "
- "resolution also failed!", host_addr_ip);
- goto unmount;
- }
+ char *path = NULL;
+ char *host_addr_ip = NULL;
+ char *host_addr_fqdn = NULL;
+ char *keydup = NULL;
+ char *colon = NULL;
+ struct mnt3_auth_params *auth_params = NULL;
+ int ret = 0;
+ int auth_status_code = 0;
+
+ gf_msg_trace(GF_MNT, 0, "Checking if key %s is authorized.", key);
+
+ auth_params = (struct mnt3_auth_params *)tmp;
+
+ /* Since we haven't obtained a lock around the mount dict
+ * here, we want to duplicate the key and then process it.
+ * Otherwise we would potentially have a race condition
+ * by modifying the key in the dict when other threads
+ * are accessing it.
+ */
+ keydup = strdupa(key);
+
+ colon = strchr(keydup, ':');
+ if (!colon)
+ return 0;
- /* If not, check if the FQDN is authorized */
- gf_msg (GF_MNT, GF_LOG_DEBUG, 0, NFS_MSG_AUTH_ERROR,
- "Authorization failed for IP [%s], attempting to"
- " auth hostname [%s]...", host_addr_ip, host_addr_fqdn);
-
- auth_status_code = mnt3_auth_host (auth_params, host_addr_fqdn,
- NULL, path, FALSE, NULL);
- if (auth_status_code == 0) {
- gf_msg (GF_MNT, GF_LOG_DEBUG, 0, NFS_MSG_AUTH_ERROR,
- "Authorization succeeded for "
- "Client [IP=%s, Hostname=%s].",
- host_addr_ip, host_addr_fqdn);
- goto out;
- }
+ *colon = '\0';
+
+ path = alloca(strlen(keydup) + 2);
+ snprintf(path, strlen(keydup) + 2, "/%s", keydup);
+
+ /* Host is one character after ':' */
+ host_addr_ip = colon + 1;
+
+ /* Check if the IP is authorized */
+ auth_status_code = mnt3_auth_host(auth_params, host_addr_ip, NULL, path,
+ FALSE, NULL);
+ if (auth_status_code == 0) {
+ goto out;
+ }
+
+ ret = gf_get_hostname_from_ip(host_addr_ip, &host_addr_fqdn);
+ if (ret != 0) {
+ gf_msg(GF_MNT, GF_LOG_DEBUG, 0, NFS_MSG_AUTH_ERROR,
+ "Authorization failed for IP [%s], but name "
+ "resolution also failed!",
+ host_addr_ip);
+ goto unmount;
+ }
+
+ /* If not, check if the FQDN is authorized */
+ gf_msg(GF_MNT, GF_LOG_DEBUG, 0, NFS_MSG_AUTH_ERROR,
+ "Authorization failed for IP [%s], attempting to"
+ " auth hostname [%s]...",
+ host_addr_ip, host_addr_fqdn);
+
+ auth_status_code = mnt3_auth_host(auth_params, host_addr_fqdn, NULL, path,
+ FALSE, NULL);
+ if (auth_status_code == 0) {
+ gf_msg(GF_MNT, GF_LOG_DEBUG, 0, NFS_MSG_AUTH_ERROR,
+ "Authorization succeeded for "
+ "Client [IP=%s, Hostname=%s].",
+ host_addr_ip, host_addr_fqdn);
+ goto out;
+ }
unmount:
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_AUTH_ERROR,
- "Client [IP=%s, Hostname=%s] not authorized for this mount. "
- "Unmounting!", host_addr_ip, host_addr_fqdn);
- mnt3svc_umount (auth_params->ms, path, host_addr_ip);
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_AUTH_ERROR,
+ "Client [IP=%s, Hostname=%s] not authorized for this mount. "
+ "Unmounting!",
+ host_addr_ip, host_addr_fqdn);
+ mnt3svc_umount(auth_params->ms, path, host_addr_ip);
out:
- GF_FREE (host_addr_fqdn);
- return 0;
+ GF_FREE(host_addr_fqdn);
+ return 0;
}
/**
@@ -3802,14 +3774,12 @@ out:
*
*/
void
-_mnt3_invalidate_old_mounts (struct mount3_state *ms)
+_mnt3_invalidate_old_mounts(struct mount3_state *ms)
{
- gf_msg_debug (GF_MNT, 0, "Invalidating old mounts ...");
- dict_foreach (ms->mountdict, __mnt3_mounted_exports_walk,
- ms->auth_params);
+ gf_msg_debug(GF_MNT, 0, "Invalidating old mounts ...");
+ dict_foreach(ms->mountdict, __mnt3_mounted_exports_walk, ms->auth_params);
}
-
/**
* _mnt3_has_file_changed -- Checks if a file has changed on disk
*
@@ -3822,25 +3792,25 @@ _mnt3_invalidate_old_mounts (struct mount3_state *ms)
* Uses get_file_mtime () in common-utils.c
*/
gf_boolean_t
-_mnt3_has_file_changed (const char *path, time_t *oldmtime)
+_mnt3_has_file_changed(const char *path, time_t *oldmtime)
{
- gf_boolean_t changed = _gf_false;
- time_t mtime = {0};
- int ret = 0;
+ gf_boolean_t changed = _gf_false;
+ time_t mtime = {0};
+ int ret = 0;
- GF_VALIDATE_OR_GOTO (GF_MNT, path, out);
- GF_VALIDATE_OR_GOTO (GF_MNT, oldmtime, out);
+ GF_VALIDATE_OR_GOTO(GF_MNT, path, out);
+ GF_VALIDATE_OR_GOTO(GF_MNT, oldmtime, out);
- ret = get_file_mtime (path, &mtime);
- if (ret < 0)
- goto out;
+ ret = get_file_mtime(path, &mtime);
+ if (ret < 0)
+ goto out;
- if (mtime != *oldmtime) {
- changed = _gf_true;
- *oldmtime = mtime;
- }
+ if (mtime != *oldmtime) {
+ changed = _gf_true;
+ *oldmtime = mtime;
+ }
out:
- return changed;
+ return changed;
}
/**
@@ -3853,84 +3823,82 @@ out:
* @return: Always returns NULL
*/
void *
-_mnt3_auth_param_refresh_thread (void *argv)
+_mnt3_auth_param_refresh_thread(void *argv)
{
- struct mount3_state *mstate = (struct mount3_state *)argv;
- char *exp_file_path = NULL;
- char *ng_file_path = NULL;
- size_t nbytes = 0;
- time_t exp_time = 0;
- time_t ng_time = 0;
- gf_boolean_t any_file_changed = _gf_false;
- int ret = 0;
-
- nbytes = strlen (exports_file_path) + 1;
- exp_file_path = alloca (nbytes);
- snprintf (exp_file_path, nbytes, "%s", exports_file_path);
-
- nbytes = strlen (netgroups_file_path) + 1;
- ng_file_path = alloca (nbytes);
- snprintf (ng_file_path, nbytes, "%s", netgroups_file_path);
-
- /* Set the initial timestamps to avoid reloading right after
- * mnt3svc_init () spawns this thread */
- get_file_mtime (exp_file_path, &exp_time);
- get_file_mtime (ng_file_path, &ng_time);
-
- while (_gf_true) {
- if (mstate->stop_refresh)
- break;
- any_file_changed = _gf_false;
-
- /* Sleep before checking the file again */
- sleep (mstate->nfs->auth_refresh_time_secs);
-
- if (_mnt3_has_file_changed (exp_file_path, &exp_time)) {
- gf_msg (GF_MNT, GF_LOG_INFO, 0, NFS_MSG_UPDATING_EXP,
- "File %s changed, updating exports,",
- exp_file_path);
-
- ret = mnt3_auth_set_exports_auth (mstate->auth_params,
- exp_file_path);
- if (ret)
- gf_msg (GF_MNT, GF_LOG_ERROR, 0,
- NFS_MSG_SET_EXP_AUTH_PARAM_FAIL,
- "Failed to set export auth params.");
- else
- any_file_changed = _gf_true;
- }
-
- if (_mnt3_has_file_changed (ng_file_path, &ng_time)) {
- gf_msg (GF_MNT, GF_LOG_INFO, 0,
- NFS_MSG_UPDATING_NET_GRP, "File %s changed,"
- "updating netgroups", ng_file_path);
-
- ret = mnt3_auth_set_netgroups_auth (mstate->auth_params,
- ng_file_path);
- if (ret)
- gf_msg (GF_MNT, GF_LOG_ERROR, 0,
- NFS_MSG_SET_NET_GRP_FAIL,
- "Failed to set netgroup auth params.");
- else
- any_file_changed = _gf_true;
- }
-
- /* If no files changed, go back to sleep */
- if (!any_file_changed)
- continue;
-
- gf_msg (GF_MNT, GF_LOG_INFO, 0, NFS_MSG_PURGING_AUTH_CACHE,
- "Purging auth cache.");
- auth_cache_purge (mstate->authcache);
-
- /* Walk through mounts that are no longer authorized
- * and unmount them on the server side. This will
- * cause subsequent file ops to fail with access denied.
- */
- _mnt3_invalidate_old_mounts (mstate);
- }
+ struct mount3_state *mstate = (struct mount3_state *)argv;
+ char *exp_file_path = NULL;
+ char *ng_file_path = NULL;
+ size_t nbytes = 0;
+ time_t exp_time = 0;
+ time_t ng_time = 0;
+ gf_boolean_t any_file_changed = _gf_false;
+ int ret = 0;
+
+ nbytes = strlen(exports_file_path) + 1;
+ exp_file_path = alloca(nbytes);
+ snprintf(exp_file_path, nbytes, "%s", exports_file_path);
+
+ nbytes = strlen(netgroups_file_path) + 1;
+ ng_file_path = alloca(nbytes);
+ snprintf(ng_file_path, nbytes, "%s", netgroups_file_path);
+
+ /* Set the initial timestamps to avoid reloading right after
+ * mnt3svc_init () spawns this thread */
+ get_file_mtime(exp_file_path, &exp_time);
+ get_file_mtime(ng_file_path, &ng_time);
+
+ while (_gf_true) {
+ if (mstate->stop_refresh)
+ break;
+ any_file_changed = _gf_false;
+
+ /* Sleep before checking the file again */
+ sleep(mstate->nfs->auth_refresh_time_secs);
+
+ if (_mnt3_has_file_changed(exp_file_path, &exp_time)) {
+ gf_msg(GF_MNT, GF_LOG_INFO, 0, NFS_MSG_UPDATING_EXP,
+ "File %s changed, updating exports,", exp_file_path);
+
+ ret = mnt3_auth_set_exports_auth(mstate->auth_params,
+ exp_file_path);
+ if (ret)
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SET_EXP_AUTH_PARAM_FAIL,
+ "Failed to set export auth params.");
+ else
+ any_file_changed = _gf_true;
+ }
+
+ if (_mnt3_has_file_changed(ng_file_path, &ng_time)) {
+ gf_msg(GF_MNT, GF_LOG_INFO, 0, NFS_MSG_UPDATING_NET_GRP,
+ "File %s changed,"
+ "updating netgroups",
+ ng_file_path);
+
+ ret = mnt3_auth_set_netgroups_auth(mstate->auth_params,
+ ng_file_path);
+ if (ret)
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SET_NET_GRP_FAIL,
+ "Failed to set netgroup auth params.");
+ else
+ any_file_changed = _gf_true;
+ }
+
+ /* If no files changed, go back to sleep */
+ if (!any_file_changed)
+ continue;
+
+ gf_msg(GF_MNT, GF_LOG_INFO, 0, NFS_MSG_PURGING_AUTH_CACHE,
+ "Purging auth cache.");
+ auth_cache_purge(mstate->authcache);
+
+ /* Walk through mounts that are no longer authorized
+ * and unmount them on the server side. This will
+ * cause subsequent file ops to fail with access denied.
+ */
+ _mnt3_invalidate_old_mounts(mstate);
+ }
- return NULL;
+ return NULL;
}
/**
@@ -3946,53 +3914,50 @@ _mnt3_auth_param_refresh_thread (void *argv)
* bubbled up from the functions we call to set the params.
*/
int
-_mnt3_init_auth_params (struct mount3_state *mstate)
+_mnt3_init_auth_params(struct mount3_state *mstate)
{
- int ret = -EINVAL;
- char *exp_file_path = NULL;
- char *ng_file_path = NULL;
- size_t nbytes = 0;
-
- GF_VALIDATE_OR_GOTO (GF_MNT, mstate, out);
-
- mstate->auth_params = mnt3_auth_params_init (mstate);
- if (!mstate->auth_params) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Failed to init mount auth params.");
- ret = -ENOMEM;
- goto out;
- }
-
- nbytes = strlen (exports_file_path) + 1;
- exp_file_path = alloca (nbytes);
- snprintf (exp_file_path, nbytes, "%s", exports_file_path);
-
- ret = mnt3_auth_set_exports_auth (mstate->auth_params, exp_file_path);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret,
- NFS_MSG_SET_EXP_AUTH_PARAM_FAIL,
- "Failed to set export auth params.");
- goto out;
- }
-
- nbytes = strlen (netgroups_file_path) + 1;
- ng_file_path = alloca (nbytes);
- snprintf (ng_file_path, nbytes, "%s", netgroups_file_path);
-
- ret = mnt3_auth_set_netgroups_auth (mstate->auth_params, ng_file_path);
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret,
- NFS_MSG_SET_EXP_AUTH_PARAM_FAIL,
- "Failed to set netgroup auth params.");
- goto out;
- }
-
- ret = 0;
+ int ret = -EINVAL;
+ char *exp_file_path = NULL;
+ char *ng_file_path = NULL;
+ size_t nbytes = 0;
+
+ GF_VALIDATE_OR_GOTO(GF_MNT, mstate, out);
+
+ mstate->auth_params = mnt3_auth_params_init(mstate);
+ if (!mstate->auth_params) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Failed to init mount auth params.");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ nbytes = strlen(exports_file_path) + 1;
+ exp_file_path = alloca(nbytes);
+ snprintf(exp_file_path, nbytes, "%s", exports_file_path);
+
+ ret = mnt3_auth_set_exports_auth(mstate->auth_params, exp_file_path);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_SET_EXP_AUTH_PARAM_FAIL,
+ "Failed to set export auth params.");
+ goto out;
+ }
+
+ nbytes = strlen(netgroups_file_path) + 1;
+ ng_file_path = alloca(nbytes);
+ snprintf(ng_file_path, nbytes, "%s", netgroups_file_path);
+
+ ret = mnt3_auth_set_netgroups_auth(mstate->auth_params, ng_file_path);
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_SET_EXP_AUTH_PARAM_FAIL,
+ "Failed to set netgroup auth params.");
+ goto out;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
/**
* mnt3svc_deinit -- Function called by the nfs translator to cleanup all state
*
@@ -4001,289 +3966,278 @@ out:
* as well as the threads that have been started.
*/
void
-mnt3svc_deinit (xlator_t *nfsx)
+mnt3svc_deinit(xlator_t *nfsx)
{
- struct mount3_state *mstate = NULL;
- struct nfs_state *nfs = NULL;
+ struct mount3_state *mstate = NULL;
+ struct nfs_state *nfs = NULL;
- if (!nfsx || !nfsx->private)
- return;
-
- nfs = (struct nfs_state *)nfsx->private;
- mstate = (struct mount3_state *)nfs->mstate;
-
- if (nfs->refresh_auth) {
- /* Mark as true and wait for thread to exit */
- mstate->stop_refresh = _gf_true;
- pthread_join (mstate->auth_refresh_thread, NULL);
- }
-
- if (nfs->exports_auth)
- mnt3_auth_params_deinit (mstate->auth_params);
-
- /* Unmount everything and clear mountdict */
- LOCK (&mstate->mountlock);
- {
- __mnt3svc_umountall (mstate);
- dict_unref (mstate->mountdict);
- }
- UNLOCK (&mstate->mountlock);
+ if (!nfsx || !nfsx->private)
+ return;
+ nfs = (struct nfs_state *)nfsx->private;
+ mstate = (struct mount3_state *)nfs->mstate;
+
+ if (nfs->refresh_auth) {
+ /* Mark as true and wait for thread to exit */
+ mstate->stop_refresh = _gf_true;
+ pthread_join(mstate->auth_refresh_thread, NULL);
+ }
+
+ if (nfs->exports_auth)
+ mnt3_auth_params_deinit(mstate->auth_params);
+
+ /* Unmount everything and clear mountdict */
+ LOCK(&mstate->mountlock);
+ {
+ __mnt3svc_umountall(mstate);
+ dict_unref(mstate->mountdict);
+ }
+ UNLOCK(&mstate->mountlock);
}
rpcsvc_program_t *
-mnt3svc_init (xlator_t *nfsx)
+mnt3svc_init(xlator_t *nfsx)
{
- struct mount3_state *mstate = NULL;
- struct nfs_state *nfs = NULL;
- dict_t *options = NULL;
- char *portstr = NULL;
- int ret = -1;
- pthread_t udp_thread;
-
- if (!nfsx || !nfsx->private)
- return NULL;
-
- nfs = (struct nfs_state *)nfsx->private;
-
- gf_msg_debug (GF_MNT, 0, "Initing Mount v3 state");
- mstate = (struct mount3_state *)nfs->mstate;
- if (!mstate) {
- gf_msg (GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_MNT_STATE_INIT_FAIL,
- "Mount v3 state init failed");
- goto err;
- }
+ struct mount3_state *mstate = NULL;
+ struct nfs_state *nfs = NULL;
+ dict_t *options = NULL;
+ char *portstr = NULL;
+ int ret = -1;
+ pthread_t udp_thread;
+
+ if (!nfsx || !nfsx->private)
+ return NULL;
- mstate->nfs = nfs;
+ nfs = (struct nfs_state *)nfsx->private;
- mstate->mountdict = dict_new ();
- if (!mstate->mountdict) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
- "Failed to setup mount dict. Allocation error.");
- goto err;
- }
+ gf_msg_debug(GF_MNT, 0, "Initing Mount v3 state");
+ mstate = (struct mount3_state *)nfs->mstate;
+ if (!mstate) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_MNT_STATE_INIT_FAIL,
+ "Mount v3 state init failed");
+ goto err;
+ }
- if (nfs->exports_auth) {
- ret = _mnt3_init_auth_params (mstate);
- if (ret < 0)
- goto err;
+ mstate->nfs = nfs;
- mstate->authcache = auth_cache_init (nfs->auth_cache_ttl_sec);
- if (!mstate->authcache) {
- ret = -ENOMEM;
- goto err;
- }
+ mstate->mountdict = dict_new();
+ if (!mstate->mountdict) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
+ "Failed to setup mount dict. Allocation error.");
+ goto err;
+ }
- mstate->stop_refresh = _gf_false; /* Allow thread to run */
- ret = gf_thread_create (&mstate->auth_refresh_thread, NULL,
- _mnt3_auth_param_refresh_thread,
- mstate, "nfsauth");
- if (ret) {
- gf_msg_debug (GF_MNT, GF_LOG_DEBUG,
- "Thread creation failed");
- }
+ if (nfs->exports_auth) {
+ ret = _mnt3_init_auth_params(mstate);
+ if (ret < 0)
+ goto err;
- } else
- gf_msg (GF_MNT, GF_LOG_INFO, 0, NFS_MSG_EXP_AUTH_DISABLED,
- "Exports auth has been disabled!");
+ mstate->authcache = auth_cache_init(nfs->auth_cache_ttl_sec);
+ if (!mstate->authcache) {
+ ret = -ENOMEM;
+ goto err;
+ }
- mnt3prog.private = mstate;
- options = dict_new ();
+ mstate->stop_refresh = _gf_false; /* Allow thread to run */
+ ret = gf_thread_create(&mstate->auth_refresh_thread, NULL,
+ _mnt3_auth_param_refresh_thread, mstate,
+ "nfsauth");
+ if (ret) {
+ gf_msg_debug(GF_MNT, GF_LOG_DEBUG, "Thread creation failed");
+ }
- ret = gf_asprintf (&portstr, "%d", GF_MOUNTV3_PORT);
- if (ret == -1)
- goto err;
+ } else
+ gf_msg(GF_MNT, GF_LOG_INFO, 0, NFS_MSG_EXP_AUTH_DISABLED,
+ "Exports auth has been disabled!");
- ret = dict_set_dynstr (options, "transport.socket.listen-port",
- portstr);
- if (ret == -1)
- goto err;
+ mnt3prog.private = mstate;
+ options = dict_new();
- ret = dict_set_str (options, "transport-type", "socket");
- if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
- "dict_set_str error");
- goto err;
- }
+ ret = gf_asprintf(&portstr, "%d", GF_MOUNTV3_PORT);
+ if (ret == -1)
+ goto err;
- if (nfs->allow_insecure) {
- ret = dict_set_str (options, "rpc-auth-allow-insecure", "on");
- if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno,
- NFS_MSG_DICT_SET_FAILED, "dict_set_str error");
- goto err;
- }
- ret = dict_set_str (options, "rpc-auth.ports.insecure", "on");
- if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno,
- NFS_MSG_DICT_SET_FAILED, "dict_set_str error");
- goto err;
- }
- }
+ ret = dict_set_dynstr(options, "transport.socket.listen-port", portstr);
+ if (ret == -1)
+ goto err;
- ret= rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name);
+ ret = dict_set_str(options, "transport-type", "socket");
+ if (ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
+ "dict_set_str error");
+ goto err;
+ }
+
+ if (nfs->allow_insecure) {
+ ret = dict_set_str(options, "rpc-auth-allow-insecure", "on");
if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno,
- NFS_MSG_LISTENERS_CREATE_FAIL,
- "Unable to create listeners");
- dict_unref (options);
- goto err;
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
+ "dict_set_str error");
+ goto err;
}
-
- if (nfs->mount_udp) {
- ret = gf_thread_create (&udp_thread, NULL, mount3udp_thread,
- nfsx, "nfsudp");
- if (ret) {
- gf_msg_debug (GF_MNT, GF_LOG_DEBUG,
- "Thread creation failed");
- }
+ ret = dict_set_str(options, "rpc-auth.ports.insecure", "on");
+ if (ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
+ "dict_set_str error");
+ goto err;
+ }
+ }
+
+ ret = rpcsvc_create_listeners(nfs->rpcsvc, options, nfsx->name);
+ if (ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_LISTENERS_CREATE_FAIL,
+ "Unable to create listeners");
+ dict_unref(options);
+ goto err;
+ }
+
+ if (nfs->mount_udp) {
+ ret = gf_thread_create(&udp_thread, NULL, mount3udp_thread, nfsx,
+ "nfsudp");
+ if (ret) {
+ gf_msg_debug(GF_MNT, GF_LOG_DEBUG, "Thread creation failed");
}
- return &mnt3prog;
+ }
+ return &mnt3prog;
err:
- return NULL;
+ return NULL;
}
-
-rpcsvc_actor_t mnt1svc_actors[MOUNT1_PROC_COUNT] = {
- {"NULL", MOUNT1_NULL, mnt3svc_null, NULL, 0, DRC_NA},
- {"MNT", MOUNT1_MNT, NULL, NULL, 0, DRC_NA },
- {"DUMP", MOUNT1_DUMP, mnt3svc_dump, NULL, 0, DRC_NA},
- {"UMNT", MOUNT1_UMNT, mnt3svc_umnt, NULL, 0, DRC_NA},
- {"UMNTALL", MOUNT1_UMNTALL, NULL, NULL, 0, DRC_NA},
- {"EXPORT", MOUNT1_EXPORT, mnt3svc_export, NULL, 0, DRC_NA}
-};
-
-rpcsvc_program_t mnt1prog = {
- .progname = "MOUNT1",
- .prognum = MOUNT_PROGRAM,
- .progver = MOUNT_V1,
- .progport = GF_MOUNTV1_PORT,
- .actors = mnt1svc_actors,
- .numactors = MOUNT1_PROC_COUNT,
- .min_auth = AUTH_NULL,
- .synctask = _gf_true,
+rpcsvc_actor_t mnt1svc_actors[MOUNT1_PROC_COUNT] = {
+ {"NULL", MOUNT1_NULL, mnt3svc_null, NULL, 0, DRC_NA},
+ {"MNT", MOUNT1_MNT, NULL, NULL, 0, DRC_NA},
+ {"DUMP", MOUNT1_DUMP, mnt3svc_dump, NULL, 0, DRC_NA},
+ {"UMNT", MOUNT1_UMNT, mnt3svc_umnt, NULL, 0, DRC_NA},
+ {"UMNTALL", MOUNT1_UMNTALL, NULL, NULL, 0, DRC_NA},
+ {"EXPORT", MOUNT1_EXPORT, mnt3svc_export, NULL, 0, DRC_NA}};
+
+rpcsvc_program_t mnt1prog = {
+ .progname = "MOUNT1",
+ .prognum = MOUNT_PROGRAM,
+ .progver = MOUNT_V1,
+ .progport = GF_MOUNTV1_PORT,
+ .actors = mnt1svc_actors,
+ .numactors = MOUNT1_PROC_COUNT,
+ .min_auth = AUTH_NULL,
+ .synctask = _gf_true,
};
-
rpcsvc_program_t *
-mnt1svc_init (xlator_t *nfsx)
+mnt1svc_init(xlator_t *nfsx)
{
- struct mount3_state *mstate = NULL;
- struct nfs_state *nfs = NULL;
- dict_t *options = NULL;
- char *portstr = NULL;
- int ret = -1;
-
- if (!nfsx || !nfsx->private)
- return NULL;
-
- nfs = (struct nfs_state *)nfsx->private;
-
- gf_msg_debug (GF_MNT, GF_LOG_DEBUG, "Initing Mount v1 state");
- mstate = (struct mount3_state *)nfs->mstate;
- if (!mstate) {
- gf_msg (GF_MNT, GF_LOG_ERROR, EINVAL,
- NFS_MSG_MNT_STATE_INIT_FAIL,
- "Mount v3 state init failed");
- goto err;
- }
+ struct mount3_state *mstate = NULL;
+ struct nfs_state *nfs = NULL;
+ dict_t *options = NULL;
+ char *portstr = NULL;
+ int ret = -1;
+
+ if (!nfsx || !nfsx->private)
+ return NULL;
+
+ nfs = (struct nfs_state *)nfsx->private;
- mnt1prog.private = mstate;
+ gf_msg_debug(GF_MNT, GF_LOG_DEBUG, "Initing Mount v1 state");
+ mstate = (struct mount3_state *)nfs->mstate;
+ if (!mstate) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, EINVAL, NFS_MSG_MNT_STATE_INIT_FAIL,
+ "Mount v3 state init failed");
+ goto err;
+ }
- options = dict_new ();
+ mnt1prog.private = mstate;
- ret = gf_asprintf (&portstr, "%d", GF_MOUNTV1_PORT);
- if (ret == -1)
- goto err;
+ options = dict_new();
- ret = dict_set_dynstr (options, "transport.socket.listen-port", portstr);
- if (ret == -1)
- goto err;
- ret = dict_set_str (options, "transport-type", "socket");
+ ret = gf_asprintf(&portstr, "%d", GF_MOUNTV1_PORT);
+ if (ret == -1)
+ goto err;
+
+ ret = dict_set_dynstr(options, "transport.socket.listen-port", portstr);
+ if (ret == -1)
+ goto err;
+ ret = dict_set_str(options, "transport-type", "socket");
+ if (ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
+ "dict_set_str error");
+ goto err;
+ }
+
+ if (nfs->allow_insecure) {
+ ret = dict_set_str(options, "rpc-auth-allow-insecure", "on");
if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
- "dict_set_str error");
- goto err;
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
+ "dict_set_str error");
+ goto err;
}
-
- if (nfs->allow_insecure) {
- ret = dict_set_str (options, "rpc-auth-allow-insecure", "on");
- if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno,
- NFS_MSG_DICT_SET_FAILED,
- "dict_set_str error");
- goto err;
- }
- ret = dict_set_str (options, "rpc-auth.ports.insecure", "on");
- if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno,
- NFS_MSG_DICT_SET_FAILED,
- "dict_set_str error");
- goto err;
- }
+ ret = dict_set_str(options, "rpc-auth.ports.insecure", "on");
+ if (ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_DICT_SET_FAILED,
+ "dict_set_str error");
+ goto err;
}
+ }
#ifdef IPV6_DEFAULT
- ret = dict_set_str (options, "transport.address-family", "inet6");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "dict_set_str error when trying to enable ipv6");
- goto err;
- }
+ ret = dict_set_str(options, "transport.address-family", "inet6");
+ if (ret == -1) {
+ gf_log(GF_NFS, GF_LOG_ERROR,
+ "dict_set_str error when trying to enable ipv6");
+ goto err;
+ }
#endif
- ret = rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name);
- if (ret == -1) {
- gf_msg (GF_NFS, GF_LOG_ERROR, errno,
- NFS_MSG_LISTENERS_CREATE_FAIL,
- "Unable to create listeners");
- dict_unref (options);
- goto err;
- }
+ ret = rpcsvc_create_listeners(nfs->rpcsvc, options, nfsx->name);
+ if (ret == -1) {
+ gf_msg(GF_NFS, GF_LOG_ERROR, errno, NFS_MSG_LISTENERS_CREATE_FAIL,
+ "Unable to create listeners");
+ dict_unref(options);
+ goto err;
+ }
- return &mnt1prog;
+ return &mnt1prog;
err:
- return NULL;
+ return NULL;
}
int
-mount_reconfigure_state (xlator_t *nfsx, dict_t *options)
+mount_reconfigure_state(xlator_t *nfsx, dict_t *options)
{
- int ret = -1;
- struct nfs_state *nfs = NULL;
- struct mount3_state *ms = NULL;
- struct mnt3_export *exp = NULL;
- struct mnt3_export *texp = NULL;
-
- if ((!nfsx) || (!options))
- return (-1);
-
- nfs = (struct nfs_state *)nfs_state (nfsx);
- if (!nfs)
- return (-1);
-
- ms = nfs->mstate;
- if (!ms)
- return (-1);
-
- /*
- * Free() up the old export list. mnt3_init_options() will
- * rebuild the export list from scratch. Do it with locking
- * to avoid unnecessary race conditions.
- */
- LOCK (&ms->mountlock);
- list_for_each_entry_safe (exp, texp, &ms->exportlist, explist) {
- list_del (&exp->explist);
- mnt3_export_free (exp);
- }
- ret = mnt3_init_options (ms, options);
- UNLOCK (&ms->mountlock);
-
- if (ret < 0) {
- gf_msg (GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RECONF_FAIL,
- "Options reconfigure failed");
- return (-1);
- }
-
- return (0);
+ int ret = -1;
+ struct nfs_state *nfs = NULL;
+ struct mount3_state *ms = NULL;
+ struct mnt3_export *exp = NULL;
+ struct mnt3_export *texp = NULL;
+
+ if ((!nfsx) || (!options))
+ return (-1);
+
+ nfs = (struct nfs_state *)nfs_state(nfsx);
+ if (!nfs)
+ return (-1);
+
+ ms = nfs->mstate;
+ if (!ms)
+ return (-1);
+
+ /*
+ * Free() up the old export list. mnt3_init_options() will
+ * rebuild the export list from scratch. Do it with locking
+ * to avoid unnecessary race conditions.
+ */
+ LOCK(&ms->mountlock);
+ list_for_each_entry_safe(exp, texp, &ms->exportlist, explist)
+ {
+ list_del(&exp->explist);
+ mnt3_export_free(exp);
+ }
+ ret = mnt3_init_options(ms, options);
+ UNLOCK(&ms->mountlock);
+
+ if (ret < 0) {
+ gf_msg(GF_MNT, GF_LOG_ERROR, ret, NFS_MSG_RECONF_FAIL,
+ "Options reconfigure failed");
+ return (-1);
+ }
+
+ return (0);
}