R/W HFS support with macFUSE on macOS 12
The original fusehfs code was published under GPL v2, so this version's code is too.
See the project page
We're discussing in the Issue #2 whether we can make fusehfs work again on macOS 12 Monterey now that HFS support is removed entirely by Apple, and whether long-term functionality will require using the File Provider API now that kexts are deprecated.
See the project page
The problem is the -oallow-other option. This option can only be used by privileged users. On older systems, the program mount_fusefs did in fact run as root, but now mount_osxfusefs does not, which is for the better. It seems to me that users who are in group 80 should have been able to use this option, but evidently not. Group 80 (admin) is the default "MacFUSE admin" and "OSXFUSE admin" group, so FUSE should run as a member of this group, but it seems to prefer 20 (staff) for some reason. My understanding of the option may be wrong anyway, if wheel is actually required. For now, leaving out this option will allow FuseHFS to work for the user who mounts the volume. Considering the somewhat niche use of this filesystem these days, this is probably OK for now.
I changed fusehfs (specifically, mount_fusefs_hfs) to only attempt this option if the user is root. There might be a way to add this back in later for all users, but for now omitting this function for non-root users is better than not functioning at all.
The problem does not seem to lie within the mount program (the one that calls mount_fusefs_hfs, not the syscall). When called from the shell, which works, it receives the same arguments as when called by hdiutil, which does not work without root. Its execution appears to proceed in the same way within lldb, no matter where it is called from or if its caller hdiutil is run by root. Its real and effective user IDs are the same both ways. If it is changing something that affects the eventual mount() syscall, I can't see what it is.
The problem does not seem to be improper permissions on the mount point in /Volumes, or at least that's not the only problem. Running hdiutil as root does allow the critical mount() call (and everything else along the way) to work correctly, but simply adding read/write permissions to the mount point does not have the same effect. I used lldb to pause the various processes involved (hdiutil, mount, mount_osxfusefs) at different points and tried setting permissions and then allowing them to continue, with no apparent effect. I also found that when only mount_osxfusefs is run with an effective UID of root, the mount() call still does not work. So there is more to this failing syscall than meets the eye.
Someone on the Emaculation forum speculated the problem was due to permissions, which is on the right track.
The problem occurs within FUSE for OS X, not within any of the code of fusehfs itself. The syscall mount() on line 938 in this program fails due to EPERM, which I believe is due to the user lacking write access to the mount point in /Volumes. The FUSE for OS X documentation indicates that the user must have write access to the mount point. It looks like my working copy of fusehfs on 10.6 with MacFUSE runs the fusefs_hfs program as root, which is not good if avoidable.
What's strange is that my workaround isn't subject to this. I can see that mount_fusefs_hfs is called with the same arguments by the same real/effective user and the exact same mount() call will work when mount_fusefs_hfs is called via my workaround, but not when mount_fusefs_hfs is called by double-clicking the disk image. Something must be different in the environment from which mount_fusefs_hfs is called, but I don't yet know what. I'm going to dig in to the source to mount to see what it does before calling the filesystem-specific program (in our case, mount_fusefs_hfs).
I'll also try to figure out how other filesystems like sshfs manage to mount in /Volumes without escalating to root. Requesting privileges from the user should work if all else fails, but that's really not a great option.
As described in this thread on the Emaculation forum: http://www.emaculation.com/forum/viewtopic.php?f=7&t=8181&p=48333#p48333
I'm able to make fusehfs work with FUSE for OS X to an extent, with no modifications. My setup is as follows:
•fusefs_hfs.fs is in /System/Library/Filesystems
•/sbin/mount_fusefs_hfs is a symbolic link to /System/Library/Filesystems/fusefs_hfs.fs/Contents/Resources/fusefs_hfs
(the fusehfs installer should put both of these things where they belong)
•Mac OS X 10.9.4
•FUSE for OS X 2.7.0 with MacFUSE compatibility layer installed
I can mount and unmount functional (read/write) HFS disk images from the shell, but definitely not using the graphical DiskImageMounter/DiskImages UI Agent/Disk Utility. These commands work for me:
$: hdiutil attach /path/to/disk/image
$: mount -t fusefs_hfs -o nodev,noowners,nosuid /dev/disk# /specify/a/mount/point
# where disk# is the value that hdiutil reports
# this works fine without the -o options, but they are here for consistency with hdiutil
# And I can safely unmount the volume with just:
$: umount /mount/point/you/specified
Note that the call to hdiutil also includes a call to mount, which fails, but the subsequent call from the shell succeeds.