diff options
| author | Csaba Henk <csaba@gluster.com> | 2010-05-17 07:06:58 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-05-21 00:31:41 -0700 | 
| commit | 18d982e6d0d330af8ccd2b12252ae29fe0932023 (patch) | |
| tree | f13c3ac28b549d5bf343715de32d16b28d93ab3c | |
| parent | 86ee9d3e144d2371e5ae7edf663916b8da6d2616 (diff) | |
OS X: basic additions for OS X client support
Signed-off-by: Csaba Henk <csaba@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 361 (GlusterFS 3.0 should work on Mac OS/X)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=361
| -rw-r--r-- | configure.ac | 15 | ||||
| -rw-r--r-- | contrib/fuse-include/fuse_kernel_macfuse.h | 439 | ||||
| -rw-r--r-- | contrib/macfuse/COPYING.txt | 128 | ||||
| -rw-r--r-- | contrib/macfuse/fuse_ioctl.h | 64 | ||||
| -rw-r--r-- | contrib/macfuse/fuse_param.h | 147 | ||||
| -rw-r--r-- | contrib/macfuse/mount_darwin.c | 355 | ||||
| -rw-r--r-- | doc/translator-options.txt | 1 | ||||
| -rw-r--r-- | glusterfsd/src/glusterfsd.c | 16 | ||||
| -rw-r--r-- | libglusterfs/src/compat.h | 14 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 5 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/Makefile.am | 11 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 140 | ||||
| -rw-r--r-- | xlators/storage/bdb/src/bdb-ll.c | 2 | 
13 files changed, 1290 insertions, 47 deletions
diff --git a/configure.ac b/configure.ac index 8bc498218..7c1ef206f 100644 --- a/configure.ac +++ b/configure.ac @@ -158,6 +158,14 @@ AC_CHECK_HEADERS([sys/xattr.h])  AC_CHECK_HEADERS([sys/extattr.h]) +case $host_os in +  darwin*) +    if ! test "`/usr/bin/sw_vers | grep ProductVersion: | cut -f 2 | cut -d. -f2`" -ge 5; then +      AC_MSG_ERROR([You need at least OS X 10.5 (Leopard) to build Glusterfs]) +    fi +    ;; +esac +  dnl Mac OS X does not have spinlocks  AC_CHECK_FUNC([pthread_spin_init], [have_spinlock=yes])  if test "x${have_spinlock}" = "xyes"; then @@ -333,6 +341,7 @@ case $host_os in  	GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS}"  	GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"  	GF_LDADD="${ARGP_STANDALONE_LDADD}" +	GF_FUSE_CFLAGS="-DFUSERMOUNT_DIR=\\\"\$(bindir)\\\""  	;;       solaris*)          GF_HOST_OS="GF_SOLARIS_HOST_OS" @@ -352,7 +361,7 @@ case $host_os in  	if test "x$ac_cv_header_execinfo_h" = "xyes"; then  	   GF_GLUSTERFS_LDFLAGS="-lexecinfo"  	fi				       -	GF_FUSE_LDADD="-liconv -lfuse" +	BUILD_FUSE_CLIENT=no  	;;       darwin*)          GF_HOST_OS="GF_DARWIN_HOST_OS" @@ -360,7 +369,7 @@ case $host_os in  	GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -bundle -undefined suppress -flat_namespace"  	GF_GLUSTERFS_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -undefined suppress -flat_namespace"  	GF_LDADD="${ARGP_STANDALONE_LDADD}" -	GF_FUSE_LDADD="-liconv -lfuse_ino64" +	GF_FUSE_CFLAGS="-I\$(CONTRIBDIR)/macfuse"  	;;  esac @@ -370,7 +379,7 @@ AC_SUBST(GF_GLUSTERFS_CFLAGS)  AC_SUBST(GF_CFLAGS)  AC_SUBST(GF_LDFLAGS)  AC_SUBST(GF_LDADD) -AC_SUBST(GF_FUSE_LDADD) +AC_SUBST(GF_FUSE_CFLAGS)  CONTRIBDIR='$(top_srcdir)/contrib'  AC_SUBST(CONTRIBDIR) diff --git a/contrib/fuse-include/fuse_kernel_macfuse.h b/contrib/fuse-include/fuse_kernel_macfuse.h new file mode 100644 index 000000000..3fbf24f70 --- /dev/null +++ b/contrib/fuse-include/fuse_kernel_macfuse.h @@ -0,0 +1,439 @@ +/* +    This file defines the kernel interface of FUSE +    Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu> + +    This program can be distributed under the terms of the GNU GPL. +    See the file COPYING. + +    This -- and only this -- header file may also be distributed under +    the terms of the BSD Licence as follows: + +    Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved. + +    Redistribution and use in source and binary forms, with or without +    modification, are permitted provided that the following conditions +    are met: +    1. Redistributions of source code must retain the above copyright +       notice, this list of conditions and the following disclaimer. +    2. Redistributions in binary form must reproduce the above copyright +       notice, this list of conditions and the following disclaimer in the +       documentation and/or other materials provided with the distribution. + +    THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +    ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +    SUCH DAMAGE. +*/ + +#ifndef linux +#include <sys/types.h> +#define __u64 uint64_t +#define __u32 uint32_t +#define __s32 int32_t +#else +#include <asm/types.h> +#include <linux/major.h> +#endif + +/** Version number of this interface */ +#define FUSE_KERNEL_VERSION 7 + +/** Minor version number of this interface */ +#define FUSE_KERNEL_MINOR_VERSION 8 + +/** The node ID of the root inode */ +#define FUSE_ROOT_ID 1 + +/** The major number of the fuse character device */ +#define FUSE_MAJOR MISC_MAJOR + +/** The minor number of the fuse character device */ +#define FUSE_MINOR 229 + +/* Make sure all structures are padded to 64bit boundary, so 32bit +   userspace works under 64bit kernels */ + +struct fuse_attr { +	__u64	ino; +	__u64	size; +	__u64	blocks; +	__u64	atime; +	__u64	mtime; +	__u64	ctime; +#if (__FreeBSD__ >= 10) +	__u64	crtime; +#endif /* __FreeBSD__ >= 10 */ +	__u32	atimensec; +	__u32	mtimensec; +	__u32	ctimensec; +#if (__FreeBSD__ >= 10) +	__u32	crtimensec; +#endif /* __FreeBSD__ >= 10 */ +	__u32	mode; +	__u32	nlink; +	__u32	uid; +	__u32	gid; +	__u32	rdev; +#if (__FreeBSD__ >= 10) +	__u32	flags; /* file flags; see chflags(2) */ +#endif /* __FreeBSD__ >= 10 */ +}; + +struct fuse_kstatfs { +	__u64	blocks; +	__u64	bfree; +	__u64	bavail; +	__u64	files; +	__u64	ffree; +	__u32	bsize; +	__u32	namelen; +	__u32	frsize; +	__u32	padding; +	__u32	spare[6]; +}; + +struct fuse_file_lock { +	__u64	start; +	__u64	end; +	__u32	type; +	__u32	pid; /* tgid */ +}; + +/** + * Bitmasks for fuse_setattr_in.valid + */ +#define FATTR_MODE	(1 << 0) +#define FATTR_UID	(1 << 1) +#define FATTR_GID	(1 << 2) +#define FATTR_SIZE	(1 << 3) +#define FATTR_ATIME	(1 << 4) +#define FATTR_MTIME	(1 << 5) +#define FATTR_FH	(1 << 6) +#if (__FreeBSD__ >= 10) +#define FATTR_CRTIME	(1 << 28) +#define FATTR_CHGTIME	(1 << 29) +#define FATTR_BKUPTIME	(1 << 30) +#define FATTR_FLAGS	(1 << 31) +#endif /* __FreeBSD__ >= 10 */ + +/** + * Flags returned by the OPEN request + * + * FOPEN_DIRECT_IO: bypass page cache for this open file + * FOPEN_KEEP_CACHE: don't invalidate the data cache on open + */ +#define FOPEN_DIRECT_IO		(1 << 0) +#define FOPEN_KEEP_CACHE	(1 << 1) +#if (__FreeBSD__ >= 10) +#define FOPEN_PURGE_ATTR	(1 << 30) +#define FOPEN_PURGE_UBC		(1 << 31) +#endif + +/** + * INIT request/reply flags + */ +#define FUSE_ASYNC_READ		(1 << 0) +#define FUSE_POSIX_LOCKS	(1 << 1) +#if (__FreeBSD__ >= 10) +#define FUSE_CASE_INSENSITIVE	(1 << 29) +#define FUSE_VOL_RENAME		(1 << 30) +#define FUSE_XTIMES		(1 << 31) +#endif /* __FreeBSD__ >= 10 */ + +/** + * Release flags + */ +#define FUSE_RELEASE_FLUSH	(1 << 0) + +enum fuse_opcode { +	FUSE_LOOKUP	   = 1, +	FUSE_FORGET	   = 2,  /* no reply */ +	FUSE_GETATTR	   = 3, +	FUSE_SETATTR	   = 4, +	FUSE_READLINK	   = 5, +	FUSE_SYMLINK	   = 6, +	FUSE_MKNOD	   = 8, +	FUSE_MKDIR	   = 9, +	FUSE_UNLINK	   = 10, +	FUSE_RMDIR	   = 11, +	FUSE_RENAME	   = 12, +	FUSE_LINK	   = 13, +	FUSE_OPEN	   = 14, +	FUSE_READ	   = 15, +	FUSE_WRITE	   = 16, +	FUSE_STATFS	   = 17, +	FUSE_RELEASE       = 18, +	FUSE_FSYNC         = 20, +	FUSE_SETXATTR      = 21, +	FUSE_GETXATTR      = 22, +	FUSE_LISTXATTR     = 23, +	FUSE_REMOVEXATTR   = 24, +	FUSE_FLUSH         = 25, +	FUSE_INIT          = 26, +	FUSE_OPENDIR       = 27, +	FUSE_READDIR       = 28, +	FUSE_RELEASEDIR    = 29, +	FUSE_FSYNCDIR      = 30, +	FUSE_GETLK         = 31, +	FUSE_SETLK         = 32, +	FUSE_SETLKW        = 33, +	FUSE_ACCESS        = 34, +	FUSE_CREATE        = 35, +	FUSE_INTERRUPT     = 36, +	FUSE_BMAP          = 37, +	FUSE_DESTROY       = 38, +#if (__FreeBSD__ >= 10) +        FUSE_SETVOLNAME    = 61, +	FUSE_GETXTIMES     = 62, +	FUSE_EXCHANGE      = 63, +#endif /* __FreeBSD__ >= 10 */ +}; + +/* The read buffer is required to be at least 8k, but may be much larger */ +#define FUSE_MIN_READ_BUFFER 8192 + +struct fuse_entry_out { +	__u64	nodeid;		/* Inode ID */ +	__u64	generation;	/* Inode generation: nodeid:gen must +				   be unique for the fs's lifetime */ +	__u64	entry_valid;	/* Cache timeout for the name */ +	__u64	attr_valid;	/* Cache timeout for the attributes */ +	__u32	entry_valid_nsec; +	__u32	attr_valid_nsec; +	struct fuse_attr attr; +}; + +struct fuse_forget_in { +	__u64	nlookup; +}; + +struct fuse_attr_out { +	__u64	attr_valid;	/* Cache timeout for the attributes */ +	__u32	attr_valid_nsec; +	__u32	dummy; +	struct fuse_attr attr; +}; + +#if (__FreeBSD__ >= 10) +struct fuse_getxtimes_out { +	__u64	bkuptime; +	__u64	crtime; +	__u32	bkuptimensec; +	__u32	crtimensec; +}; +#endif /* __FreeBSD__ >= 10 */ + +struct fuse_mknod_in { +	__u32	mode; +	__u32	rdev; +}; + +struct fuse_mkdir_in { +	__u32	mode; +	__u32	padding; +}; + +struct fuse_rename_in { +	__u64	newdir; +}; + +#if (__FreeBSD__ >= 10) +struct fuse_exchange_in { +	__u64	olddir; +	__u64	newdir; +	__u64	options; +}; +#endif /* __FreeBSD__ >= 10 */ + +struct fuse_link_in { +	__u64	oldnodeid; +}; + +struct fuse_setattr_in { +	__u32	valid; +	__u32	padding; +	__u64	fh; +	__u64	size; +	__u64	unused1; +	__u64	atime; +	__u64	mtime; +	__u64	unused2; +	__u32	atimensec; +	__u32	mtimensec; +	__u32	unused3; +	__u32	mode; +	__u32	unused4; +	__u32	uid; +	__u32	gid; +	__u32	unused5; +#if (__FreeBSD__ >= 10) +	__u64	bkuptime; +	__u64	chgtime; +	__u64	crtime; +	__u32	bkuptimensec; +	__u32	chgtimensec; +	__u32	crtimensec; +	__u32	flags; /* file flags; see chflags(2) */ +#endif /* __FreeBSD__ >= 10 */ +}; + +struct fuse_open_in { +	__u32	flags; +	__u32	mode; +}; + +struct fuse_open_out { +	__u64	fh; +	__u32	open_flags; +	__u32	padding; +}; + +struct fuse_release_in { +	__u64	fh; +	__u32	flags; +	__u32	release_flags; +	__u64	lock_owner; +}; + +struct fuse_flush_in { +	__u64	fh; +	__u32	unused; +	__u32	padding; +	__u64	lock_owner; +}; + +struct fuse_read_in { +	__u64	fh; +	__u64	offset; +	__u32	size; +	__u32	padding; +}; + +struct fuse_write_in { +	__u64	fh; +	__u64	offset; +	__u32	size; +	__u32	write_flags; +}; + +struct fuse_write_out { +	__u32	size; +	__u32	padding; +}; + +#define FUSE_COMPAT_STATFS_SIZE 48 + +struct fuse_statfs_out { +	struct fuse_kstatfs st; +}; + +struct fuse_fsync_in { +	__u64	fh; +	__u32	fsync_flags; +	__u32	padding; +}; + +struct fuse_setxattr_in { +	__u32	size; +	__u32	flags; +#if (__FreeBSD__ >= 10) +	__u32	position; +	__u32	padding; +#endif /* __FreeBSD__ >= 10 */ +}; + +struct fuse_getxattr_in { +	__u32	size; +	__u32	padding; +#if (__FreeBSD__ >= 10) +	__u32	position; +	__u32	padding2; +#endif /* __FreeBSD__ >= 10 */ +}; + +struct fuse_getxattr_out { +	__u32	size; +	__u32	padding; +}; + +struct fuse_lk_in { +	__u64	fh; +	__u64	owner; +	struct fuse_file_lock lk; +}; + +struct fuse_lk_out { +	struct fuse_file_lock lk; +}; + +struct fuse_access_in { +	__u32	mask; +	__u32	padding; +}; + +struct fuse_init_in { +	__u32	major; +	__u32	minor; +	__u32	max_readahead; +	__u32	flags; +}; + +struct fuse_init_out { +	__u32	major; +	__u32	minor; +	__u32	max_readahead; +	__u32	flags; +	__u32	unused; +	__u32	max_write; +}; + +struct fuse_interrupt_in { +	__u64	unique; +}; + +struct fuse_bmap_in { +	__u64	block; +	__u32	blocksize; +	__u32	padding; +}; + +struct fuse_bmap_out { +	__u64	block; +}; + +struct fuse_in_header { +	__u32	len; +	__u32	opcode; +	__u64	unique; +	__u64	nodeid; +	__u32	uid; +	__u32	gid; +	__u32	pid; +	__u32	padding; +}; + +struct fuse_out_header { +	__u32	len; +	__s32	error; +	__u64	unique; +}; + +struct fuse_dirent { +	__u64	ino; +	__u64	off; +	__u32	namelen; +	__u32	type; +	char name[0]; +}; + +#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) +#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1)) +#define FUSE_DIRENT_SIZE(d) \ +	FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) diff --git a/contrib/macfuse/COPYING.txt b/contrib/macfuse/COPYING.txt new file mode 100644 index 000000000..3f89bb08d --- /dev/null +++ b/contrib/macfuse/COPYING.txt @@ -0,0 +1,128 @@ +MacFUSE is a package developed by Google and is covered under the following +BSD-style license: + +    ================================================================ +    Copyright (c) 2007-2009 Google Inc. +    All rights reserved. + +    Redistribution and use in source and binary forms, with or without +    modification, are permitted provided that the following conditions are +    met: + +    * Redistributions of source code must retain the above copyright +      notice, this list of conditions and the following disclaimer. +    * Redistributions in binary form must reproduce the above +      copyright notice, this list of conditions and the following disclaimer +      in the documentation and/or other materials provided with the +      distribution. +    * Neither the name of Google Inc. nor the names of its +      contributors may be used to endorse or promote products derived from +      this software without specific prior written permission. + +    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +    ================================================================ + +Note that Google's patches to the FUSE library (libfuse/*.patch) (and to +the SSHFS user-space program (filesystems/sshfs/*.patch) are also released +under the BSD license. + +Portions of this package were derived from code developed by other authors. +Please read further for specific details. + +* fusefs/fuse_kernel.h is an unmodified copy of the interface header from +  the Linux FUSE distribution (http://fuse.sourceforge.net). fuse_kernel.h +  can be redistributed either under the GPL or under the BSD license. It +  is being redistributed here under the BSD license. + +* Unless otherwise noted, parts of MacFUSE (multiple files in fusefs/) contain +  code derived from the FreeBSD version of FUSE (http://fuse4bsd.creo.hu), +  which is covered by the following BSD-style license: + +    ================================================================ +    Copyright (C) 2005 Csaba Henk. All rights reserved. +    +    Redistribution and use in source and binary forms, with or without +    modification, are permitted provided that the following conditions +    are met: +    1. Redistributions of source code must retain the above copyright +       notice, this list of conditions and the following disclaimer. +    2. Redistributions in binary form must reproduce the above copyright +       notice, this list of conditions and the following disclaimer in the +       documentation and/or other materials provided with the distribution. +    +    THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +    ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +    SUCH DAMAGE. +    ================================================================ + +* fusefs/fuse_nodehash.c is a modified version of HashNode.c from an +  Apple Developer Technical Support (DTS) sample code example. The original +  source, which is available on http://developer.apple.com/samplecode/, has +  the following disclaimer: + +    ================================================================ +    Disclaimer: IMPORTANT: This Apple software is supplied to you by +    Apple Computer, Inc. Apple") in consideration of your agreement +    to the following terms, and your use, installation, modification +    or redistribution of this Apple software constitutes acceptance +    of these terms.  If you do not agree with these terms, please do +    not use, install, modify or redistribute this Apple software. + +    In consideration of your agreement to abide by the following terms, +    and subject to these terms, Apple grants you a personal, non-exclusive +    license, under Apple's copyrights in this original Apple software +    (the "Apple Software"), to use, reproduce, modify and redistribute +    the Apple Software, with or without modifications, in source and/or +    binary forms; provided that if you redistribute the Apple Software +    in its entirety and without modifications, you must retain this +    notice and the following text and disclaimers in all such +    redistributions of the Apple Software.  Neither the name, +    trademarks, service marks or logos of Apple Computer, Inc. may be +    used to endorse or promote products derived from the Apple Software +    without specific prior written permission from Apple.  Except as +    expressly stated in this notice, no other rights or licenses, +    express or implied, are granted by Apple herein, including but +    not limited to any patent rights that may be infringed by your +    derivative works or by other works in which the Apple Software +    may be incorporated. + +    The Apple Software is provided by Apple on an "AS IS" basis.  APPLE +    MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +    THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND +    FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR +    ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + +    IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, +    INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +    PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, +    REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, +    HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING +    NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN +    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +    ================================================================ + +* Parts of the mount_fusefs and the load_fusefs command-line programs +  (implemented in fusefs/mount_fusefs/ and fusefs/load_fusefs/, respectively) +  come from Apple's Darwin sources and are covered under the Apple Public +  Source License (APSL). You can read the APSL at: + +  http://www.publicsource.apple.com/apsl/ diff --git a/contrib/macfuse/fuse_ioctl.h b/contrib/macfuse/fuse_ioctl.h new file mode 100644 index 000000000..054968cb1 --- /dev/null +++ b/contrib/macfuse/fuse_ioctl.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006-2008 Google. All Rights Reserved. + * Amit Singh <singh@> + */ + +#ifndef _FUSE_IOCTL_H_ +#define _FUSE_IOCTL_H_ + +#include <stdint.h> +#include <sys/ioctl.h> + +/* FUSEDEVIOCxxx */ + +/* Get mounter's pid. */ +#define FUSEDEVGETMOUNTERPID           _IOR('F', 1,  u_int32_t) + +/* Check if FUSE_INIT kernel-user handshake is complete. */ +#define FUSEDEVIOCGETHANDSHAKECOMPLETE _IOR('F', 2,  u_int32_t) + +/* Mark the daemon as dead. */ +#define FUSEDEVIOCSETDAEMONDEAD        _IOW('F', 3,  u_int32_t) + +/* Tell the kernel which operations the daemon implements. */ +#define FUSEDEVIOCSETIMPLEMENTEDBITS   _IOW('F', 4,  u_int64_t) + +/* Get device's random "secret". */ +#define FUSEDEVIOCGETRANDOM            _IOR('F', 5, u_int32_t) + +/* + * The 'AVFI' (alter-vnode-for-inode) ioctls all require an inode number + * as an argument. In the user-space library, you can get the inode number + * from a path by using fuse_lookup_inode_by_path_np() [lib/fuse.c]. + * + * To see an example of using this, see the implementation of + * fuse_purge_path_np() in lib/fuse_darwin.c. + */ + +struct fuse_avfi_ioctl { +    uint64_t inode; +    uint64_t cmd; +    uint32_t ubc_flags; +    uint32_t note; +    off_t    size; +}; + +/* Alter the vnode (if any) specified by the given inode. */ +#define FUSEDEVIOCALTERVNODEFORINODE  _IOW('F', 6,  struct fuse_avfi_ioctl) +#define FSCTLALTERVNODEFORINODE       IOCBASECMD(FUSEDEVIOCALTERVNODEFORINODE) + +/* + * Possible cmd values for AVFI. + */ + +#define FUSE_AVFI_MARKGONE       0x00000001 /* no ubc_flags   */ +#define FUSE_AVFI_PURGEATTRCACHE 0x00000002 /* no ubc_flags   */ +#define FUSE_AVFI_PURGEVNCACHE   0x00000004 /* no ubc_flags   */ +#define FUSE_AVFI_UBC            0x00000008 /* uses ubc_flags */ +#define FUSE_AVFI_UBC_SETSIZE    0x00000010 /* uses ubc_flags, size */ +#define FUSE_AVFI_KNOTE          0x00000020 /* uses note */ + +#define FUSE_SETACLSTATE              _IOW('h', 10, int32_t) +#define FSCTLSETACLSTATE              IOCBASECMD(FUSE_SETACLSTATE) + +#endif /* _FUSE_IOCTL_H_ */ diff --git a/contrib/macfuse/fuse_param.h b/contrib/macfuse/fuse_param.h new file mode 100644 index 000000000..81d753c6c --- /dev/null +++ b/contrib/macfuse/fuse_param.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2006-2008 Google. All Rights Reserved. + * Amit Singh <singh@> + */ + +#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__ +#else +#define FUSE_VNOP_EXPORT static +#endif /* M_MACFUSE_ENABLE_INTERIM_FSNODE_LOCK */ + +/* User Control */ + +#define MACFUSE_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" + +/* 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 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 + +/* 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 + * 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" + +/* + * This is the number of /dev/fuse<n> nodes we will create. <n> goes from + * 0 to (FUSE_NDEVICES - 1). + */ +#define MACFUSE_NDEVICES                   24 + +/* + * This is the default block size of the virtual storage devices that are + * implicitly implemented by the FUSE kernel extension. This can be changed + * on a per-mount basis (there's one such virtual device for each mount). + */ +#define FUSE_DEFAULT_BLOCKSIZE             4096 + +#define FUSE_MIN_BLOCKSIZE                 512 +#define FUSE_MAX_BLOCKSIZE                 MAXPHYS + +#ifndef MAX_UPL_TRANSFER +#define MAX_UPL_TRANSFER 256 +#endif + +/* + * This is default I/O size used while accessing the virtual storage devices. + * This can be changed on a per-mount basis. + * + * Nevertheless, the I/O size must be at least as big as the block size. + */ +#define FUSE_DEFAULT_IOSIZE                (16 * PAGE_SIZE) + +#define FUSE_MIN_IOSIZE                    512 +#define FUSE_MAX_IOSIZE                    (MAX_UPL_TRANSFER * PAGE_SIZE) + +#define FUSE_DEFAULT_INIT_TIMEOUT                  10     /* s  */ +#define FUSE_MIN_INIT_TIMEOUT                      1      /* s  */ +#define FUSE_MAX_INIT_TIMEOUT                      300    /* s  */ +#define FUSE_INIT_WAIT_INTERVAL                    100000 /* us */ + +#define FUSE_INIT_TIMEOUT_DEFAULT_BUTTON_TITLE     "OK" +#define FUSE_INIT_TIMEOUT_NOTICE_MESSAGE                                  \ +  "Timed out waiting for the file system to initialize. The volume has "  \ +  "been ejected. You can use the init_timeout mount option to wait longer." + +#define FUSE_DEFAULT_DAEMON_TIMEOUT                60     /* s */ +#define FUSE_MIN_DAEMON_TIMEOUT                    0      /* s */ +#define FUSE_MAX_DAEMON_TIMEOUT                    600    /* s */ + +#define FUSE_DAEMON_TIMEOUT_DEFAULT_BUTTON_TITLE   "Keep Trying" +#define FUSE_DAEMON_TIMEOUT_OTHER_BUTTON_TITLE     "Force Eject" +#define FUSE_DAEMON_TIMEOUT_ALTERNATE_BUTTON_TITLE "Don't Warn Again" +#define FUSE_DAEMON_TIMEOUT_ALERT_MESSAGE                                 \ +  "There was a timeout waiting for the file system to respond. You can "  \ +  "eject this volume immediately, but unsaved changes may be lost." +#define FUSE_DAEMON_TIMEOUT_ALERT_TIMEOUT          120    /* s */ + +#ifdef KERNEL + +/* + * This is the soft upper limit on the number of "request tickets" FUSE's + * user-kernel IPC layer can have for a given mount. This can be modified + * through the fuse.* sysctl interface. + */ +#define FUSE_DEFAULT_MAX_FREE_TICKETS      1024 +#define FUSE_DEFAULT_IOV_PERMANENT_BUFSIZE (1 << 19) +#define FUSE_DEFAULT_IOV_CREDIT            16 + +/* User-Kernel IPC Buffer */ + +#define FUSE_MIN_USERKERNEL_BUFSIZE        (128  * 1024) +#define FUSE_MAX_USERKERNEL_BUFSIZE        (4096 * 1024) + +#define FUSE_REASONABLE_XATTRSIZE          FUSE_MIN_USERKERNEL_BUFSIZE + +#endif /* KERNEL */ + +#define FUSE_DEFAULT_USERKERNEL_BUFSIZE    (4096 * 1024) + +#define FUSE_LINK_MAX                      LINK_MAX +#define FUSE_UIO_BACKUP_MAX                8 + +#define FUSE_MAXNAMLEN                     255 + +#endif /* _FUSE_PARAM_H_ */ diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c new file mode 100644 index 000000000..f7fcc2a70 --- /dev/null +++ b/contrib/macfuse/mount_darwin.c @@ -0,0 +1,355 @@ +/* + * Derived from mount_bsd.c from the fuse distribution. + * + *  FUSE: Filesystem in Userspace + *  Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu> + *  Copyright (C) 2007-2009 Amit Singh <asingh@gmail.com> + *  Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> + * + *  This program can be distributed under the terms of the GNU LGPLv2. + *  See the file COPYING.LIB. + */ + +#undef _POSIX_C_SOURCE +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/sysctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stddef.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <paths.h> + +#include <libproc.h> +#include <sys/utsname.h> + +#include <sys/param.h> +#include <sys/mount.h> +#include <AssertMacros.h> + +#include "fuse_param.h" +#include "fuse_ioctl.h" + +#include "glusterfs.h" +#include "logging.h" +#include "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) +{ +    int fd, pid; +    int result; +    char *fdnam, *dev; +    const char *mountprog = MACFUSE_MOUNT_PROG; + +    /* 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); + +    if (!mountpoint) { +        fprintf(stderr, "missing or invalid mount point\n"); +        return -1; +    } + +    if (fuse_running_under_rosetta()) { +        fprintf(stderr, "MacFUSE does not work under Rosetta\n"); +        return -1; +    } + +    signal(SIGCHLD, SIG_DFL); /* So that we can wait4() below. */ + +    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. */ + +        char   version[MAXHOSTNAMELEN + 1] = { 0 }; +        size_t version_len = MAXHOSTNAMELEN; +        size_t version_len_desired = 0; + +        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++) +                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; +        } + +        goto mount; +    } + +    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; +        } +    } 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; +            } +        } +        if (devidx == -1) { +            GFFUSE_LOGERR("failed to open device (%s)", strerror(errno)); +            return -1; +        } +    } + +mount: +    if (getenv("FUSE_NO_MOUNT") || ! mountpoint) +        goto out; + +    signal(SIGCHLD, SIG_IGN); + +    pid = fork(); + +    if (pid == -1) { +        GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); +        close(fd); +        return -1; +    } + +    if (pid == 0) { + +        pid = fork(); +        if (pid == -1) { +            GFFUSE_LOGERR("fork() failed (%s)", strerror(errno)); +            close(fd); +            exit(1); +        } + +        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); +                } +            } +            execvp(mountprog, (char **) argv); +            GFFUSE_LOGERR("MacFUSE: failed to exec mount program (%s)", strerror(errno)); +            exit(1); +        } + +        _exit(0); +    } + +out: +    return fd; +} + +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; + +    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; +    } + +    if (fstat(fd, &sbuf) == -1) { +        return; +    } + +    devname_r(sbuf.st_rdev, S_IFCHR, dev, 128); + +    if (strncmp(dev, MACFUSE_DEVICE_BASENAME, +                sizeof(MACFUSE_DEVICE_BASENAME) - 1)) { +        return; +    } + +    strtol(dev + 4, &ep, 10); +    if (*ep != '\0') { +        return; +    } + +    rp = realpath(mountpoint, resolved_path); +    if (rp) { +        ret = unmount(resolved_path, 0); +    } + +    close(fd); + +    return; +} diff --git a/doc/translator-options.txt b/doc/translator-options.txt index b43ad6ef9..278ef5b00 100644 --- a/doc/translator-options.txt +++ b/doc/translator-options.txt @@ -1,6 +1,5 @@  mount/fuse:  	* direct-io-mode            GF_OPTION_TYPE_BOOL   on|off|yes|no -	* macfuse-local             GF_OPTION_TYPE_BOOL   on|off|yes|no  	* mount-point (mountpoint)  GF_OPTION_TYPE_PATH   <any-posix-valid-path>  	* attribute-timeout         GF_OPTION_TYPE_DOUBLE   0.0   	* entry-timeout             GF_OPTION_TYPE_DOUBLE   0.0 diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index b01285a08..afd9cafa6 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -158,10 +158,6 @@ static struct argp_option gf_options[] = {           "[default: 1]"},          {"volfile-check", ARGP_VOLFILE_CHECK_KEY, 0, 0,           "Enable strict volume file checking"}, -#ifdef GF_DARWIN_HOST_OS -        {"non-local", ARGP_NON_LOCAL_KEY, 0, 0, -         "Mount the macfuse volume without '-o local' option"}, -#endif          {0, 0, 0, 0, "Miscellaneous Options:"},          {0, }  }; @@ -345,11 +341,6 @@ _add_fuse_mount (xlator_t *graph)                          "if O_APPEND is used. disabling 'direct-io-mode'");          }          ret = dict_set_static_ptr (top->options, ZR_DIRECT_IO_OPT, "disable"); - -        if (cmd_args->non_local) -                ret = dict_set_uint32 (top->options, "macfuse-local", -                                       cmd_args->non_local); -  #else /* ! DARWIN HOST OS */          switch (cmd_args->fuse_direct_io_mode_flag) {          case 0: /* disable */ @@ -994,13 +985,6 @@ parse_opts (int key, char *arg, struct argp_state *state)                  gf_remember_xlator_option (&cmd_args->xlator_options, arg);                  break; -#ifdef GF_DARWIN_HOST_OS -        case ARGP_NON_LOCAL_KEY: -                cmd_args->non_local = _gf_true; -                break; - -#endif /* DARWIN */ -          case ARGP_KEY_NO_ARGS:                  break; diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h index d69d504cb..2d9130aac 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -164,6 +164,10 @@ enum {  #define F_SETLK64       F_SETLK  #define F_SETLKW64      F_SETLKW +#ifndef FTW_CONTINUE +  #define FTW_CONTINUE 0 +#endif +  int32_t gf_darwin_compat_listxattr (int len, dict_t *dict, int size);  int32_t gf_darwin_compat_getxattr (const char *key, dict_t *dict);  int32_t gf_darwin_compat_setxattr (dict_t *dict); @@ -298,7 +302,7 @@ size_t strnlen(const char *string, size_t maxlen);           }))  #endif  -#define ALIGN(x) (((x) + sizeof (uint64_t) - 1) & ~(sizeof (uint64_t) - 1)) +#define GF_DIR_ALIGN(x) (((x) + sizeof (uint64_t) - 1) & ~(sizeof (uint64_t) - 1))  #include <sys/types.h>  #include <dirent.h> @@ -307,16 +311,16 @@ static inline int32_t  dirent_size (struct dirent *entry)  {  #ifdef GF_BSD_HOST_OS -        return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen); +        return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);  #endif  #ifdef GF_DARWIN_HOST_OS -        return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen); +        return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);  #endif  #ifdef GF_LINUX_HOST_OS -        return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen); +        return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);  #endif  #ifdef GF_SOLARIS_HOST_OS -        return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen); +        return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);  #endif  } diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index f6ba4e2ef..181f7f943 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -219,11 +219,6 @@ struct _cmd_args {  	double           fuse_entry_timeout;  	double           fuse_attribute_timeout;  	char            *volume_name; -	int              non_local;       /* Used only by darwin os,  -					     used for '-o local' option */ -	char            *icon_name;       /* This string will appear as  -					     Desktop icon name when mounted -					     on darwin */  	int              fuse_nodev;  	int              fuse_nosuid; diff --git a/xlators/mount/fuse/src/Makefile.am b/xlators/mount/fuse/src/Makefile.am index e85d63887..4374c96b5 100644 --- a/xlators/mount/fuse/src/Makefile.am +++ b/xlators/mount/fuse/src/Makefile.am @@ -4,13 +4,20 @@ noinst_HEADERS = $(CONTRIBDIR)/fuse-include/fuse_kernel.h\  xlator_LTLIBRARIES = fuse.la  xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount + +if GF_DARWIN_HOST_OS +    mount_source=$(CONTRIBDIR)/macfuse/mount_darwin.c +else +    mount_source=$(CONTRIBDIR)/fuse-lib/mount.c +endif +  fuse_la_SOURCES = fuse-bridge.c $(CONTRIBDIR)/fuse-lib/misc.c \ -	$(CONTRIBDIR)/fuse-lib/mount.c +	$(mount_source)  fuse_la_LDFLAGS = -module -avoidversion -shared -nostartfiles  AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) -Wall \  	-I$(top_srcdir)/libglusterfs/src -I$(CONTRIBDIR)/fuse-include \ -	$(GF_CFLAGS) -DFUSERMOUNT_DIR=\"$(bindir)\" +	$(GF_CFLAGS) $(GF_FUSE_CFLAGS)  CLEANFILES =  diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 22973ac5d..984479b32 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -25,6 +25,7 @@   * fuse_loc_fill() and inode_path() return success/failure.   */ +  #include <stdint.h>  #include <signal.h>  #include <pthread.h> @@ -45,7 +46,13 @@  #include "common-utils.h"  #include "statedump.h" +#ifdef GF_DARWIN_HOST_OS +/* This is MacFUSE's marker for MacFUSE-specific code */ +#define __FreeBSD__ 10 +#include "fuse_kernel_macfuse.h" +#else  #include "fuse_kernel.h" +#endif  #include "fuse-misc.h"  #include "fuse-mount.h"  #include "fuse-mem-types.h" @@ -60,7 +67,12 @@  #define ZR_DIRECT_IO_OPT        "direct-io-mode"  #define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check" -#define FUSE_713_OP_HIGH (FUSE_POLL + 1) +#ifdef GF_LINUX_HOST_OS +#define FUSE_OP_HIGH (FUSE_POLL + 1) +#endif +#ifdef GF_DARWIN_HOST_OS +#define FUSE_OP_HIGH (FUSE_DESTROY + 1) +#endif  #define GLUSTERFS_XATTR_LEN_MAX  65536  #define MAX_FUSE_PROC_DELAY 1 @@ -442,7 +454,14 @@ stat2attr (struct iatt *st, struct fuse_attr *fa)          fa->uid        = st->ia_uid;          fa->gid        = st->ia_gid;          fa->rdev       = st->ia_rdev; +#if FUSE_KERNEL_MINOR_VERSION >= 9          fa->blksize    = st->ia_blksize; +#endif +#ifdef GF_DARWIN_HOST_OS +        fa->crtime     = (uint64_t)-1; +        fa->crtimensec = (uint32_t)-1; +        fa->flags      = 0; +#endif  } @@ -513,10 +532,14 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  feo.attr_valid_nsec =                          calc_timeout_nsec (priv->attribute_timeout); +#if FUSE_KERNEL_MINOR_VERSION >= 9                  priv->proto_minor >= 9 ? -                        send_fuse_obj (this, finh, &feo) : -                        send_fuse_data (this, finh, &feo, -                                        FUSE_COMPAT_ENTRY_OUT_SIZE); +                send_fuse_obj (this, finh, &feo) : +                send_fuse_data (this, finh, &feo, +                                FUSE_COMPAT_ENTRY_OUT_SIZE); +#else +                send_fuse_obj (this, finh, &feo); +#endif          } else {                  gf_log ("glusterfs-fuse",                          (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING), @@ -664,10 +687,14 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  fao.attr_valid_nsec =                    calc_timeout_nsec (priv->attribute_timeout); +#if FUSE_KERNEL_MINOR_VERSION >= 9                  priv->proto_minor >= 9 ?                  send_fuse_obj (this, finh, &fao) :                  send_fuse_data (this, finh, &fao,                                  FUSE_COMPAT_ATTR_OUT_SIZE); +#else +                send_fuse_obj (this, finh, &fao); +#endif          } else {                  gf_log ("glusterfs-fuse", GF_LOG_WARNING,                          "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique, @@ -714,10 +741,14 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  fao.attr_valid_nsec =                    calc_timeout_nsec (priv->attribute_timeout); +#if FUSE_KERNEL_MINOR_VERSION >= 9                  priv->proto_minor >= 9 ?                  send_fuse_obj (this, finh, &fao) :                  send_fuse_data (this, finh, &fao,                                  FUSE_COMPAT_ATTR_OUT_SIZE); +#else +                send_fuse_obj (this, finh, &fao); +#endif          } else {                  GF_LOG_OCCASIONALLY ( gf_fuse_conn_err_log, "glusterfs-fuse",                                         GF_LOG_WARNING,  @@ -841,6 +872,19 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  if (!IA_ISDIR (fd->inode->ia_type)) {                          if (priv->direct_io_mode)                                  foo.open_flags |= FOPEN_DIRECT_IO; +#ifdef GF_DARWIN_HOST_OS +                                /* In Linux: by default, buffer cache +                                 * is purged upon open, setting +                                 * FOPEN_KEEP_CACHE implies no-purge +                                 * +                                 * In MacFUSE: by default, buffer cache +                                 * is left intact upon open, setting +                                 * FOPEN_PURGE_UBC implies purge +                                 * +                                 * [[Innnnteresting...]] +                                 */ +                                foo.open_flags |= FOPEN_PURGE_UBC; +#endif                  }                  gf_log ("glusterfs-fuse", GF_LOG_TRACE, @@ -923,10 +967,14 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  if (state->truncate_needed) {                          fuse_do_truncate (state, state->size);                  } else { +#if FUSE_KERNEL_MINOR_VERSION >= 9                          priv->proto_minor >= 9 ? -                                send_fuse_obj (this, finh, &fao) : -                                send_fuse_data (this, finh, &fao, -                                                FUSE_COMPAT_ATTR_OUT_SIZE); +                        send_fuse_obj (this, finh, &fao) : +                        send_fuse_data (this, finh, &fao, +                                        FUSE_COMPAT_ATTR_OUT_SIZE); +#else +                        send_fuse_obj (this, finh, &fao); +#endif                          op_done = 1;                  }          } else { @@ -1020,8 +1068,10 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)           * linux-2.6.git;a=commit;h=v2.6.23-5896-gf333211           */          priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >= 9          if (priv->proto_minor >= 9 && fsi->valid & FATTR_LOCKOWNER)                  state->lk_owner = fsi->lock_owner; +#endif          if ((state->loc.inode == NULL && ret == 0) ||              (ret < 0)) { @@ -1286,8 +1336,10 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)          int32_t         ret = -1;          priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >= 12          if (priv->proto_minor < 12)                  name = (char *)msg + FUSE_COMPAT_MKNOD_IN_SIZE; +#endif          GET_STATE (this, finh, state);          ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); @@ -1653,9 +1705,13 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  fouh.error = 0;                  iov_out[0].iov_base = &fouh;                  iov_out[1].iov_base = &feo; +#if FUSE_KERNEL_MINOR_VERSION >= 9                  iov_out[1].iov_len = priv->proto_minor >= 9 ?                                       sizeof (feo) :                                       FUSE_COMPAT_ENTRY_OUT_SIZE; +#else +                iov_out[1].iov_len = sizeof (feo); +#endif                  iov_out[2].iov_base = &foo;                  iov_out[2].iov_len = sizeof (foo);                  if (send_fuse_iov (this, finh, iov_out, 3) == ENOENT) { @@ -1684,7 +1740,11 @@ out:  static void  fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)  { +#if FUSE_KERNEL_MINOR_VERSION >= 12          struct fuse_create_in *fci = msg; +#else +        struct fuse_open_in *fci = msg; +#endif          char         *name = (char *)(fci + 1);          fuse_private_t        *priv = NULL; @@ -1693,8 +1753,10 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)          int32_t       ret = -1;          priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >= 12          if (priv->proto_minor < 12)                  name = (char *)((struct fuse_open_in *)msg + 1); +#endif          GET_STATE (this, finh, state);          state->flags = fci->flags; @@ -1829,8 +1891,10 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)          /* See comment by similar code in fuse_settatr */          priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >= 9          if (priv->proto_minor >= 9 && fri->read_flags & FUSE_READ_LOCKOWNER)                  state->lk_owner = fri->lock_owner; +#endif          gf_log ("glusterfs-fuse", GF_LOG_TRACE,                  "%"PRIu64": READ (%p, size=%"PRIu32", offset=%"PRIu64")", @@ -1905,8 +1969,10 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)          /* See comment by similar code in fuse_settatr */          priv = this->private; +#if FUSE_KERNEL_MINOR_VERSION >= 9          if (priv->proto_minor >= 9 && fwi->write_flags & FUSE_WRITE_LOCKOWNER)                  state->lk_owner = fwi->lock_owner; +#endif          gf_log ("glusterfs-fuse", GF_LOG_TRACE,                  "%"PRIu64": WRITE (%p, size=%"PRIu32", offset=%"PRId64")", @@ -2352,6 +2418,18 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          char         *dict_value = NULL;          int32_t       ret = -1; +#ifdef GF_DARWIN_HOST_OS +        if (fsi->position) { +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "%"PRIu64": SETXATTR %s/%"PRIu64" (%s):" +                        "refusing positioned setxattr", +                        finh->unique, state->loc.path, finh->nodeid, name); +                send_fuse_err (this, finh, EINVAL); +                FREE (finh); +                return; +        } +#endif +  #ifdef DISABLE_POSIX_ACL          if (!strncmp (name, "system.", 7)) {                  send_fuse_err (this, finh, EOPNOTSUPP); @@ -2558,6 +2636,26 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          fuse_state_t *state = NULL;          int32_t       ret = -1; +#ifdef GF_DARWIN_HOST_OS +        if (fgxi->position) { +                /* position can be used only for +                 * resource fork queries which we +                 * don't support anyway... so handling +                 * it separately is just sort of a +                 * matter of aesthetics, not strictly +                 * necessary. +                 */ + +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "%"PRIu64": GETXATTR %s/%"PRIu64" (%s):" +                        "refusing positioned getxattr", +                        finh->unique, state->loc.path, finh->nodeid, name); +                send_fuse_err (this, finh, EINVAL); +                FREE (finh); +                return; +        } +#endif +  #ifdef DISABLE_POSIX_ACL          if (!strncmp (name, "system.", 7)) {                  send_fuse_err (this, finh, ENODATA); @@ -2843,6 +2941,7 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)          fino.max_readahead = 1 << 17;          fino.max_write = 1 << 17;          fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS; +#if FUSE_KERNEL_MINOR_VERSION >= 9          if (fini->minor >= 6 /* fuse_init_in has flags */ &&              fini->flags & FUSE_BIG_WRITES) {                  /* no need for direct I/O mode by default if big writes are supported */ @@ -2858,7 +2957,7 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)          }          if (fini->minor < 9)                  *priv->msg0_len_p = sizeof(*finh) + FUSE_COMPAT_WRITE_IN_SIZE; - +#endif          ret = send_fuse_obj (this, finh, &fino);          if (ret == 0)                  gf_log ("glusterfs-fuse", GF_LOG_INFO, @@ -2895,7 +2994,7 @@ fuse_destroy (xlator_t *this, fuse_in_header_t *finh, void *msg)          GF_FREE (finh);  } -static fuse_handler_t *fuse_ops[FUSE_713_OP_HIGH]; +static fuse_handler_t *fuse_ops[FUSE_OP_HIGH];  int  fuse_first_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -3073,7 +3172,17 @@ fuse_thread_proc (void *data)                  }                  finh = (fuse_in_header_t *)iov_in[0].iov_base; -                if (res != finh->len) { +                if (res != finh->len +#ifdef GF_DARWIN_HOST_OS +                    /* work around fuse4bsd/MacFUSE msg size miscalculation bug, +                     * that is, payload size is not taken into account for +                     * buffered writes +                     */ +                    && !(finh->opcode == FUSE_WRITE && +                         finh->len == sizeof(*finh) + sizeof(struct fuse_write_in) && +                         res == finh->len + ((struct fuse_write_in *)(finh + 1))->size) +#endif +                   ) {                          gf_log ("glusterfs-fuse", GF_LOG_WARNING, "inconsistent read on /dev/fuse");                          break;                  } @@ -3105,6 +3214,12 @@ fuse_thread_proc (void *data)                          msg = finh + 1;                  } +#ifdef GF_DARWIN_HOST_OS +                if (finh->opcode >= FUSE_OP_HIGH) +                        /* turn down MacFUSE specific messages */ +                        fuse_enosys (this, finh, msg); +                else +#endif                  fuse_ops[finh->opcode] (this, finh, msg);                  iobuf_unref (iobuf); @@ -3405,7 +3520,7 @@ init (xlator_t *this_xl)          pthread_mutex_init (&priv->child_up_mutex, NULL);          priv->child_up_value = 1; -        for (i = 0; i < FUSE_713_OP_HIGH; i++) +        for (i = 0; i < FUSE_OP_HIGH; i++)                  fuse_ops[i] = fuse_enosys;          fuse_ops[FUSE_INIT]        = fuse_init;          fuse_ops[FUSE_DESTROY]     = fuse_destroy; @@ -3496,9 +3611,6 @@ struct volume_options options[] = {          { .key  = {"direct-io-mode"},            .type = GF_OPTION_TYPE_BOOL          }, -        { .key  = {"macfuse-local"}, -          .type = GF_OPTION_TYPE_BOOL -        },          { .key  = {"mountpoint", "mount-point"},            .type = GF_OPTION_TYPE_PATH          }, diff --git a/xlators/storage/bdb/src/bdb-ll.c b/xlators/storage/bdb/src/bdb-ll.c index dcf18c0a7..7d3938daf 100644 --- a/xlators/storage/bdb/src/bdb-ll.c +++ b/xlators/storage/bdb/src/bdb-ll.c @@ -884,7 +884,7 @@ out:  int32_t  bdb_dirent_size (DBT *key)  { -        return ALIGN (24 /* FIX MEEEE!!! */ + key->size); +        return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + key->size);  }  | 
