[Mono-dev] Announce: Mono.Fuse (+ Required Mono.Posix Changes)
Jonathan Pryor
jonpryor at vt.edu
Tue Aug 29 08:27:02 EDT 2006
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
More information about the Mono-devel-list
mailing list