clintonjade / macfuse

Automatically exported from code.google.com/p/macfuse
Other
0 stars 0 forks source link

ENHANCEMENT: Add `fstype=` option to allow per-mount `f_fstypename` customization #243

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

  1. Mount volume through custom FS bundle and DiskArbitration
  2. Check localized names of filesystem mount points
  3. Names use those provided in fusefs.fs, not your bundle

What is the expected output? What do you see instead?

  I expect my filesystem's information to be obtained through my bundle.  This is currently not 
the case, and I believe I understand why.

What version of the product are you using? On what operating system?

  I've used MacFUSE 0.3.0 and 0.4.0 under Mac OS X 10.4.

Please provide any additional information below.

---

I believe that the private DiskManagement framework (which I think is 
responsible for the 
behavior of apps like Finder, Disk Utility, and diskutil) uses the 
`f_fstypename` of a mount point 
to determine which filesystem bundle contains its information (personalities).  
Since all MacFUSE 
volumes are mounted through `mount_fusefs` and use the "fusefs" VFS plugin, 
they are all set to 
the string "fusefs," so all lookups are done in the `fusefs.fs` bundle.

A solution would be the addition of an `fstype=` option to `mount_fusefs`, 
which the kernel 
module would use to overwrite the `mount.mnt_vfsstat.f_fstypename` field inside 
its 
`vfs_mount()` routine.  At this point, the kernel has copied in the zeroed-out 
buffer into 
`f_fstypename` and the "fusefs" string is placed at the beginning.  Since the 
kernel has already 
looked up the VFS module by name, it will not be using this string again.  I 
*beleive* that string 
is only useful to user-space programs, which we aim to intentionally deceive.

Note that the `f_fstypename` buffer is guaranteed to be zero-filled by the 
kernel's routines 
(right now).  Thus, we can place a non-zero 32-bit token at the *end* of 
`f_fstypename` to 
accurately identify MacFUSE volumes, while allowing volumes to specify a custom 
`f_fstypename` 
that the rest of the system will see.  Obviously, all custom `f_fstypename` 
fields must be 11 
characters or fewer, NOT counting a zero-terminator.

If the `fstype=` option is not specified, `mount_fusefs` would fall back to 
using the "fusefs" 
string, but STILL place the 32-bit token at the end, so it's still a reliable 
method.  This has the 
advantage of allowing third-party filesystems based on MacFUSE to ship their 
own filesystem 
bundles, and have all OS X apps read localized strings from their bundles, 
instead of having to 
include a rudimentary set in the fusefs.fs bundle.

Since the kernel zeros this buffer, having four non-zero bytes at the buffer's 
end is a fail-proof 
way to identify MacFUSE volumes, even if they have custom `f_fstypename` 
fields.  fsid 
generation would not be altered.

A likely candidate for a 32-bit identifier would be the 'UFES' constant used 
for fsid construction.  
This would be stored as a byte sequence "UFES" so that even Rosetta-based apps 
would see the 
correct value.  If it were stored using the host's endianness, Rosetta-based 
apps would break, 
since the bytes would not be properly swapped.  Basically, we would settle on 
the big-endian 
representation of the 32-bit constant 'UFES', and user-space code would have to 
account for 
that.

Also, this would allow each third-party filesystem to maintain its own set of 
`FSSubType` values 
without worry of conflicting with other MacFUSE volumes, as long as they all 
specify custom 
`fstype=` values.

Feel free to close this enhancement request if it seems unreasonable or 
dangerous.  I've glanced 
at most of the VFS code, so I believe this is safe, but I could easily be wrong.

Original issue reported on code.google.com by shadowof...@gmail.com on 19 Jul 2007 at 5:17

GoogleCodeExporter commented 8 years ago
Sorry about not responding earlier, but I've only recently managed to look at 
this as a priority issue.

Also see: 
http://groups.google.com/group/macfuse-devel/browse_thread/thread/b62bd1b823b94c
82/749bd5e87c43430b

