diff options
Diffstat (limited to 'contrib/macfuse')
| -rw-r--r-- | contrib/macfuse/fuse_param.h | 97 | ||||
| -rw-r--r-- | contrib/macfuse/mount_darwin.c | 459 |
2 files changed, 240 insertions, 316 deletions
diff --git a/contrib/macfuse/fuse_param.h b/contrib/macfuse/fuse_param.h index 81d753c6cd7..347db9464bc 100644 --- a/contrib/macfuse/fuse_param.h +++ b/contrib/macfuse/fuse_param.h @@ -1,4 +1,9 @@ /* + * 'rebel' branch modifications: + * Copyright (C) 2010 Tuxera. All Rights Reserved. + */ + +/* * Copyright (C) 2006-2008 Google. All Rights Reserved. * Amit Singh <singh@> */ @@ -6,69 +11,81 @@ #ifndef _FUSE_PARAM_H_ #define _FUSE_PARAM_H_ -/* Compile-time tunables (M_MACFUSE*) */ - -#define M_MACFUSE_ENABLE_FIFOFS 0 -#define M_MACFUSE_ENABLE_INTERRUPT 1 -#define M_MACFUSE_ENABLE_SPECFS 0 -#define M_MACFUSE_ENABLE_TSLOCKING 0 -#define M_MACFUSE_ENABLE_UNSUPPORTED 1 -#define M_MACFUSE_ENABLE_XATTR 1 - -#if M_MACFUSE_ENABLE_UNSUPPORTED - #define M_MACFUSE_ENABLE_DSELECT 0 - #define M_MACFUSE_ENABLE_EXCHANGE 1 - #define M_MACFUSE_ENABLE_KQUEUE 1 - #define M_MACFUSE_ENABLE_KUNC 0 -#if __LP64__ - #define M_MACFUSE_ENABLE_INTERIM_FSNODE_LOCK 1 -#endif /* __LP64__ */ -#endif /* M_MACFUSE_ENABLE_UNSUPPORTED */ - -#if M_MACFUSE_ENABLE_INTERIM_FSNODE_LOCK -#define FUSE_VNOP_EXPORT __private_extern__ +#include <AvailabilityMacros.h> + +/* Compile-time tunables (M_OSXFUSE*) */ + +#define M_OSXFUSE_ENABLE_FIFOFS 0 +#define M_OSXFUSE_ENABLE_INTERRUPT 1 +#define M_OSXFUSE_ENABLE_SPECFS 0 +#define M_OSXFUSE_ENABLE_TSLOCKING 1 +#define M_OSXFUSE_ENABLE_UNSUPPORTED 1 +#define M_OSXFUSE_ENABLE_XATTR 1 +#define M_OSXFUSE_ENABLE_DSELECT 1 + +#if M_OSXFUSE_ENABLE_UNSUPPORTED +# define M_OSXFUSE_ENABLE_EXCHANGE 1 +# define M_OSXFUSE_ENABLE_KUNC 0 +# define M_OSXFUSE_ENABLE_INTERIM_FSNODE_LOCK 1 +#endif /* M_OSXFUSE_ENABLE_UNSUPPORTED */ + +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +# if M_OSXFUSE_ENABLE_UNSUPPORTED + /* + * In Mac OS X 10.5 the file system implementation is responsible for + * posting kqueue events. Starting with Mac OS X 10.6 VFS took over that + * job. + */ +# define M_OSXFUSE_ENABLE_KQUEUE 1 +# endif +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ + +#if M_OSXFUSE_ENABLE_INTERIM_FSNODE_LOCK +# define M_OSXFUSE_ENABLE_HUGE_LOCK 0 +# define M_OSXFUSE_ENABLE_LOCK_LOGGING 0 +# define FUSE_VNOP_EXPORT __private_extern__ #else -#define FUSE_VNOP_EXPORT static -#endif /* M_MACFUSE_ENABLE_INTERIM_FSNODE_LOCK */ +# define FUSE_VNOP_EXPORT static +#endif /* M_OSXFUSE_ENABLE_INTERIM_FSNODE_LOCK */ /* User Control */ -#define MACFUSE_POSTUNMOUNT_SIGNAL SIGKILL +#define OSXFUSE_POSTUNMOUNT_SIGNAL SIGKILL #define MACOSX_ADMIN_GROUP_NAME "admin" -#define SYSCTL_MACFUSE_TUNABLES_ADMIN "macfuse.tunables.admin_group" -#define SYSCTL_MACFUSE_VERSION_NUMBER "macfuse.version.number" +#define SYSCTL_OSXFUSE_TUNABLES_ADMIN "osxfuse.tunables.admin_group" +#define SYSCTL_OSXFUSE_VERSION_NUMBER "osxfuse.version.number" /* Paths */ -#define MACFUSE_BUNDLE_PATH "/Library/Filesystems/fusefs.fs" -#define MACFUSE_KEXT MACFUSE_BUNDLE_PATH "/Support/fusefs.kext" -#define MACFUSE_LOAD_PROG MACFUSE_BUNDLE_PATH "/Support/load_fusefs" -#define MACFUSE_MOUNT_PROG MACFUSE_BUNDLE_PATH "/Support/mount_fusefs" +#define OSXFUSE_BUNDLE_PATH "/Library/Filesystems/osxfusefs.fs" +#define OSXFUSE_KEXT OSXFUSE_BUNDLE_PATH "/Support/osxfusefs.kext" +#define OSXFUSE_LOAD_PROG OSXFUSE_BUNDLE_PATH "/Support/load_osxfusefs" +#define OSXFUSE_MOUNT_PROG OSXFUSE_BUNDLE_PATH "/Support/mount_osxfusefs" #define SYSTEM_KEXTLOAD "/sbin/kextload" #define SYSTEM_KEXTUNLOAD "/sbin/kextunload" /* Compatible API version */ -#define MACFUSE_MIN_USER_VERSION_MAJOR 7 -#define MACFUSE_MIN_USER_VERSION_MINOR 5 +#define OSXFUSE_MIN_USER_VERSION_MAJOR 7 +#define OSXFUSE_MIN_USER_VERSION_MINOR 5 /* Device Interface */ /* - * This is the prefix ("fuse" by default) of the name of a FUSE device node - * in devfs. The suffix is the device number. "/dev/fuse0" is the first FUSE + * This is the prefix ("osxfuse" by default) of the name of a FUSE device node + * in devfs. The suffix is the device number. "/dev/osxfuse0" is the first FUSE * device by default. If you change the prefix from the default to something * else, the user-space FUSE library will need to know about it too. */ -#define MACFUSE_DEVICE_BASENAME "fuse" +#define OSXFUSE_DEVICE_BASENAME "osxfuse" /* - * This is the number of /dev/fuse<n> nodes we will create. <n> goes from - * 0 to (FUSE_NDEVICES - 1). + * This is the number of /dev/osxfuse<n> nodes we will create. <n> goes from + * 0 to (OSXFUSE_NDEVICES - 1). */ -#define MACFUSE_NDEVICES 24 +#define OSXFUSE_NDEVICES 24 /* * This is the default block size of the virtual storage devices that are @@ -131,13 +148,13 @@ /* User-Kernel IPC Buffer */ #define FUSE_MIN_USERKERNEL_BUFSIZE (128 * 1024) -#define FUSE_MAX_USERKERNEL_BUFSIZE (4096 * 1024) +#define FUSE_MAX_USERKERNEL_BUFSIZE (16 * 1024 * 1024) #define FUSE_REASONABLE_XATTRSIZE FUSE_MIN_USERKERNEL_BUFSIZE #endif /* KERNEL */ -#define FUSE_DEFAULT_USERKERNEL_BUFSIZE (4096 * 1024) +#define FUSE_DEFAULT_USERKERNEL_BUFSIZE (16 * 1024 * 1024) #define FUSE_LINK_MAX LINK_MAX #define FUSE_UIO_BACKUP_MAX 8 diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c index c485583e96b..d1d1c34e761 100644 --- a/contrib/macfuse/mount_darwin.c +++ b/contrib/macfuse/mount_darwin.c @@ -1,5 +1,5 @@ /* - * Derived from mount_bsd.c from the fuse distribution. + * Derived from mount_bsd.c from the fuse distribution. * * FUSE: Filesystem in Userspace * Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu> @@ -34,324 +34,231 @@ #include "fuse_param.h" #include "fuse_ioctl.h" -#include "glusterfs.h" -#include "logging.h" -#include "common-utils.h" +#include "glusterfs/glusterfs.h" +#include "glusterfs/logging.h" +#include "glusterfs/common-utils.h" #define GFFUSE_LOGERR(...) \ gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__) -static long -fuse_os_version_major_np(void) -{ - int ret = 0; - long major = 0; - char *c = NULL; - struct utsname u; - size_t oldlen; - - oldlen = sizeof(u.release); - - ret = sysctlbyname("kern.osrelease", u.release, &oldlen, NULL, 0); - if (ret != 0) { - return -1; - } - - c = strchr(u.release, '.'); - if (c == NULL) { - return -1; - } - - *c = '\0'; - - errno = 0; - major = strtol(u.release, NULL, 10); - if ((errno == EINVAL) || (errno == ERANGE)) { - return -1; - } - - return major; -} - -static int -fuse_running_under_rosetta(void) -{ - int result = 0; - int is_native = 1; - size_t sz = sizeof(result); - - int ret = sysctlbyname("sysctl.proc_native", &result, &sz, NULL, (size_t)0); - if ((ret == 0) && !result) { - is_native = 0; - } - - return !is_native; -} - -static int -loadkmod(void) -{ - int result = -1; - int pid, terminated_pid; - union wait status; - long major; - - major = fuse_os_version_major_np(); - - if (major < 9) { /* not Mac OS X 10.5+ */ - return EINVAL; - } - - pid = fork(); - - if (pid == 0) { - execl(MACFUSE_LOAD_PROG, MACFUSE_LOAD_PROG, NULL); - - /* exec failed */ - exit(ENOENT); - } - - require_action(pid != -1, Return, result = errno); - - while ((terminated_pid = wait4(pid, (int *)&status, 0, NULL)) < 0) { - /* retry if EINTR, else break out with error */ - if (errno != EINTR) { - break; - } - } - - if ((terminated_pid == pid) && (WIFEXITED(status))) { - result = WEXITSTATUS(status); - } else { - result = -1; - } - -Return: - check_noerr_string(result, strerror(errno)); - - return result; -} - int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param, - pid_t *mtab_pid /* not used on OS X */) + pid_t *mnt_pid, int status_fd) /* Not used on OS X */ { - int fd, pid; - int result; - char *fdnam, *dev; - const char *mountprog = MACFUSE_MOUNT_PROG; - sig_t chldf; + int fd = 0; + int pid = 0; + int ret = 0; + char *fdnam = NULL; + char *dev = NULL; + char vstr[4]; + unsigned vval = 0; + int i = 0; + + const char *mountprog = OSXFUSE_MOUNT_PROG; + sig_t chldf = SIG_ERR; + char version[MAXHOSTNAMELEN + 1] = { 0 }; + size_t version_len = MAXHOSTNAMELEN; + size_t version_len_desired = 0; + int r = 0; + char devpath[MAXPATHLEN] = { 0 };; + + if (!mountpoint) { + gf_log ("glustefs-fuse", GF_LOG_ERROR, + "missing or invalid mount point"); + goto err; + } - /* mount_fusefs should not try to spawn the daemon */ - setenv("MOUNT_FUSEFS_SAFE", "1", 1); + /* mount_fusefs should not try to spawn the daemon */ + setenv("MOUNT_FUSEFS_SAFE", "1", 1); - /* to notify mount_fusefs it's called from lib */ - setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1); + /* to notify mount_fusefs it's called from lib */ + setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1); - if (!mountpoint) { - fprintf(stderr, "missing or invalid mount point\n"); - return -1; - } + chldf = signal(SIGCHLD, SIG_DFL); /* So that we can wait4() below. */ - if (fuse_running_under_rosetta()) { - fprintf(stderr, "MacFUSE does not work under Rosetta\n"); - return -1; - } + if (chldf == SIG_ERR) { + gf_log ("glusterfs-fuse", GF_LOG_ERROR, + "signal() returned SIG_ERR: %s", + strerror(errno)); + goto err; + } - chldf = signal(SIGCHLD, SIG_DFL); /* So that we can wait4() below. */ + /* check for user<->kernel match. */ + ret = sysctlbyname(SYSCTL_OSXFUSE_VERSION_NUMBER, version, + &version_len, NULL, (size_t)0); + if (ret != 0) { + gf_log ("glustefs-fuse", GF_LOG_ERROR, + "sysctlbyname() returned error: %s", + strerror(errno)); + goto err; + } - result = loadkmod(); - if (result == EINVAL) - GFFUSE_LOGERR("OS X >= 10.5 (at least Leopard) required"); - else if (result == 0 || result == ENOENT || result == EBUSY) { - /* Module loaded, but now need to check for user<->kernel match. */ + /* sysctlbyname() includes the trailing '\0' in version_len */ + version_len_desired = sizeof ("2.x.y"); - char version[MAXHOSTNAMELEN + 1] = { 0 }; - size_t version_len = MAXHOSTNAMELEN; - size_t version_len_desired = 0; + if (version_len != version_len_desired) { + gf_log ("glusterfs-fuse", GF_LOG_ERROR, + "version length mismatch for OSXFUSE %s", + version); + ret = -1; + goto err; + } - result = sysctlbyname(SYSCTL_MACFUSE_VERSION_NUMBER, version, - &version_len, NULL, (size_t)0); - if (result == 0) { - /* sysctlbyname() includes the trailing '\0' in version_len */ - version_len_desired = strlen("2.x.y") + 1; - - if (version_len != version_len_desired) - result = -1; - } else - strcpy(version, "?.?.?"); - if (result == 0) { - char *ep; - char vstr[4]; - unsigned vval; - int i; - - for (i = 0; i < 3; i++) + for (i = 0; i < 3; i++) vstr[i] = version[2*i]; - vstr[3] = '\0'; - - vval = strtoul(vstr, &ep, 10); - if (*ep || vval < 203 || vval > 217) - result = -1; - else - gf_log("glusterfs-fuse", GF_LOG_INFO, - "MacFUSE kext version %s", version); - } - if (result != 0) - GFFUSE_LOGERR("MacFUSE version %s is not supported", version); - } else - GFFUSE_LOGERR("cannot load MacFUSE kext"); - if (result != 0) - return -1; - - fdnam = getenv("FUSE_DEV_FD"); - - if (fdnam) { - char *ep; - - fd = strtol(fdnam, &ep, 10); - if (*ep != '\0' || fd < 0) { - GFFUSE_LOGERR("invalid value given in FUSE_DEV_FD"); - return -1; + vstr[3] = '\0'; + + vval = strtoul(vstr, NULL, 10); + if (vval < 264) { + GFFUSE_LOGERR("OSXFUSE version %s is not supported", version); + ret = -1; + goto err; } - goto mount; - } + gf_log("glusterfs-fuse", GF_LOG_INFO, + "OSXFUSE kext version supported %s", version); - dev = getenv("FUSE_DEV_NAME"); - if (dev) { - if ((fd = open(dev, O_RDWR)) < 0) { - GFFUSE_LOGERR("failed to open device (%s)", strerror(errno)); - return -1; + fdnam = getenv("FUSE_DEV_FD"); + if (fdnam) { + fd = strtol(fdnam, NULL, 10); + if (fd < 0) { + GFFUSE_LOGERR("invalid value given in FUSE_DEV_FD"); + ret = -1; + goto err; + } + goto mount; } - } else { - int r, devidx = -1; - char devpath[MAXPATHLEN]; - - for (r = 0; r < MACFUSE_NDEVICES; r++) { - snprintf(devpath, MAXPATHLEN - 1, - _PATH_DEV MACFUSE_DEVICE_BASENAME "%d", r); - fd = open(devpath, O_RDWR); - if (fd >= 0) { - dev = devpath; - devidx = r; - break; - } + + dev = getenv("FUSE_DEV_NAME"); + if (!dev) { + for (r = 0; r < OSXFUSE_NDEVICES; r++) { + snprintf(devpath, MAXPATHLEN - 1, + _PATH_DEV OSXFUSE_DEVICE_BASENAME "%d", r); + if ((fd = open(devpath, O_RDWR)) < 0) { + GFFUSE_LOGERR("failed to open device %s (%s)", + devpath, + strerror(errno)); + goto err; + } + dev = devpath; + goto mount; + } } - if (devidx == -1) { - GFFUSE_LOGERR("failed to open device (%s)", strerror(errno)); - return -1; + + fd = open(dev, O_RDWR); + if (fd < 0) { + GFFUSE_LOGERR("failed to open device %s (%s)", dev, + strerror(errno)); + ret = -1; + goto err; } - } mount: - if (getenv("FUSE_NO_MOUNT") || ! mountpoint) - goto out; - - signal(SIGCHLD, chldf); - - pid = fork(); - - if (pid == -1) { - GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); - close(fd); - return -1; - } - - if (pid == 0) { + signal(SIGCHLD, chldf); pid = fork(); if (pid == -1) { - GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); - close(fd); - exit(1); + GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); + ret = -1; + goto err; } if (pid == 0) { - const char *argv[32]; - int a = 0; - char *opts = NULL; - - if (asprintf(&opts, "%s,fssubtype=glusterfs", mnt_param) == -1) { - GFFUSE_LOGERR("Out of memory"); - exit(1); - } - - if (! fdnam) - asprintf(&fdnam, "%d", fd); - - argv[a++] = mountprog; - if (opts) { - argv[a++] = "-o"; - argv[a++] = opts; - } - argv[a++] = fdnam; - argv[a++] = mountpoint; - argv[a++] = NULL; - - { - char title[MAXPATHLEN + 1] = { 0 }; - u_int32_t len = MAXPATHLEN; - int ret = proc_pidpath(getpid(), title, len); - if (ret) { - setenv("MOUNT_FUSEFS_DAEMON_PATH", title, 1); + pid = fork(); + if (pid == -1) { + GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); + ret = -1; + goto err; } - } - execvp(mountprog, (char **) argv); - GFFUSE_LOGERR("MacFUSE: failed to exec mount program (%s)", strerror(errno)); - exit(1); - } - _exit(0); - } - -out: - return fd; + if (pid == 0) { + const char *argv[32]; + int a = 0; + char *opts = NULL; + + if (asprintf(&opts, "%s,fssubtype=glusterfs", + mnt_param) == -1) { + GFFUSE_LOGERR("asprintf() error: %s", + strerror(errno)); + ret = -1; + goto err; + } + + if (!fdnam) + asprintf(&fdnam, "%d", fd); + + argv[a++] = mountprog; + if (opts) { + argv[a++] = "-o"; + argv[a++] = opts; + } + argv[a++] = fdnam; + argv[a++] = mountpoint; + argv[a++] = NULL; + + { + char title[MAXPATHLEN + 1] = { 0 }; + u_int32_t len = MAXPATHLEN; + int ret = proc_pidpath(getpid(), title, len); + if (ret) { + setenv("MOUNT_FUSEFS_DAEMON_PATH", + title, 1); + } + } + execvp(mountprog, (char **) argv); + GFFUSE_LOGERR("OSXFUSE: failed to exec mount" + " program (%s)", strerror(errno)); + _exit(1); + } + _exit(0); + } + ret = fd; +err: + if (ret == -1) { + if (fd > 0) { + close(fd); + } + } + return ret; } void gf_fuse_unmount(const char *mountpoint, int fd) { - int ret; - struct stat sbuf; - char dev[128]; - char resolved_path[PATH_MAX]; - char *ep, *rp = NULL; - - unsigned int hs_complete = 0; + int ret; + struct stat sbuf; + char dev[128]; + char resolved_path[PATH_MAX]; + char *ep, *rp = NULL; - ret = ioctl(fd, FUSEDEVIOCGETHANDSHAKECOMPLETE, &hs_complete); - if (ret || !hs_complete) { - return; - } - /* XXX does this have any use here? */ - ret = ioctl(fd, FUSEDEVIOCSETDAEMONDEAD, &fd); - if (ret) { - return; - } + unsigned int hs_complete = 0; - if (fstat(fd, &sbuf) == -1) { - return; - } + ret = ioctl(fd, FUSEDEVIOCGETHANDSHAKECOMPLETE, &hs_complete); + if (ret || !hs_complete) { + return; + } - devname_r(sbuf.st_rdev, S_IFCHR, dev, 128); + if (fstat(fd, &sbuf) == -1) { + return; + } - if (strncmp(dev, MACFUSE_DEVICE_BASENAME, - sizeof(MACFUSE_DEVICE_BASENAME) - 1)) { - return; - } + devname_r(sbuf.st_rdev, S_IFCHR, dev, 128); - strtol(dev + 4, &ep, 10); - if (*ep != '\0') { - return; - } + if (strncmp(dev, OSXFUSE_DEVICE_BASENAME, + sizeof(OSXFUSE_DEVICE_BASENAME) - 1)) { + return; + } - rp = realpath(mountpoint, resolved_path); - if (rp) { - ret = unmount(resolved_path, 0); - } + strtol(dev + sizeof(OSXFUSE_DEVICE_BASENAME) - 1, &ep, 10); + if (*ep != '\0') { + return; + } - close(fd); + rp = realpath(mountpoint, resolved_path); + if (rp) { + ret = unmount(resolved_path, 0); + } - return; + close(fd); + return; } |
