diff options
| -rw-r--r-- | contrib/fuse-include/fuse-mount.h | 3 | ||||
| -rw-r--r-- | contrib/fuse-lib/mount-gluster-compat.h | 42 | ||||
| -rw-r--r-- | contrib/fuse-lib/mount.c | 119 | ||||
| -rw-r--r-- | contrib/macfuse/mount_darwin.c | 3 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 9 | 
5 files changed, 151 insertions, 25 deletions
diff --git a/contrib/fuse-include/fuse-mount.h b/contrib/fuse-include/fuse-mount.h index 9358ac810e1..7a3756d92b8 100644 --- a/contrib/fuse-include/fuse-mount.h +++ b/contrib/fuse-include/fuse-mount.h @@ -8,6 +8,5 @@  */  void gf_fuse_unmount (const char *mountpoint, int fd); -int gf_fuse_mount (const char *mountpoint, char *fsname, -                   unsigned long mountflags, char *mnt_param, +int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,                     pid_t *mtab_pid, int status_fd); diff --git a/contrib/fuse-lib/mount-gluster-compat.h b/contrib/fuse-lib/mount-gluster-compat.h index 562f089dd1f..a16103e0fbb 100644 --- a/contrib/fuse-lib/mount-gluster-compat.h +++ b/contrib/fuse-lib/mount-gluster-compat.h @@ -30,17 +30,59 @@  #include <sys/wait.h>  #include <sys/mount.h> +#ifdef GF_LINUX_HOST_OS +typedef unsigned long mount_flag_t; +#endif +  #if defined(__NetBSD__)  #include <perfuse.h>  #define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)  #define MS_RDONLY MNT_RDONLY +#define MS_NOSUID MNT_NOSUID +#define MS_NODEV  MNT_NODEV +#define MS_NOATIME MNT_NOATIME +#define MS_NOEXEC MNT_NOEXEC +typedef int mount_flag_t;  #endif  #if defined(GF_DARWIN_HOST_OS) || defined(__FreeBSD__)  #include <sys/param.h>  #include <sys/mount.h>  #define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0) +#endif + +#if defined(__FreeBSD__)  #define MS_RDONLY MNT_RDONLY +#define MS_NOSUID MNT_NOSUID +/* "nodev"/MNT_NODEV was removed from FreBSD, as it became unneeded because "As + * of FreeBSD 6.0 device nodes may be created in regular file systems but such + * nodes cannot be used to access devices." (See + * https://freebsd.org/cgi/man.cgi?query=mknod&sektion=8 . + * Also see: + * - https://github.com/freebsd/freebsd/commit/266790a + * - https://github.com/freebsd/freebsd/commit/a5e716d + * - 700008 in + *   https://www.freebsd.org/doc/en/books/porters-handbook/versions-7.html .) + */ +#if __FreeBSD_version < 700008 +#define MS_NODEV  MNT_NODEV +#else +#define MS_NODEV  0 +#endif +#define MS_NOATIME MNT_NOATIME +#define MS_NOEXEC MNT_NOEXEC +#if __FreeBSD_version < 1000715 +typedef int  mount_flag_t; +#else +/* __FreeBSD_version was not bumped for this type change. Anyway, see + * https://github.com/freebsd/freebsd/commit/e8d76f8 + * and respective __FreeBSD_version: + * https://github.com/freebsd/freebsd/blob/e8d76f8/sys/sys/param.h#L61 . + * We use the subsequent value, 1000715, to switch. (Also see: + * https://www.freebsd.org/doc/en/books/porters-handbook/versions-10.html .) + */ +typedef long long mount_flag_t; +#endif  #endif  #ifdef GF_LINUX_HOST_OS diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c index bfe28d3a26a..1dfd2a71c05 100644 --- a/contrib/fuse-lib/mount.c +++ b/contrib/fuse-lib/mount.c @@ -106,8 +106,7 @@ escape (char *s)  static int  fuse_mount_fusermount (const char *mountpoint, char *fsname, -                       unsigned long mountflags, char *mnt_param, -                       int fd) +                       char *mnt_param, int fd)  {          int  pid = -1;          int  res = 0; @@ -130,8 +129,7 @@ fuse_mount_fusermount (const char *mountpoint, char *fsname,                  return -1;          }          ret = asprintf (&fm_mnt_params, -                        "%s%s,fsname=%s,nonempty,subtype=glusterfs", -                        (mountflags & MS_RDONLY) ? "ro," : "", +                        "%s,fsname=%s,nonempty,subtype=glusterfs",                          mnt_param, efsname);          FREE (efsname);          if (ret == -1) { @@ -224,19 +222,112 @@ build_iovec_argf(struct iovec **iov, int *iovlen, const char *name,  }  #endif /* __FreeBSD__ */ +struct mount_flags { +        const char *opt; +        mount_flag_t flag; +        int on; +} mount_flags[] = { +        /* We provide best effort cross platform support for mount flags by +         * defining the ones which are commonly used in Unix-like OS-es. +         */ +        {"ro",      MS_RDONLY,      1}, +        {"nosuid",  MS_NOSUID,      1}, +        {"nodev",   MS_NODEV,       1}, +        {"noatime", MS_NOATIME,     1}, +        {"noexec",  MS_NOEXEC,      1}, +#ifdef GF_LINUX_HOST_OS +        {"rw",      MS_RDONLY,      0}, +        {"suid",    MS_NOSUID,      0}, +        {"dev",     MS_NODEV,       0}, +        {"exec",    MS_NOEXEC,      0}, +        {"async",   MS_SYNCHRONOUS, 0}, +        {"sync",    MS_SYNCHRONOUS, 1}, +        {"atime",   MS_NOATIME,     0}, +        {"dirsync", MS_DIRSYNC,     1}, +#endif +        {NULL,      0,              0} +}; + +static int +mount_param_to_flag (char *mnt_param, mount_flag_t *mntflags, +                     char **mnt_param_new) +{ +        int i = 0; +        int j = 0; +        char *p = NULL; +        gf_boolean_t found = _gf_false; +        struct mount_flags *flag = NULL; + +        /* Allocate a buffer that will hold the mount parameters remaining +         * after the ones corresponding to mount flags are processed and +         * removed.The length of the original params are a good upper bound +         * of the size needed. +         */ +        *mnt_param_new = CALLOC (1, strlen (mnt_param) + 1); +        if (!*mnt_param_new) +                return -1; +        p = *mnt_param_new; + +        while (mnt_param[j]) { +                if (j > 0) +                        i = j+1; +                j = i; + +                /* Seek the delimiters. */ +                while (mnt_param[j] != ',' && mnt_param[j] != '\0') +                        j++; + +                found = _gf_false; +                for (flag = mount_flags; flag->opt; flag++) { +                        /* Compare the mount flag name to the param +                         * name at hand (from i to j in mnt_param). +                         */ +                        if (strlen (flag->opt) == j - i && +                            memcmp (flag->opt, mnt_param + i, j - i) == 0) { +                                /* If there is a match, adjust mntflags +                                 * accordingly and break. +                                 */ +                                if (flag->on) { +                                        *mntflags |= flag->flag; +                                } else { +                                        *mntflags &= ~flag->flag; +                                } +                                found = _gf_true; +                                break; +                        } +                } +                /* If the param did't match any flag name, retain it (ie. copy +                 * over to the new param buffer). +                 */ +                if (!found) { +                        if (p != *mnt_param_new) +                                *p++ = ','; +                        memcpy (p, mnt_param + i, j - i); +                        p += j - i; +                } +        } + +        return 0; +} +  static int  fuse_mount_sys (const char *mountpoint, char *fsname, -                unsigned long mountflags, char *mnt_param, int fd) +                char *mnt_param, int fd)  {          int ret = -1;          unsigned mounted = 0;          char *mnt_param_mnt = NULL;          char *fstype = "fuse.glusterfs";          char *source = fsname; - -        ret = asprintf (&mnt_param_mnt, -                        "%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i", -                        mnt_param, fd, S_IFDIR, getuid (), getgid ()); +        mount_flag_t mountflags = 0; +        char *mnt_param_new = NULL; + +        ret = mount_param_to_flag (mnt_param, &mountflags, &mnt_param_new); +        if (ret == 0) +                ret = asprintf (&mnt_param_mnt, +                                "%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i", +                                mnt_param_new, fd, S_IFDIR, getuid (), +                                getgid ());          if (ret == -1) {                  GFFUSE_LOGERR ("Out of memory"); @@ -295,7 +386,7 @@ fuse_mount_sys (const char *mountpoint, char *fsname,                  ret = asprintf (&mnt_param_mtab, "%s%s",                                  mountflags & MS_RDONLY ? "ro," : "", -                                mnt_param); +                                mnt_param_new);                  if (ret == -1)                          GFFUSE_LOGERR ("Out of memory");                  else { @@ -320,6 +411,7 @@ out:                          umount2 (mountpoint, 2); /* lazy umount */          }          FREE (mnt_param_mnt); +        FREE (mnt_param_new);          if (source != fsname)                  FREE (source); @@ -328,8 +420,7 @@ out:  int  gf_fuse_mount (const char *mountpoint, char *fsname, -               unsigned long mountflags, char *mnt_param, -               pid_t *mnt_pid, int status_fd) +               char *mnt_param, pid_t *mnt_pid, int status_fd)  {          int   fd  = -1;          pid_t pid = -1; @@ -356,8 +447,7 @@ gf_fuse_mount (const char *mountpoint, char *fsname,                                  exit (pid == -1 ? 1 : 0);                  } -                ret = fuse_mount_sys (mountpoint, fsname, mountflags, mnt_param, -                                      fd); +                ret = fuse_mount_sys (mountpoint, fsname, mnt_param, fd);                  if (ret == -1) {                          gf_log ("glusterfs-fuse", GF_LOG_INFO,                                  "direct mount failed (%s) errno %d", @@ -368,7 +458,6 @@ gf_fuse_mount (const char *mountpoint, char *fsname,                                          "retry to mount via fusermount");                                  ret = fuse_mount_fusermount (mountpoint, fsname, -                                                             mountflags,                                                               mnt_param, fd);                          }                  } diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c index 10eff204bc6..f4ecacad86a 100644 --- a/contrib/macfuse/mount_darwin.c +++ b/contrib/macfuse/mount_darwin.c @@ -42,8 +42,7 @@          gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)  int -gf_fuse_mount (const char *mountpoint, char *fsname, -               unsigned long mountflags, char *mnt_param, +gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,                 pid_t *mnt_pid, int status_fd) /* Not used on OS X */  {          int fd       = 0; diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 6e5cd63a818..7056b6fd164 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -10,7 +10,6 @@  #include <sys/wait.h>  #include "fuse-bridge.h" -#include "mount-gluster-compat.h"  #include "glusterfs.h"  #include "byte-order.h"  #include "compat-errno.h" @@ -5481,7 +5480,6 @@ init (xlator_t *this_xl)          glusterfs_ctx_t   *ctx = NULL;          gf_boolean_t       sync_to_mount = _gf_false;          gf_boolean_t       fopen_keep_cache = _gf_false; -        unsigned long      mntflags = 0;          char              *mnt_args = NULL;          eh_t              *event = NULL; @@ -5717,10 +5715,9 @@ init (xlator_t *this_xl)                  goto cleanup_exit;          } -        if (priv->read_only) -                mntflags |= MS_RDONLY; -        gf_asprintf (&mnt_args, "%s%s%sallow_other,max_read=131072", +        gf_asprintf (&mnt_args, "%s%s%s%sallow_other,max_read=131072",                       priv->acl ? "" : "default_permissions,", +                     priv->read_only ? "ro," : "",                       priv->fuse_mountopts ? priv->fuse_mountopts : "",                       priv->fuse_mountopts ? "," : "");          if (!mnt_args) @@ -5732,7 +5729,7 @@ init (xlator_t *this_xl)                  goto cleanup_exit;          } -        priv->fd = gf_fuse_mount (priv->mount_point, fsname, mntflags, mnt_args, +        priv->fd = gf_fuse_mount (priv->mount_point, fsname, mnt_args,                                    sync_to_mount ? &ctx->mnt_pid : NULL,                                    priv->status_pipe[1]);          if (priv->fd == -1)  | 