I considered John Brisbin's solution. Although his implementation is nice, I 
find the solution much too complex for the task at hand. It rewrites files on 
the fly and also 
requires the mount utility to be setuid root.

shadowofged: Your suggestion is simpler, but what it does is ugly and 
potentially dangerous. There are parts of the kernel that do look at 
f_fstypename of mount points, 
although mostly they are checking to see if something is "hfs", "ufs", etc. So, 
at the very least, one would have to police incoming file systems so that they 
don't take over 
"important" fstypenames. The implications might change in the future 
too--there's no implicit or explicit understanding that one can overwrite this 
field and nothing bad 
will ever happen. Observing the current behavior is no guarantee. It's also 
semantically incorrect: the vfs type *is* fusefs--just because a portion of the 
file system stays in 
user space doesn't mean it's not fusefs from the kernel's standpoint. If a 
kernel-space or user-space program wants to do things to, say, all file systems 
of type "xyz", that 
program will use f_fstypename to figure things out. Since I don't control all 
such programs (some of them come from Apple), I can't predict what might break, 
if anything.

I thought of another approach--that of "simulating" the personality plist. The 
per-file-system content within fusefs.fs's Info.plist will be dynamically 
adjustable because 
the file itself would be served by macfuse. At kext load time, macfuse will 
"mount" an in-kernel auxiliary file system (nice to be in kernel so we don't 
have to worry about 
daemons dying) that would serve the Info.plist, and could possibly serve other 
things such as mount status info, etc. ... somewhat akin to a proc file system. 
The content of 
this file could/would change dynamically as mounts/unmounts happen. So, for 
example, a new FSName/FSSubType combination would just automagically appear in 
this file 
when a new user-space file system is mounted. I did implement this and it works 
nicely, but the implementation is even more complex than John Brisbin's 
solution above, 
which I just said was "too complex". Therefore, I can't justify incorporating 
this into macfuse.

As a compromise, I'll go with a slight variation of f_fstypename overwriting.

MacFUSE will have a '-o fstypename=<name>" argument. <name> can be at most 7 
characters and at least 1 character. (I'm talking about the *type* name 
here--not the 
description string, which can be longer, like "PassThrough File System 
(MacFUSE)".) This would cause the in-kernel f_fstypename to be "fusefs_<name>". 
That is, the 
"fusefs_" prefix will be implied and automatically added by the kernel. This 
means a user-space file system that uses this option, say, to set its typename 
to "foo", must 
name its bundle "fusefs_foo.fs". The "-o fssubtype=<number>" option will 
continue to exist and work--as expected, the system would look in fusefs_foo.fs 
for subtypes. 
The limit is 7 characters (and not 8) because the Finder is unhappy otherwise. 
File systems that use this option will be subject to a general "this might 
break things you 
don't know about" warning.

A user-space file system that does not use this option will continue to see 
"fusefs" as its f_fstypename. The current set of subtypes in the "main" 
Info.plist will likely 
continue to be there.

Original comment by si...@gmail.com on 27 Sep 2007 at 7:48

GoogleCodeExporter commented 8 years ago
I actually did read that thread before filing this bug.  After grepping through 
the publicly-available 10.4.9 xnu 
sources, I see that my original proposal wouldn't work as expected.  They use 
strncpy() for syscalls, which 
would (of course) fail to copy the hidden constant at the end of the 
`f_fstypename` buffer.  Given it's a small 
buffer, I'm surprised the kernel didn't just do memcpy() on the whole buffer, 
but that's immaterial now.

The only in-kernel uses of `f_fstypename` that I can find are checks for HFS 
and UFS volumes, like you 
mentioned.  I understand the general "might break things warning," but it looks 
pretty safe for now, yes?  I 
assume, from your comments, that changing this field had the desired effect 
upon properly locating 
filesystem bundles?

If so, that's good to know; thanks for the update and for considering/making 
the changes.

Original comment by shadowof...@gmail.com on 28 Sep 2007 at 5:27

GoogleCodeExporter commented 8 years ago
Will be in the next release.

Original comment by si...@gmail.com on 28 Sep 2007 at 6:20