Mono.Fuse is a binding for the FUSE library, permitting user-space file systems to be written in C#.
Why? === I read Robert Love's announcement of beaglefs, a FUSE program that exposes Beagle searches as a filesystem. My first thought: Why wasn't that done in C# (considering that the rest of Beagle is C#)? What about SULF? =============== Stackable User-Level Filesystem, or SULF (http://arg0.net/users/vgough/sulf/), is a pre-existing FUSE binding in C#, started by Valient Gough in 2004. Mono.Fuse has no relation to SULF, for two reasons: 1. It goes to great efforts to avoid a Mono.Posix.dll dependency, duplicating Mono.Unix.Native.Stat (Fuse.Stat), Mono.Unix.Native.Statvfs (Fuse.StatFS), and many methods from Mono.Unix.Native.Syscall (Fuse.Wrapper). 2. I don't like the SULF API. (Not that I spent a great deal of time looking at it, but what I did see I didn't like.) 3. SULF wraps the FUSE kernel-level interface, while Mono.Fuse wraps the higher level libfuse C interface I find (1) the most appalling, if only because I'm the Mono.Posix maintainer and I'd like to see my work actually used. :-) Once I started writing Mono.Fuse, I discovered a good reason to avoid Mono.Posix: it's currently impossible to use from outside of Mono. I figured this would be a good opportunity to rectify that, making it easier for additional libraries to build upon the Mono.Posix infrastructure. Implementation: ============== Mono.Fuse requires patches to the mcs & mono modules, changes which need to be proposed (hence this email) and discussed. mono: ---- The biggest problem with the mono module is that no headers are installed, making it difficult to make use of libMonoPosixHelper.so. Changes: - Modify `configure' to generate a mono-config.h file, installed as $libdir/mono/include/mono-config.h. (Basic idea "borrowed" from GLib's $libdir/glib-2.0/include/glibconfig.h). - Add a mono-posix-helper.pc file - Install the files $includedir/mono/posix/helper.h and $includedir/mono/posix/map.h. map.h is the current map.h file generated by make-map.exe, with some major additions (detailed in the mcs section). helper.h is the main include file, which includes map.h and declares all types/functions which cannot be generated by make-map.exe. mono-config.h is necessary because it needs to contain platform-specific macros. In particular, Linux needs: int Mono_Posix_ToStat (struct statvfs *to, struct Mono_Posix_Helper *to); while OS X and *BSD need: int Mono_Posix_ToStat (struct statfs *to, struct Mono_Posix_Helper *to); Note `struct statvfs' vs. `struct statfs'. The mono/posix/helper.h header needs to "paper over" the difference, and thus needs to know which type the platform prefers. helper.h thus looks like: #ifdef MONO_HAVE_STATVFS struct statvfs; int Mono_Posix_ToStatvfs (struct statvfs *from, struct Mono_Posix_Statvfs *to); #endif #ifdef MONO_HAVE_STATFS struct statfs; int Mono_Posix_ToStatvfs (struct statfs *from, struct Mono_Posix_Statvfs *to); #endif One of MONO_HAVE_STATVFS or MONO_HAVE_STATFS would be defined in mono-config.h. mcs: --- There are two major changes: * The addition of one public attributes to the API: // targets Class, Delegate, Enum, Field, Struct class Mono.Unix.Native.MapAttribute { public MapAttribute (); public MapAttribute (string nativeType); public string NativeType {get;} public string NativeSymbolPrefix {get; set;} } * A major revamp to make-map.exe The Map and MapHeader attributes are public so that make-map.exe can use a publically exposed API for code generation purposes which can be used by other libraries (Mono.Fuse makes use of these changes). Make-map.exe can also generate structure declarations and delegate declarations in addition to P/Invoke function declarations, allowing for a better, automated interface between C and C#. Previously, [Map] could only be used on enumerations. Now, [Map] can be used on classes, structures, & delegates, to create a C declaration of the C# type, suitable for P/Invoke purposes, e.g. [Map] struct Stat {public FilePermissions mode;} would generate the C declaration struct Namespace_Stat {unsigned int mode;}; The MapAttribute.NativeType property is used to specify that type conversion functions should be generated, thus: [Map ("struct stat")] struct Stat {public FilePermissions mode;} would generate struct Namespace_Stat {unsigned int mode;}; int Namespace_ToStat (struct stat *from, struct Namespace_Stat *to); int Namespace_FromStat (struct Namespace_Stat *from, struct stat *to); along with the actual implementations of Namespace_ToStat() and Namespace_FromStat(). The MapAttribute.NativeSymbolPrefix is used to specify the C "namespace" to use: [Map (NativeSymbolPrefix="Foo")] struct Stat {FilePermissiond mode;} generates struct Foo_Stat {unsigned int mode;}; This prefix is also used for the conversion functions. (You may be wondering why NativeSymbolPrefix exists at all. This is for reasonable symbol versioning -- make-map.exe currently has a "hack" in place to rename Mono.Unix(.Native) to Mono_Posix, a hack I'd like to remove, and NativeSymbolPrefix allows the Mono.Unix.Native types to have a "Mono_Posix" C namespace in a reasonably general manner.) The previously internal Mono.Unix.HeaderAttribute has been removed. The HeaderAttribute.Includes and HeaderAttribute.Defines properties have been replaced with make-map.exe command-line arguments. In particular, HeaderAttribute.Includes has been replaced with --autoconf-header, --impl-header, --impl-macro, --public-header, and --public-macro (the first three modify the generated .c file, while the latter two modify the generated .h file). Finally, make-map.exe has been renamed and moved from mcs/class/Mono.Posix/Mono.Unix.Native/make-map.exe to mcs/tools/create-native-map/create-native-map.exe. HOWTO: ===== Go to http://www.jprl.com/mono-fuse for the patches and source download. Apply ``mcs.patch'' to a ``mcs'' checkout, rebuild, and install. Apply ``mono.patch'' to a ``mono'' checkout, rebuild, and install. Build ``mono-fuse-0.1.0.tar.gz'' in "the standard manner" (ye olde "./configure; make; make install" business). Questions: ========= - Is it OK for create-native-map.exe to be a .NET 2.0 app? - How should we cope with unstable APIs which make use of native code? The Application Deployment Guidelines [1] don't address this issue, nor the related issue of what should be done with 64-bit binaries. In particular, for an AMD64 machine, which directory layout should be used for an assembly + native lib combo? 1. What Mono seems to do, with the GAC in $prefix/lib no matter what the architecture: /usr/lib/mono-fuse/Mono.Fuse.dll /usr/lib64/libMonoFuseHelper.so 2. Be consistent, and toss everything in @libdir@: /usr/lib64/mono-fuse/Mono.Fuse.dll /usr/lib64/libMonoFuseHelper.so [1] http://www.mono-project.com/Guidelines:Application_Deployment#Libraries_with_Unstable_APIs Thanks, - Jon _______________________________________________ Mono-list maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-list
