diff options
Diffstat (limited to 'contrib')
-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 |
4 files changed, 148 insertions, 19 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; |