summaryrefslogtreecommitdiffstats
path: root/contrib/fuse-lib/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/fuse-lib/mount.c')
-rw-r--r--contrib/fuse-lib/mount.c87
1 files changed, 80 insertions, 7 deletions
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
index 922d9e464db..a7fd94de464 100644
--- a/contrib/fuse-lib/mount.c
+++ b/contrib/fuse-lib/mount.c
@@ -17,6 +17,11 @@
#endif
#define FUSE_DEVFD_ENV "_FUSE_DEVFD"
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#endif /* __FreeBSD__ */
/* FUSE: function is called fuse_kern_unmount() */
void
@@ -170,6 +175,55 @@ fuse_mount_fusermount (const char *mountpoint, char *fsname,
return ret;
}
+#if defined(__FreeBSD__)
+void
+build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
+ size_t len)
+{
+ int i;
+ if (*iovlen < 0)
+ return;
+ i = *iovlen;
+
+ *iov = realloc(*iov, sizeof **iov * (i + 2));
+ if (*iov == NULL) {
+ *iovlen = -1;
+ return;
+ }
+
+ (*iov)[i].iov_base = strdup(name);
+ (*iov)[i].iov_len = strlen(name) + 1;
+
+ i++;
+ (*iov)[i].iov_base = val;
+ if (len == (size_t) -1) {
+ if (val != NULL)
+ len = strlen(val) + 1;
+ else
+ len = 0;
+ }
+ (*iov)[i].iov_len = (int)len;
+ *iovlen = ++i;
+}
+
+/*
+ * This function is needed for compatibility with parameters
+ * which used to use the mount_argf() command for the old mount() syscall.
+ */
+void
+build_iovec_argf(struct iovec **iov, int *iovlen, const char *name,
+ const char *fmt, ...)
+{
+ va_list ap;
+ char val[255] = { 0 };
+
+ va_start(ap, fmt);
+ vsnprintf(val, sizeof(val), fmt, ap);
+ va_end(ap);
+ build_iovec(iov, iovlen, name, strdup(val), (size_t)-1);
+}
+#endif /* __FreeBSD__ */
+
static int
fuse_mount_sys (const char *mountpoint, char *fsname,
unsigned long mountflags, char *mnt_param, int fd)
@@ -188,8 +242,24 @@ fuse_mount_sys (const char *mountpoint, char *fsname,
goto out;
}
+
+#ifdef __FreeBSD__
+ struct iovec *iov = NULL;
+ int iovlen = 0;
+ build_iovec (&iov, &iovlen, "fstype", "fusefs", -1);
+ build_iovec (&iov, &iovlen, "subtype", "glusterfs", -1);
+ build_iovec (&iov, &iovlen, "fspath", mountpoint, -1);
+ build_iovec (&iov, &iovlen, "from", "/dev/fuse", -1);
+ build_iovec (&iov, &iovlen, "volname", source, -1);
+ build_iovec_argf (&iov, &iovlen, "fd", "%d", fd);
+ build_iovec_argf (&iov, &iovlen, "user_id", "%d", getuid());
+ build_iovec_argf (&iov, &iovlen, "group_id", "%d", getgid());
+ ret = nmount (iov, iovlen, mountflags);
+#else
ret = mount (source, mountpoint, fstype, mountflags,
mnt_param_mnt);
+#endif /* __FreeBSD__ */
+#ifdef GF_LINUX_HOST_OS
if (ret == -1 && errno == ENODEV) {
/* fs subtype support was added by 79c0b2df aka
v2.6.21-3159-g79c0b2d. Probably we have an
@@ -204,12 +274,13 @@ fuse_mount_sys (const char *mountpoint, char *fsname,
ret = mount (source, mountpoint, fstype, mountflags,
mnt_param_mnt);
}
+#endif /* GF_LINUX_HOST_OS */
if (ret == -1)
goto out;
else
mounted = 1;
-#ifndef __NetBSD__
+#ifdef GF_LINUX_HOST_OS
if (geteuid () == 0) {
char *newmnt = fuse_mnt_resolve_path ("fuse", mountpoint);
char *mnt_param_mtab = NULL;
@@ -238,10 +309,11 @@ fuse_mount_sys (const char *mountpoint, char *fsname,
goto out;
}
}
-#endif /* __NetBSD__ */
+#endif /* GF_LINUX_HOST_OS */
out:
if (ret == -1) {
+ GFFUSE_LOGERR("ret = -1\n");
if (mounted)
umount2 (mountpoint, 2); /* lazy umount */
}
@@ -282,15 +354,16 @@ 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, mountflags, mnt_param,
+ fd);
if (ret == -1) {
gf_log ("glusterfs-fuse", GF_LOG_INFO,
- "direct mount failed (%s), "
+ "direct mount failed (%s) errno %d, "
"retry to mount via fusermount",
- strerror (errno));
+ strerror (errno), errno);
- ret = fuse_mount_fusermount (mountpoint, fsname, mountflags,
- mnt_param, fd);
+ ret = fuse_mount_fusermount (mountpoint, fsname,
+ mountflags, mnt_param, fd);
}
if (ret == -1)